Merge "ResourceLoader::makeLoaderImplementScript: Bind args as '$' and 'jQuery'"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 14 Apr 2014 20:53:47 +0000 (20:53 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 14 Apr 2014 20:53:47 +0000 (20:53 +0000)
175 files changed:
.gitignore
CREDITS
HISTORY
RELEASE-NOTES-1.23
RELEASE-NOTES-1.24 [new file with mode: 0644]
docs/hooks.txt
docs/kss/Makefile
docs/kss/package.json
includes/AutoLoader.php
includes/CategoryPage.php
includes/Collation.php
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/OutputPage.php
includes/PHPVersionError.php
includes/Preferences.php
includes/PrefixSearch.php
includes/Setup.php
includes/Skin.php
includes/TitleArray.php
includes/TitleArrayFromResult.php
includes/UserArray.php
includes/UserArrayFromResult.php
includes/WebResponse.php
includes/Wiki.php
includes/WikiFilePage.php
includes/actions/Action.php
includes/actions/CachedAction.php
includes/actions/CreditsAction.php
includes/actions/FormAction.php
includes/actions/FormlessAction.php
includes/actions/HistoryAction.php
includes/actions/InfoAction.php
includes/actions/RawAction.php
includes/api/ApiFeedRecentChanges.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryBlocks.php
includes/api/ApiQueryCategoryMembers.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryProtectedTitles.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiQueryWatchlist.php
includes/clientpool/RedisConnectionPool.php
includes/content/Content.php
includes/dao/DBAccessBase.php
includes/db/Database.php
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendMultiWrite.php
includes/filerepo/file/File.php
includes/logging/DeleteLogFormatter.php
includes/media/DjVu.php
includes/profiler/Profiler.php
includes/profiler/ProfilerMwprof.php
includes/profiler/ProfilerSimple.php [deleted file]
includes/profiler/ProfilerSimpleDB.php [new file with mode: 0644]
includes/profiler/ProfilerSimpleText.php
includes/profiler/ProfilerSimpleTrace.php
includes/profiler/ProfilerSimpleUDP.php
includes/specialpage/ChangesListSpecialPage.php
includes/specials/SpecialContributions.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRecentchangeslinked.php
includes/specials/SpecialWatchlist.php
includes/title/TitleValue.php
languages/i18n/ace.json
languages/i18n/ar.json
languages/i18n/arc.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/crh-latn.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frr.json
languages/i18n/fy.json
languages/i18n/gl.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/haw.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/id.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ka.json
languages/i18n/kiu.json
languages/i18n/kk-cyrl.json
languages/i18n/ko.json
languages/i18n/krc.json
languages/i18n/lb.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mn.json
languages/i18n/nan.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/rm.json
languages/i18n/ro.json
languages/i18n/ru.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/sco.json
languages/i18n/sdc.json
languages/i18n/sh.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/ta.json
languages/i18n/te.json
languages/i18n/th.json
languages/i18n/uk.json
languages/i18n/uz.json
languages/i18n/vi.json
languages/i18n/yi.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/jsduck/CustomTags.rb [new file with mode: 0644]
maintenance/jsduck/config.json
maintenance/mwjsduck-gen
resources/Resources.php
resources/lib/jquery/jquery.qunit.css
resources/lib/jquery/jquery.qunit.js
resources/lib/oojs-ui/oojs-ui-apex.css
resources/lib/oojs-ui/oojs-ui.js
resources/lib/oojs-ui/oojs-ui.svg.css
resources/src/jquery/jquery.delayedBind.js [deleted file]
resources/src/mediawiki.action/mediawiki.action.edit.js
resources/src/mediawiki.ui/components/default/buttons.less
resources/src/mediawiki.ui/mixins/effects.less
resources/src/mediawiki/mediawiki.debug.profile.js
resources/src/mediawiki/mediawiki.js
skins/common/IEFixes.js
skins/vector/variables.less
tests/parser/parserTests.txt
tests/qunit/QUnitTestResources.php
tests/qunit/data/testrunner.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js

index c7d6f66..0351cf5 100644 (file)
@@ -48,7 +48,7 @@ node_modules/
 /composer.json
 
 # MediaWiki UI documentation
-resources/mediawiki.ui/docs
+/docs/kss/static
 
 # Operating systems
 ## Mac OS X
diff --git a/CREDITS b/CREDITS
index 6e28d6d..cf222a0 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1,6 +1,6 @@
 {{int:version-credits-summary}}
 <!--
-MediaWiki 1.23 is a collaborative project released under the
+MediaWiki 1.24 is a collaborative project released under the
 GNU General Public License v2. We would like to recognize the
 following names for their contribution to the product.
 -->
diff --git a/HISTORY b/HISTORY
index b2705f1..12532db 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1,4 +1,4 @@
-Change notes from older releases. For current info see RELEASE-NOTES-1.23.
+Change notes from older releases. For current info see RELEASE-NOTES-1.24.
 
 == MediaWiki 1.22 ==
 
index 79c692a..d0a8ec7 100644 (file)
@@ -148,6 +148,8 @@ production.
   process the result set prior to rendering.
 * A PoolCounterRedis class was added which can be make use of in $wgPoolCounterConf.
   This requires at least one Redis 2.6+ server.
+* $wgProfileToDatabase was removed. Set $wgProfiler to ProfilerSimpleDB
+  in StartProfiler.php instead of using this.
 
 === Bug fixes in 1.23 ===
 * (bug 41759) The "updated since last visit" markers (on history pages, recent
@@ -248,6 +250,8 @@ production.
   included in all searches.
 * Added list=prefixsearch that works like action=opensearch but can be used as
   a generator.
+* (bug 24782) Various modules will now use unique continuation parameters.
+* (bug 63249) Cache RecentChanges Atom feed in varnish for 15 seconds.
 
 === Languages updated in 1.23 ===
 
diff --git a/RELEASE-NOTES-1.24 b/RELEASE-NOTES-1.24
new file mode 100644 (file)
index 0000000..3d9efc3
--- /dev/null
@@ -0,0 +1,91 @@
+Security reminder: MediaWiki does not require PHP's register_globals. If you
+have it on, turn it '''off''' if you can.
+
+== MediaWiki 1.24 ==
+
+THIS IS NOT A RELEASE YET
+
+MediaWiki 1.24 is an alpha-quality branch and is not recommended for use in
+production.
+
+=== Configuration changes in 1.24 ===
+
+=== New features in 1.24 ===
+
+=== Bug fixes in 1.24 ===
+
+=== Web API changes in 1.24 ===
+
+=== Languages updated in 1.24 ===
+
+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 Bugzilla reports.
+
+=== Other changes in 1.24 ===
+* The deprecated jquery.delayedBind ResourceLoader module was removed.
+
+== Compatibility ==
+
+MediaWiki 1.24 requires PHP 5.3.2 or later.
+
+MySQL 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.0.2 or later
+* PostgreSQL 8.3 or later
+* SQLite 3.3.7 or later
+* Oracle 9.0.1 or later
+* Microsoft SQL Server 2005 (9.00.1399)
+
+== Upgrading ==
+
+1.24 has several database changes since 1.22, 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).
+
+If upgrading from before 1.11, and you are using a wiki as a commons
+repository, make sure that it is updated as well. Otherwise, errors may arise
+due to database schema changes.
+
+If upgrading from before 1.7, you may want to run refreshLinks.php to ensure
+new database fields are filled with data.
+
+If you are upgrading from MediaWiki 1.4.x or earlier, you should upgrade to
+1.5 first. The upgrade script maintenance/upgrade1_5.php has been removed
+with MediaWiki 1.21.
+
+Don't forget to always back up your database before upgrading!
+
+See the file UPGRADE for more detailed upgrade instructions.
+
+For notes on 1.21.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/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 ff1d6a1..a9bc736 100644 (file)
@@ -844,6 +844,21 @@ $changesList: ChangesList instance
 $rows: The data that will be rendered. May be a ResultWrapper instance or
   an array.
 
+'ChangesListSpecialPageFilters': Called after building form options on pages inheriting from ChangesListSpecialPage (in core: RecentChanges, RecentChangesLinked and Watchlist).
+$special: ChangesListSpecialPage instance
+&$filters: associative array of filter definitions. The keys are the HTML
+  name/URL parameters. Each key maps to an associative array with a 'msg'
+  (message key) and a 'default' value.
+
+'ChangesListSpecialPageQuery': Called when building SQL query on pages inheriting from ChangesListSpecialPage (in core: RecentChanges, RecentChangesLinked and Watchlist).
+$name: name of the special page, e.g. 'Watchlist'
+&$tables: array of tables to be queried
+&$fields: array of columns to select
+&$conds: array of WHERE conditionals for query
+&$query_options: array of options for the database request
+&$join_conds: join conditions for the tables
+$opts: FormOptions for this request
+
 'Collation::factory': Called if $wgCategoryCollation is an unknown collation.
 $collationName: Name of the collation in question
 &$collationObject: Null. Replace with a subclass of the Collation class that
@@ -2369,7 +2384,7 @@ use this to change some selection criteria or substitute a different title.
   result from the normal query
 
 'SpecialRecentChangesFilters': Called after building form options at
-RecentChanges.
+RecentChanges. Deprecated, use ChangesListSpecialPageFilters instead.
 $special: the special page object
 &$filters: associative array of filter definitions. The keys are the HTML
   name/URL parameters. Each key maps to an associative array with a 'msg'
@@ -2381,7 +2396,8 @@ SpecialRecentChanges.
 $opts: FormOptions for this request
 
 'SpecialRecentChangesQuery': Called when building SQL query for
-SpecialRecentChanges and SpecialRecentChangesLinked.
+SpecialRecentChanges and SpecialRecentChangesLinked. Deprecated, use
+ChangesListSpecialPageQuery instead.
 &$conds: array of WHERE conditionals for query
 &$tables: array of tables to be queried
 &$join_conds: join conditions for the tables
@@ -2471,12 +2487,14 @@ $wgVersion: Current $wgVersion for you to use
 &$versionUrl: Raw url to link to (eg: release notes)
 
 'SpecialWatchlistFilters': Called after building form options at Watchlist.
+Deprecated, use ChangesListSpecialPageFilters instead.
 $special: the special page object
 &$filters: associative array of filter definitions. The keys are the HTML
   name/URL parameters. Each key maps to an associative array with a 'msg'
   (message key) and a 'default' value.
 
 'SpecialWatchlistQuery': Called when building sql query for SpecialWatchlist.
+Deprecated, use ChangesListSpecialPageQuery instead.
 &$conds: array of WHERE conditionals for query
 &$tables: array of tables to be queried
 &$join_conds: join conditions for the tables
index 1b7aeb1..fee82cb 100644 (file)
@@ -7,13 +7,13 @@ kss: nodecheck
 # KSS style guide
        $(eval KSS_RL_TMP := $(shell mktemp /tmp/tmp.XXXXXXXXXX))
        @curl -sG "${MEDIAWIKI_LOAD_URL}?modules=mediawiki.ui|mediawiki.ui.button&only=styles" > $(KSS_RL_TMP)
-       @node_modules/.bin/kss-node mediawiki.ui mediawiki.ui/docs --css $(KSS_RL_TMP) -t styleguide-template
+       @node_modules/.bin/kss-node ../../resources/src/mediawiki.ui static/ --css $(KSS_RL_TMP) -t styleguide-template
        @rm $(KSS_RL_TMP)
 
 kssopen: kss
        @echo Opening the generated style guide...
-       @command -v xdg-open >/dev/null 2>&1 || { open ${PWD}/mediawiki.ui/docs/index.html; exit 0; }
-       @xdg-open ${PWD}/mediawiki.ui/docs/index.html
+       @command -v xdg-open >/dev/null 2>&1 || { open ${PWD}/static/index.html; exit 0; }
+       @xdg-open ${PWD}/static/index.html
 
 nodecheck:
        @scripts/nodecheck.sh
index a1722b5..70cebd2 100644 (file)
@@ -3,7 +3,7 @@
        "description": "Node.js dependencies used for KSS generation",
        "version": "0.0.1",
        "dependencies": {
-               "kss": ">=0.3.6"
+               "kss": ">=0.3.7"
        },
        "repository" : {
                "type" : "git",
index 6675860..923c8d1 100644 (file)
@@ -831,7 +831,7 @@ $wgAutoloadLocalClasses = array(
        # includes/profiler
        'Profiler' => 'includes/profiler/Profiler.php',
        'ProfilerMwprof' => 'includes/profiler/ProfilerMwprof.php',
-       'ProfilerSimple' => 'includes/profiler/ProfilerSimple.php',
+       'ProfilerSimpleDB' => 'includes/profiler/ProfilerSimpleDB.php',
        'ProfilerSimpleText' => 'includes/profiler/ProfilerSimpleText.php',
        'ProfilerSimpleTrace' => 'includes/profiler/ProfilerSimpleTrace.php',
        'ProfilerSimpleUDP' => 'includes/profiler/ProfilerSimpleUDP.php',
index ba71aa0..9abc6a8 100644 (file)
@@ -30,7 +30,7 @@ class CategoryPage extends Article {
        protected $mCategoryViewerClass = 'CategoryViewer';
 
        /**
-        * @param $title Title
+        * @param Title $title
         * @return WikiCategoryPage
         */
        protected function newPage( Title $title ) {
@@ -40,7 +40,7 @@ class CategoryPage extends Article {
 
        /**
         * Constructor from a page id
-        * @param int $id article ID to load
+        * @param int $id Article ID to load
         * @return CategoryPage|null
         */
        public static function newFromID( $id ) {
index 987f3a7..88e15b3 100644 (file)
@@ -36,7 +36,7 @@ abstract class Collation {
 
        /**
         * @throws MWException
-        * @param $collationName string
+        * @param string $collationName
         * @return Collation
         */
        static function factory( $collationName ) {
index 8b8d75c..663098f 100644 (file)
@@ -70,7 +70,7 @@ $wgConfigClass = 'GlobalConfig';
  * MediaWiki version number
  * @since 1.2
  */
-$wgVersion = '1.23alpha';
+$wgVersion = '1.24alpha';
 
 /**
  * Name of the site. It must be changed in LocalSettings.php
@@ -5092,18 +5092,6 @@ $wgProfileLimit = 0.0;
  */
 $wgProfileOnly = false;
 
-/**
- * Log sums from profiling into "profiling" table in db.
- *
- * You have to create a 'profiling' table in your database before using
- * this feature.  Run set $wgProfileToDatabase to true in
- * LocalSettings.php and run maintenance/update.php or otherwise
- * manually add patch-profiling.sql to your database.
- *
- * To enable profiling, edit StartProfiler.php
- */
-$wgProfileToDatabase = false;
-
 /**
  * If true, print a raw call tree instead of per-function report
  */
index cef19e1..c900306 100644 (file)
@@ -2881,15 +2881,6 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(),
        if ( $useLogPipe ) {
                $desc[3] = array( 'pipe', 'w' );
        }
-
-       # TODO/FIXME: This is a bad hack to workaround an HHVM bug that prevents
-       # proc_open() from opening stdin/stdout, so use /dev/null *for now*
-       # See bug 56597 / https://github.com/facebook/hhvm/issues/1247 for more info
-       if ( wfIsHHVM() ) {
-               $desc[0] = array( 'file', '/dev/null', 'r' );
-               $desc[2] = array( 'file', '/dev/null', 'w' );
-       }
-
        $pipes = null;
        $proc = proc_open( $cmd, $desc, $pipes );
        if ( !$proc ) {
index 9b641c3..052ab34 100644 (file)
@@ -295,7 +295,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the URL to redirect to, or an empty string if not redirect URL set
         *
-        * @return String
+        * @return string
         */
        public function getRedirect() {
                return $this->mRedirect;
@@ -304,7 +304,7 @@ class OutputPage extends ContextSource {
        /**
         * Set the HTTP status code to send with the output.
         *
-        * @param $statusCode Integer
+        * @param int $statusCode
         */
        public function setStatusCode( $statusCode ) {
                $this->mStatusCode = $statusCode;
@@ -355,7 +355,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the value of the "rel" attribute for metadata links
         *
-        * @return String
+        * @return string
         */
        public function getMetadataAttribute() {
                # note: buggy CC software only reads first "meta" link
@@ -392,7 +392,7 @@ class OutputPage extends ContextSource {
        /**
         * Get all styles added by extensions
         *
-        * @return Array
+        * @return array
         */
        function getExtStyle() {
                return $this->mExtStyles;
@@ -431,7 +431,7 @@ class OutputPage extends ContextSource {
        /**
         * Get all registered JS and CSS tags for the header.
         *
-        * @return String
+        * @return string
         */
        function getScript() {
                return $this->mScripts . $this->getHeadItems();
@@ -440,10 +440,10 @@ class OutputPage extends ContextSource {
        /**
         * Filter an array of modules to remove insufficiently trustworthy members, and modules
         * which are no longer registered (eg a page is cached before an extension is disabled)
-        * @param $modules Array
-        * @param string $position if not null, only return modules with this position
-        * @param $type string
-        * @return Array
+        * @param array $modules
+        * @param string|null $position if not null, only return modules with this position
+        * @param string $type
+        * @return array
         */
        protected function filterModules( $modules, $position = null, $type = ResourceLoaderModule::TYPE_COMBINED ) {
                $resourceLoader = $this->getResourceLoader();
@@ -464,10 +464,10 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of modules to include on this page
         *
-        * @param bool $filter whether to filter out insufficiently trustworthy modules
-        * @param string $position if not null, only return modules with this position
-        * @param $param string
-        * @return Array of module names
+        * @param bool $filter Whether to filter out insufficiently trustworthy modules
+        * @param string|null $position If not null, only return modules with this position
+        * @param string $param
+        * @return array Array of module names
         */
        public function getModules( $filter = false, $position = null, $param = 'mModules' ) {
                $modules = array_values( array_unique( $this->$param ) );
@@ -490,10 +490,10 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of module JS to include on this page
         *
-        * @param $filter
-        * @param $position
+        * @param bool $filter
+        * @param string|null $position
         *
-        * @return array of module names
+        * @return array Array of module names
         */
        public function getModuleScripts( $filter = false, $position = null ) {
                return $this->getModules( $filter, $position, 'mModuleScripts' );
@@ -513,10 +513,10 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of module CSS to include on this page
         *
-        * @param $filter
-        * @param $position
+        * @param bool $filter
+        * @param string|null $position
         *
-        * @return Array of module names
+        * @return array Array of module names
         */
        public function getModuleStyles( $filter = false, $position = null ) {
                return $this->getModules( $filter, $position, 'mModuleStyles' );
@@ -538,10 +538,10 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of module messages to include on this page
         *
-        * @param $filter
-        * @param $position
+        * @param bool $filter
+        * @param string|null $position
         *
-        * @return Array of module names
+        * @return array Array of module names
         */
        public function getModuleMessages( $filter = false, $position = null ) {
                return $this->getModules( $filter, $position, 'mModuleMessages' );
@@ -568,7 +568,7 @@ class OutputPage extends ContextSource {
        /**
         * Sets ResourceLoader target for load.php links. If null, will be omitted
         *
-        * @param $target string|null
+        * @param string|null $target
         */
        public function setTarget( $target ) {
                $this->mTarget = $target;
@@ -577,7 +577,7 @@ class OutputPage extends ContextSource {
        /**
         * Get an array of head items
         *
-        * @return Array
+        * @return array
         */
        function getHeadItemsArray() {
                return $this->mHeadItems;
@@ -586,7 +586,7 @@ class OutputPage extends ContextSource {
        /**
         * Get all header items in a string
         *
-        * @return String
+        * @return string
         */
        function getHeadItems() {
                $s = '';
@@ -609,8 +609,8 @@ class OutputPage extends ContextSource {
        /**
         * Check if the header item $name is already set
         *
-        * @param string $name item name
-        * @return Boolean
+        * @param string $name Item name
+        * @return bool
         */
        public function hasHeadItem( $name ) {
                return isset( $this->mHeadItems[$name] );
@@ -639,7 +639,7 @@ class OutputPage extends ContextSource {
        /**
         * Return whether the output will contain only the body of the article
         *
-        * @return Boolean
+        * @return bool
         */
        public function getArticleBodyOnly() {
                return $this->mArticleBodyOnly;
@@ -833,7 +833,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the value of the "action text"
         *
-        * @return String
+        * @return string
         */
        public function getPageTitleActionText() {
                if ( isset( $this->mPageTitleActionText ) ) {
@@ -846,7 +846,7 @@ class OutputPage extends ContextSource {
         * "HTML title" means the contents of "<title>".
         * It is stored as plain, unescaped text and will be run through htmlspecialchars in the skin file.
         *
-        * @param $name string
+        * @param string $name
         */
        public function setHTMLTitle( $name ) {
                if ( $name instanceof Message ) {
@@ -859,7 +859,7 @@ class OutputPage extends ContextSource {
        /**
         * Return the "HTML title", i.e. the content of the "<title>" tag.
         *
-        * @return String
+        * @return string
         */
        public function getHTMLTitle() {
                return $this->mHTMLtitle;
@@ -868,7 +868,7 @@ class OutputPage extends ContextSource {
        /**
         * Set $mRedirectedFrom, the Title of the page which redirected us to the current page.
         *
-        * @param $t Title
+        * @param Title $t
         */
        public function setRedirectedFrom( $t ) {
                $this->mRedirectedFrom = $t;
@@ -880,7 +880,7 @@ class OutputPage extends ContextSource {
         * This function automatically sets \<title\> to the same content as \<h1\> but with all tags removed.
         * Bad tags that were escaped in \<h1\> will still be escaped in \<title\>, and good tags like \<i\> will be dropped entirely.
         *
-        * @param $name string|Message
+        * @param string|Message $name
         */
        public function setPageTitle( $name ) {
                if ( $name instanceof Message ) {
@@ -902,7 +902,7 @@ class OutputPage extends ContextSource {
        /**
         * Return the "page title", i.e. the content of the \<h1\> tag.
         *
-        * @return String
+        * @return string
         */
        public function getPageTitle() {
                return $this->mPagetitle;
@@ -911,7 +911,7 @@ class OutputPage extends ContextSource {
        /**
         * Set the Title object to use
         *
-        * @param $t Title object
+        * @param Title $t
         */
        public function setTitle( Title $t ) {
                $this->getContext()->setTitle( $t );
@@ -953,7 +953,7 @@ class OutputPage extends ContextSource {
        /**
         * Add a subtitle containing a backlink to a page
         *
-        * @param $title Title to link to
+        * @param Title $title Title to link to
         */
        public function addBacklinkSubtitle( Title $title ) {
                $query = array();
@@ -973,7 +973,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the subtitle
         *
-        * @return String
+        * @return string
         */
        public function getSubtitle() {
                return implode( "<br />\n\t\t\t\t", $this->mSubtitle );
@@ -990,7 +990,7 @@ class OutputPage extends ContextSource {
        /**
         * Return whether the page is "printable"
         *
-        * @return Boolean
+        * @return bool
         */
        public function isPrintable() {
                return $this->mPrintable;
@@ -1006,7 +1006,7 @@ class OutputPage extends ContextSource {
        /**
         * Return whether the output will be completely disabled
         *
-        * @return Boolean
+        * @return bool
         */
        public function isDisabled() {
                return $this->mDoNothing;
@@ -1015,7 +1015,7 @@ class OutputPage extends ContextSource {
        /**
         * Show an "add new section" link?
         *
-        * @return Boolean
+        * @return bool
         */
        public function showNewSectionLink() {
                return $this->mNewSectionLink;
@@ -1024,7 +1024,7 @@ class OutputPage extends ContextSource {
        /**
         * Forcibly hide the new section link?
         *
-        * @return Boolean
+        * @return bool
         */
        public function forceHideNewSectionLink() {
                return $this->mHideNewSectionLink;
@@ -1085,7 +1085,7 @@ class OutputPage extends ContextSource {
 
        /**
         * Should we output feed links for this page?
-        * @return Boolean
+        * @return bool
         */
        public function isSyndicated() {
                return count( $this->mFeedLinks ) > 0;
@@ -1113,7 +1113,7 @@ class OutputPage extends ContextSource {
         * corresponding article on the wiki
         * Setting true will cause the change "article related" toggle to true
         *
-        * @param $v Boolean
+        * @param bool $v
         */
        public function setArticleFlag( $v ) {
                $this->mIsarticle = $v;
@@ -1126,7 +1126,7 @@ class OutputPage extends ContextSource {
         * Return whether the content displayed page is related to the source of
         * the corresponding article on the wiki
         *
-        * @return Boolean
+        * @return bool
         */
        public function isArticle() {
                return $this->mIsarticle;
@@ -1136,7 +1136,7 @@ class OutputPage extends ContextSource {
         * Set whether this page is related an article on the wiki
         * Setting false will cause the change of "article flag" toggle to false
         *
-        * @param $v Boolean
+        * @param bool $v
         */
        public function setArticleRelated( $v ) {
                $this->mIsArticleRelated = $v;
@@ -1148,7 +1148,7 @@ class OutputPage extends ContextSource {
        /**
         * Return whether this page is related an article on the wiki
         *
-        * @return Boolean
+        * @return bool
         */
        public function isArticleRelated() {
                return $this->mIsArticleRelated;
@@ -1177,7 +1177,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of language links
         *
-        * @return Array of Interwiki Prefixed (non DB key) Titles (e.g. 'fr:Test page')
+        * @return array Array of Interwiki Prefixed (non DB key) Titles (e.g. 'fr:Test page')
         */
        public function getLanguageLinks() {
                return $this->mLanguageLinks;
@@ -1260,7 +1260,7 @@ class OutputPage extends ContextSource {
         * hidden categories) and $link a HTML fragment with a link to the category
         * page
         *
-        * @return Array
+        * @return array
         */
        public function getCategoryLinks() {
                return $this->mCategoryLinks;
@@ -1269,7 +1269,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of category names this page belongs to
         *
-        * @return Array of strings
+        * @return array Array of strings
         */
        public function getCategories() {
                return $this->mCategories;
@@ -1290,7 +1290,7 @@ class OutputPage extends ContextSource {
         * Return whether user JavaScript is allowed for this page
         * @deprecated since 1.18 Load modules with ResourceLoader, and origin and
         *     trustworthiness is identified and enforced automagically.
-        * @return Boolean
+        * @return bool
         */
        public function isUserJsAllowed() {
                wfDeprecated( __METHOD__, '1.18' );
@@ -1301,7 +1301,7 @@ class OutputPage extends ContextSource {
         * Show what level of JavaScript / CSS untrustworthiness is allowed on this page
         * @see ResourceLoaderModule::$origin
         * @param string $type ResourceLoaderModule TYPE_ constant
-        * @return Int ResourceLoaderModule ORIGIN_ class constant
+        * @return int ResourceLoaderModule ORIGIN_ class constant
         */
        public function getAllowedModules( $type ) {
                if ( $type == ResourceLoaderModule::TYPE_COMBINED ) {
@@ -1315,8 +1315,8 @@ class OutputPage extends ContextSource {
 
        /**
         * Set the highest level of CSS/JS untrustworthiness allowed
-        * @param $type String ResourceLoaderModule TYPE_ constant
-        * @param $level Int ResourceLoaderModule class constant
+        * @param string $type ResourceLoaderModule TYPE_ constant
+        * @param int $level ResourceLoaderModule class constant
         */
        public function setAllowedModules( $type, $level ) {
                $this->mAllowedModules[$type] = $level;
@@ -1324,8 +1324,8 @@ class OutputPage extends ContextSource {
 
        /**
         * As for setAllowedModules(), but don't inadvertently make the page more accessible
-        * @param $type String
-        * @param $level Int ResourceLoaderModule class constant
+        * @param string $type
+        * @param int $level ResourceLoaderModule class constant
         */
        public function reduceAllowedModules( $type, $level ) {
                $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level );
@@ -1354,9 +1354,9 @@ class OutputPage extends ContextSource {
         *
         * @since 1.19
         *
-        * @param $element string
-        * @param $attribs array
-        * @param $contents string
+        * @param string $element
+        * @param array $attribs
+        * @param string $contents
         */
        public function addElement( $element, $attribs = array(), $contents = '' ) {
                $this->addHTML( Html::element( $element, $attribs, $contents ) );
@@ -1381,9 +1381,9 @@ class OutputPage extends ContextSource {
        /**
         * Get/set the ParserOptions object to use for wikitext parsing
         *
-        * @param $options ParserOptions|null either the ParserOption to use or null to only get the
-        *                 current ParserOption object
-        * @return ParserOptions object
+        * @param ParserOptions|null $options Either the ParserOption to use or null to only get the
+        *   current ParserOption object
+        * @return ParserOptions
         */
        public function parserOptions( $options = null ) {
                if ( !$this->mParserOptions ) {
@@ -1408,7 +1408,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the displayed revision ID
         *
-        * @return Integer
+        * @return int
         */
        public function getRevisionId() {
                return $this->mRevisionId;
@@ -1429,7 +1429,7 @@ class OutputPage extends ContextSource {
         * Get the timestamp of displayed revision.
         * This will be null if not filled by setRevisionTimestamp().
         *
-        * @return String or null
+        * @return string|null
         */
        public function getRevisionTimestamp() {
                return $this->mRevisionTimestamp;
@@ -1452,7 +1452,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the displayed file version
         *
-        * @return Array|null ('time' => MW timestamp, 'sha1' => sha1)
+        * @return array|null ('time' => MW timestamp, 'sha1' => sha1)
         */
        public function getFileVersion() {
                return $this->mFileVersion;
@@ -1461,7 +1461,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the templates used on this page
         *
-        * @return Array (namespace => dbKey => revId)
+        * @return array (namespace => dbKey => revId)
         * @since 1.18
         */
        public function getTemplateIds() {
@@ -1471,7 +1471,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the files used on this page
         *
-        * @return Array (dbKey => array('time' => MW timestamp or null, 'sha1' => sha1 or ''))
+        * @return array (dbKey => array('time' => MW timestamp or null, 'sha1' => sha1 or ''))
         * @since 1.18
         */
        public function getFileSearchOptions() {
@@ -1561,7 +1561,7 @@ class OutputPage extends ContextSource {
        /**
         * Add a ParserOutput object, but without Html
         *
-        * @param $parserOutput ParserOutput object
+        * @param ParserOutput $parserOutput
         */
        public function addParserOutputNoText( &$parserOutput ) {
                $this->mLanguageLinks += $parserOutput->getLanguageLinks();
@@ -1613,7 +1613,7 @@ class OutputPage extends ContextSource {
        /**
         * Add a ParserOutput object
         *
-        * @param $parserOutput ParserOutput
+        * @param ParserOutput $parserOutput
         */
        function addParserOutput( &$parserOutput ) {
                $this->addParserOutputNoText( $parserOutput );
@@ -1631,7 +1631,7 @@ class OutputPage extends ContextSource {
        /**
         * Add the output of a QuickTemplate to the output buffer
         *
-        * @param $template QuickTemplate
+        * @param QuickTemplate $template
         */
        public function addTemplate( &$template ) {
                $this->addHTML( $template->getHTML() );
@@ -1640,7 +1640,7 @@ class OutputPage extends ContextSource {
        /**
         * Parse wikitext and return the HTML.
         *
-        * @param String $text
+        * @param string $text
         * @param bool $linestart Is this the start of a line?
         * @param bool $interface Use interface language ($wgLang instead of
         *   $wgContLang) while parsing language sensitive magic words like GRAMMAR and PLURAL.
@@ -1712,7 +1712,7 @@ class OutputPage extends ContextSource {
        /**
         * Use enableClientCache(false) to force it to send nocache headers
         *
-        * @param $state bool
+        * @param bool $state
         *
         * @return bool
         */
@@ -1723,7 +1723,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of cookies that will influence on the cache
         *
-        * @return Array
+        * @return array
         */
        function getCacheVaryCookies() {
                global $wgCookiePrefix, $wgCacheVaryCookies;
@@ -1747,7 +1747,7 @@ class OutputPage extends ContextSource {
         * Check if the request has a cache-varying cookie header
         * If it does, it's very important that we don't allow public caching
         *
-        * @return Boolean
+        * @return bool
         */
        function haveCacheVaryCookies() {
                $cookieHeader = $this->getRequest()->getHeader( 'cookie' );
@@ -1770,7 +1770,7 @@ class OutputPage extends ContextSource {
         * Add an HTTP header that will influence on the cache
         *
         * @param string $header header name
-        * @param $option Array|null
+        * @param array|null $option
         * @todo FIXME: Document the $option parameter; it appears to be for
         *        X-Vary-Options but what format is acceptable?
         */
@@ -1791,7 +1791,7 @@ class OutputPage extends ContextSource {
         * Return a Vary: header on which to vary caches. Based on the keys of $mVaryHeader,
         * such as Accept-Encoding or Cookie
         *
-        * @return String
+        * @return string
         */
        public function getVaryHeader() {
                return 'Vary: ' . join( ', ', array_keys( $this->mVaryHeader ) );
@@ -1800,7 +1800,7 @@ class OutputPage extends ContextSource {
        /**
         * Get a complete X-Vary-Options header
         *
-        * @return String
+        * @return string
         */
        public function getXVO() {
                $cvCookies = $this->getCacheVaryCookies();
@@ -1864,7 +1864,7 @@ class OutputPage extends ContextSource {
         * This is the default for special pages. If you display a CSRF-protected
         * form on an ordinary view page, then you need to call this function.
         *
-        * @param $enable bool
+        * @param bool $enable
         */
        public function preventClickjacking( $enable = true ) {
                $this->mPreventClickjacking = $enable;
@@ -2442,10 +2442,10 @@ $templates
        /**
         * Add a "return to" link pointing to a specified title
         *
-        * @param $title Title to link
-        * @param array $query query string parameters
-        * @param string $text text of the link (input is not escaped)
-        * @param $options Options array to pass to Linker
+        * @param Title $title Title to link
+        * @param array $query Query string parameters
+        * @param string $text Text of the link (input is not escaped)
+        * @param array $options Options array to pass to Linker
         */
        public function addReturnTo( $title, $query = array(), $text = null, $options = array() ) {
                $link = $this->msg( 'returnto' )->rawParams(
@@ -2457,9 +2457,9 @@ $templates
         * Add a "return to" link pointing to a specified title,
         * or the title indicated in the request, or else the main page
         *
-        * @param $unused
-        * @param $returnto Title or String to return to
-        * @param string $returntoquery query string for the return to link
+        * @param mixed $unused
+        * @param Title|string $returnto Title or String to return to
+        * @param string $returntoquery Query string for the return to link
         */
        public function returnToMain( $unused = null, $returnto = null, $returntoquery = null ) {
                if ( $returnto == null ) {
@@ -2588,9 +2588,9 @@ $templates
         * TODO: Document
         * @param array|string $modules One or more module names
         * @param string $only ResourceLoaderModule TYPE_ class constant
-        * @param boolean $useESI
-        * @param array $extraQuery with extra query parameters to add to each request. array( param => value )
-        * @param boolean $loadCall If true, output an (asynchronous) mw.loader.load() call rather than a "<script src='...'>" tag
+        * @param bool $useESI
+        * @param array $extraQuery Array with extra query parameters to add to each request. array( param => value )
+        * @param bool $loadCall If true, output an (asynchronous) mw.loader.load() call rather than a "<script src='...'>" tag
         * @return string The html "<script>", "<link>" and "<style>" tags
         */
        protected function makeResourceLoaderLink( $modules, $only, $useESI = false, array $extraQuery = array(), $loadCall = false ) {
@@ -2864,7 +2864,7 @@ $templates
         * modules marked with position 'bottom', legacy scripts ($this->mScripts),
         * user preferences, site JS and user JS.
         *
-        * @param $inHead boolean If true, this HTML goes into the "<head>", if false it goes into the "<body>"
+        * @param bool $inHead If true, this HTML goes into the "<head>", if false it goes into the "<body>"
         * @return string
         */
        function getScriptsForBottomQueue( $inHead ) {
@@ -2954,7 +2954,7 @@ $templates
        /**
         * Get the javascript config vars to include on this page
         *
-        * @return Array of javascript config vars
+        * @return array Array of javascript config vars
         * @since 1.23
         */
        public function getJsConfigVars() {
@@ -2962,10 +2962,10 @@ $templates
        }
 
        /**
-        * Add one or more variables to be set in mw.config in JavaScript.
+        * Add one or more variables to be set in mw.config in JavaScript
         *
-        * @param $keys {String|Array} Key or array of key/value pairs.
-        * @param $value {Mixed} [optional] Value of the configuration variable.
+        * @param string|array $keys Key or array of key/value pairs
+        * @param mixed $value [optional] Value of the configuration variable
         */
        public function addJsConfigVars( $keys, $value = null ) {
                if ( is_array( $keys ) ) {
@@ -3483,7 +3483,7 @@ $templates
        }
 
        /**
-        * @return Array
+        * @return array
         */
        public function buildCssLinksArray() {
                $links = array();
@@ -3604,8 +3604,8 @@ $templates
         * Like addWikiMsg() except the parameters are taken as an array
         * instead of a variable argument list.
         *
-        * @param $name string
-        * @param $args array
+        * @param string $name
+        * @param array $args
         */
        public function addWikiMsgArray( $name, $args ) {
                $this->addHTML( $this->msg( $name, $args )->parseAsBlock() );
@@ -3632,7 +3632,7 @@ $templates
         *
         * The newline after opening div is needed in some wikitext. See bug 19226.
         *
-        * @param $wrap string
+        * @param string $wrap
         */
        public function wrapWikiMsg( $wrap /*, ...*/ ) {
                $msgSpecs = func_get_args();
index 60aa33c..9b5373b 100644 (file)
@@ -38,7 +38,7 @@
  * version are hardcoded here
  */
 function wfPHPVersionError( $type ) {
-       $mwVersion = '1.23';
+       $mwVersion = '1.24';
        $minimumVersionPHP = '5.3.2';
 
        $phpVersion = phpversion();
index d026b97..1825cce 100644 (file)
@@ -1065,9 +1065,8 @@ class Preferences {
                $mptitle = Title::newMainPage();
                $previewtext = $context->msg( 'skin-preview' )->text();
 
-               # Only show members of Skin::getSkinNames() rather than
-               # $skinNames (skins is all skin names from Language.php)
-               $validSkinNames = Skin::getUsableSkins();
+               # Only show skins that aren't disabled in $wgSkipSkins
+               $validSkinNames = Skin::getAllowedSkins();
 
                # Sort by UI skin name. First though need to update validSkinNames as sometimes
                # the skinkey & UI skinname differ (e.g. "standard" skinkey is "Classic" in the UI).
index 957a119..45c591a 100644 (file)
@@ -192,13 +192,11 @@ abstract class PrefixSearch {
                $srchres = array();
                foreach ( $keys as $pageKey => $page ) {
                        if ( $searchKey === '' || strpos( $pageKey, $searchKey ) === 0 ) {
-                               wfSuppressWarnings();
                                // bug 27671: Don't use SpecialPage::getTitleFor() here because it
                                // localizes its input leading to searches for e.g. Special:All
                                // returning Spezial:MediaWiki-Systemnachrichten and returning
                                // Spezial:Alle_Seiten twice when $wgLanguageCode == 'de'
                                $srchres[] = Title::makeTitleSafe( NS_SPECIAL, $page );
-                               wfRestoreWarnings();
                        }
 
                        if ( count( $srchres ) >= $limit ) {
index 20c6021..b155f90 100644 (file)
@@ -1,6 +1,10 @@
 <?php
 /**
- * Include most things that's need to customize the site.
+ * Include most things that are needed to make %MediaWiki work.
+ *
+ * This file is included by WebStart.php and doMaintenance.php so that both
+ * web and maintenance scripts share a final set up phase to include necessary
+ * files and create global object variables.
  *
  * 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
@@ -28,12 +32,6 @@ if ( !defined( 'MEDIAWIKI' ) ) {
        exit( 1 );
 }
 
-# The main wiki script and things like database
-# conversion and maintenance scripts all share a
-# common setup of including lots of classes and
-# setting up a few globals.
-#
-
 $fname = 'Setup.php';
 wfProfileIn( $fname );
 wfProfileIn( $fname . '-defaults' );
@@ -61,8 +59,8 @@ if ( $wgArticlePath === false ) {
 }
 
 if ( !empty( $wgActionPaths ) && !isset( $wgActionPaths['view'] ) ) {
-       # 'view' is assumed the default action path everywhere in the code
-       # but is rarely filled in $wgActionPaths
+       // 'view' is assumed the default action path everywhere in the code
+       // but is rarely filled in $wgActionPaths
        $wgActionPaths['view'] = $wgArticlePath;
 }
 
@@ -249,9 +247,9 @@ foreach ( $wgForeignFileRepos as &$repo ) {
 unset( $repo ); // no global pollution; destroy reference
 
 if ( $wgRCFilterByAge ) {
-       # # Trim down $wgRCLinkDays so that it only lists links which are valid
-       # # as determined by $wgRCMaxAge.
-       # # Note that we allow 1 link higher than the max for things like 56 days but a 60 day link.
+       // Trim down $wgRCLinkDays so that it only lists links which are valid
+       // as determined by $wgRCMaxAge.
+       // Note that we allow 1 link higher than the max for things like 56 days but a 60 day link.
        sort( $wgRCLinkDays );
        for ( $i = 0; $i < count( $wgRCLinkDays ); $i++ ) {
                if ( $wgRCLinkDays[$i] >= $wgRCMaxAge / ( 3600 * 24 ) ) {
@@ -269,7 +267,7 @@ if ( $wgLocalInterwiki ) {
        array_unshift( $wgLocalInterwikis, $wgLocalInterwiki );
 }
 
-# Set default shared prefix
+// Set default shared prefix
 if ( $wgSharedPrefix === false ) {
        $wgSharedPrefix = $wgDBprefix;
 }
@@ -328,31 +326,31 @@ if ( is_array( $wgExtraNamespaces ) ) {
        $wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces;
 }
 
-# These are now the same, always
-# To determine the user language, use $wgLang->getCode()
+// These are now the same, always
+// To determine the user language, use $wgLang->getCode()
 $wgContLanguageCode = $wgLanguageCode;
 
-# Easy to forget to falsify $wgShowIPinHeader for static caches.
-# If file cache or squid cache is on, just disable this (DWIMD).
-# Do the same for $wgDebugToolbar.
+// Easy to forget to falsify $wgShowIPinHeader for static caches.
+// If file cache or squid cache is on, just disable this (DWIMD).
+// Do the same for $wgDebugToolbar.
 if ( $wgUseFileCache || $wgUseSquid ) {
        $wgShowIPinHeader = false;
        $wgDebugToolbar = false;
 }
 
-# Doesn't make sense to have if disabled.
+// Doesn't make sense to have if disabled.
 if ( !$wgEnotifMinorEdits ) {
        $wgHiddenPrefs[] = 'enotifminoredits';
 }
 
-# We always output HTML5 since 1.22, overriding these is no longer supported
-# we set them here for extensions that depend on its value.
+// We always output HTML5 since 1.22, overriding these is no longer supported
+// we set them here for extensions that depend on its value.
 $wgHtml5 = true;
 $wgXhtmlDefaultNamespace = 'http://www.w3.org/1999/xhtml';
 $wgJsMimeType = 'text/javascript';
 
 if ( !$wgHtml5Version && $wgAllowRdfaAttributes ) {
-       # see http://www.w3.org/TR/rdfa-in-html/#document-conformance
+       // see http://www.w3.org/TR/rdfa-in-html/#document-conformance
        if ( $wgMimeType == 'application/xhtml+xml' ) {
                $wgHtml5Version = 'XHTML+RDFa 1.0';
        } else {
@@ -360,7 +358,7 @@ if ( !$wgHtml5Version && $wgAllowRdfaAttributes ) {
        }
 }
 
-# Blacklisted file extensions shouldn't appear on the "allowed" list
+// Blacklisted file extensions shouldn't appear on the "allowed" list
 $wgFileExtensions = array_values( array_diff ( $wgFileExtensions, $wgFileBlacklist ) );
 
 if ( $wgArticleCountMethod === null ) {
@@ -372,7 +370,7 @@ if ( $wgInvalidateCacheOnLocalSettingsChange ) {
 }
 
 if ( $wgNewUserLog ) {
-       # Add a new log type
+       // Add a new log type
        $wgLogTypes[] = 'newusers';
        $wgLogNames['newusers'] = 'newuserlogpage';
        $wgLogHeaders['newusers'] = 'newuserlogpagetext';
@@ -427,8 +425,8 @@ if ( $wgSecureLogin && substr( $wgServer, 0, 2 ) !== '//' ) {
        wfWarn( 'Secure login was enabled on a server that only supports HTTP or HTTPS. Disabling secure login.' );
 }
 
-# Now that GlobalFunctions is loaded, set defaults that depend
-# on it.
+// Now that GlobalFunctions is loaded, set defaults that depend
+// on it.
 if ( $wgTmpDirectory === false ) {
        wfProfileIn( $fname . '-tempDir' );
        $wgTmpDirectory = wfTempDir();
@@ -469,7 +467,7 @@ if ( $wgProfileOnly ) {
 wfProfileOut( $fname . '-defaults2' );
 wfProfileIn( $fname . '-misc1' );
 
-# Raise the memory limit if it's too low
+// Raise the memory limit if it's too low
 wfMemoryLimit();
 
 /**
@@ -488,13 +486,13 @@ if ( is_null( $wgLocalTZoffset ) ) {
        $wgLocalTZoffset = date( 'Z' ) / 60;
 }
 
-# Useful debug output
+// Useful debug output
 if ( $wgCommandLineMode ) {
        $wgRequest = new FauxRequest( array() );
 
        wfDebug( "\n\nStart command line script $self\n" );
 } else {
-       # Can't stub this one, it sets up $_GET and $_REQUEST in its constructor
+       // Can't stub this one, it sets up $_GET and $_REQUEST in its constructor
        $wgRequest = new WebRequest;
 
        $debug = "\n\nStart request {$wgRequest->getMethod()} {$wgRequest->getRequestURL()}\n";
@@ -523,12 +521,12 @@ wfDebugLog( 'caches', 'main: ' . get_class( $wgMemc ) .
 
 wfProfileOut( $fname . '-memcached' );
 
-# # Most of the config is out, some might want to run hooks here.
+// Most of the config is out, some might want to run hooks here.
 wfRunHooks( 'SetupAfterCache' );
 
 wfProfileIn( $fname . '-session' );
 
-# If session.auto_start is there, we can't touch session name
+// If session.auto_start is there, we can't touch session name
 if ( !wfIniGetBool( 'session.auto_start' ) ) {
        session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' );
 }
@@ -551,7 +549,7 @@ $wgContLang->initContLang();
 
 // Now that variant lists may be available...
 $wgRequest->interpolateTitle();
-$wgUser = RequestContext::getMain()->getUser(); # BackCompat
+$wgUser = RequestContext::getMain()->getUser(); // BackCompat
 
 /**
  * @var $wgLang Language
@@ -561,7 +559,7 @@ $wgLang = new StubUserLang;
 /**
  * @var OutputPage
  */
-$wgOut = RequestContext::getMain()->getOutput(); # BackCompat
+$wgOut = RequestContext::getMain()->getOutput(); // BackCompat
 
 /**
  * @var $wgParser Parser
@@ -581,12 +579,12 @@ $wgDeferredUpdateList = array();
 wfProfileOut( $fname . '-globals' );
 wfProfileIn( $fname . '-extensions' );
 
-# Extension setup functions for extensions other than skins
-# Entries should be added to this variable during the inclusion
-# of the extension file. This allows the extension to perform
-# any necessary initialisation in the fully initialised environment
+// Extension setup functions for extensions other than skins
+// Entries should be added to this variable during the inclusion
+// 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+
+       // Allow closures in PHP 5.3+
        if ( is_object( $func ) && $func instanceof Closure ) {
                $profName = $fname . '-extensions-closure';
        } elseif ( is_array( $func ) ) {
index 9ec7c31..e6abdfb 100644 (file)
@@ -92,9 +92,9 @@ abstract class Skin extends ContextSource {
         * Fetch the list of user-selectable skins in regards to $wgSkipSkins.
         * Useful for Special:Preferences and other places where you
         * only want to show skins users _can_ use.
-        * @return array of strings
+        * @return string[]
         */
-       public static function getUsableSkins() {
+       public static function getAllowedSkins() {
                global $wgSkipSkins;
 
                $allowedSkins = self::getSkinNames();
@@ -106,6 +106,15 @@ abstract class Skin extends ContextSource {
                return $allowedSkins;
        }
 
+       /**
+        * @deprecated since 1.23, use getAllowedSkins
+        * @return string[]
+        */
+       public static function getUsableSkins() {
+               wfDeprecated( __METHOD__, '1.23' );
+               return self::getAllowedSkins();
+       }
+
        /**
         * Normalize a skin preference value to a form that can be loaded.
         * If a skin can't be found, it will fall back to the configured
index eac9211..b67d9f4 100644 (file)
@@ -30,7 +30,7 @@
  */
 abstract class TitleArray implements Iterator {
        /**
-        * @param $res ResultWrapper A SQL result including at least page_namespace and
+        * @param ResultWrapper $res A SQL result including at least page_namespace and
         *   page_title -- also can have page_id, page_len, page_is_redirect,
         *   page_latest (if those will be used).  See Title::newFromRow.
         * @return TitleArrayFromResult
@@ -47,7 +47,7 @@ abstract class TitleArray implements Iterator {
        }
 
        /**
-        * @param $res ResultWrapper
+        * @param ResultWrapper $res
         * @return TitleArrayFromResult
         */
        protected static function newFromResult_internal( $res ) {
index b4a553f..4fcb2eb 100644 (file)
@@ -39,7 +39,7 @@ class TitleArrayFromResult extends TitleArray implements Countable {
        }
 
        /**
-        * @param $row ResultWrapper
+        * @param bool|ResultWrapper $row
         * @return void
         */
        protected function setCurrent( $row ) {
index 51fb154..7da6582 100644 (file)
@@ -22,7 +22,7 @@
 
 abstract class UserArray implements Iterator {
        /**
-        * @param $res ResultWrapper
+        * @param ResultWrapper $res
         * @return UserArrayFromResult
         */
        static function newFromResult( $res ) {
@@ -37,7 +37,7 @@ abstract class UserArray implements Iterator {
        }
 
        /**
-        * @param $ids array
+        * @param array $ids
         * @return UserArrayFromResult
         */
        static function newFromIDs( $ids ) {
@@ -57,7 +57,7 @@ abstract class UserArray implements Iterator {
        }
 
        /**
-        * @param $res
+        * @param ResultWrapper $res
         * @return UserArrayFromResult
         */
        protected static function newFromResult_internal( $res ) {
index 00366e4..0012b44 100644 (file)
@@ -29,7 +29,7 @@ class UserArrayFromResult extends UserArray implements Countable {
        var $key, $current;
 
        /**
-        * @param $res ResultWrapper
+        * @param ResultWrapper $res
         */
        function __construct( $res ) {
                $this->res = $res;
@@ -38,7 +38,7 @@ class UserArrayFromResult extends UserArray implements Countable {
        }
 
        /**
-        * @param $row
+        * @param bool|stdClass $row
         * @return void
         */
        protected function setCurrent( $row ) {
index a3dadd0..75efce5 100644 (file)
 class WebResponse {
 
        /**
-        * Output a HTTP header, wrapper for PHP's
-        * header()
+        * Output a HTTP header, wrapper for PHP's header()
         * @param string $string header to output
         * @param bool $replace replace current similar header
-        * @param $http_response_code null|int Forces the HTTP response code to the specified value.
+        * @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 ) {
                header( $string, $replace, $http_response_code );
@@ -126,7 +125,7 @@ class FauxResponse extends WebResponse {
         * Stores a HTTP header
         * @param string $string header to output
         * @param bool $replace replace current similar header
-        * @param $http_response_code null|int Forces the HTTP response code to the specified value.
+        * @param null|int $http_response_code Forces the HTTP response code to the specified value.
         */
        public function header( $string, $replace = true, $http_response_code = null ) {
                if ( substr( $string, 0, 5 ) == 'HTTP/' ) {
@@ -163,7 +162,7 @@ class FauxResponse extends WebResponse {
        /**
         * Get the HTTP response code, null if not set
         *
-        * @return Int or null
+        * @return int|null
         */
        public function getStatusCode() {
                return $this->code;
@@ -182,7 +181,7 @@ class FauxResponse extends WebResponse {
        }
 
        /**
-        * @param $name string
+        * @param string $name
         * @return string
         */
        public function getcookie( $name ) {
index fbafba8..9e8c720 100644 (file)
@@ -444,7 +444,15 @@ class MediaWiki {
        public function run() {
                try {
                        $this->checkMaxLag();
-                       $this->main();
+                       try {
+                               $this->main();
+                       } catch ( ErrorPageError $e ) {
+                               // Bug 62091: while exceptions are convenient to bubble up GUI errors,
+                               // they are not internal application faults. As with normal requests, this
+                               // should commit, print the output, do deferred updates, jobs, and profiling.
+                               wfGetLBFactory()->commitMasterChanges();
+                               $e->report(); // display the GUI error
+                       }
                        if ( function_exists( 'fastcgi_finish_request' ) ) {
                                fastcgi_finish_request();
                        }
index 3e8a1ce..44f0599 100644 (file)
@@ -47,7 +47,7 @@ class WikiFilePage extends WikiPage {
        }
 
        /**
-        * @param $file File:
+        * @param File $file
         */
        public function setFile( $file ) {
                $this->mFile = $file;
index 07a5c24..8fb104d 100644 (file)
@@ -50,15 +50,15 @@ abstract class Action {
 
        /**
         * The fields used to create the HTMLForm
-        * @var Array $fields
+        * @var array $fields
         */
        protected $fields;
 
        /**
         * Get the Action subclass which should be used to handle this action, false if
         * the action is disabled, or null if it's not recognised
-        * @param $action String
-        * @param $overrides Array
+        * @param string $action
+        * @param array $overrides
         * @return bool|null|string|callable
         */
        final private static function getClass( $action, array $overrides ) {
@@ -82,10 +82,10 @@ abstract class Action {
 
        /**
         * Get an appropriate Action subclass for the given action
-        * @param $action String
-        * @param $page Page
-        * @param $context IContextSource
-        * @return Action|bool|null false if the action is disabled, null
+        * @param string $action
+        * @param Page $page
+        * @param IContextSource $context
+        * @return Action|bool|null False if the action is disabled, null
         *     if it is not recognised
         */
        final public static function factory( $action, Page $page, IContextSource $context = null ) {
@@ -109,8 +109,8 @@ abstract class Action {
         * $wgActions will be replaced by "nosuchaction".
         *
         * @since 1.19
-        * @param $context IContextSource
-        * @return string: action name
+        * @param IContextSource $context
+        * @return string Action name
         */
        final public static function getActionName( IContextSource $context ) {
                global $wgActions;
@@ -153,8 +153,8 @@ abstract class Action {
        /**
         * Check if a given action is recognised, even if it's disabled
         *
-        * @param string $name name of an action
-        * @return Bool
+        * @param string $name Name of an action
+        * @return bool
         */
        final public static function exists( $name ) {
                return self::getClass( $name, array() ) !== null;
@@ -245,7 +245,7 @@ abstract class Action {
         * Get a Message object with context set
         * Parameters are the same as wfMessage()
         *
-        * @return Message object
+        * @return Message
         */
        final public function msg() {
                $params = func_get_args();
@@ -257,8 +257,8 @@ abstract class Action {
         *
         * Only public since 1.21
         *
-        * @param $page Page
-        * @param $context IContextSource
+        * @param Page $page
+        * @param IContextSource $context
         */
        public function __construct( Page $page, IContextSource $context = null ) {
                if ( $context === null ) {
@@ -273,14 +273,14 @@ abstract class Action {
 
        /**
         * Return the name of the action this object responds to
-        * @return String lowercase
+        * @return string Lowercase name
         */
        abstract public function getName();
 
        /**
         * Get the permission required to perform this action.  Often, but not always,
         * the same as the action name
-        * @return String|null
+        * @return string|null
         */
        public function getRestriction() {
                return null;
@@ -291,7 +291,7 @@ abstract class Action {
         * overridden by sub-classes with more complicated permissions schemes.  Failures here
         * must throw subclasses of ErrorPageError
         *
-        * @param $user User: the user to check, or null to use the context user
+        * @param User $user The user to check, or null to use the context user
         * @throws UserBlockedError|ReadOnlyError|PermissionsError
         * @return bool True on success
         */
@@ -320,7 +320,7 @@ abstract class Action {
 
        /**
         * Whether this action requires the wiki not to be locked
-        * @return Bool
+        * @return bool
         */
        public function requiresWrite() {
                return true;
@@ -328,7 +328,7 @@ abstract class Action {
 
        /**
         * Whether this action can still be executed by a blocked user
-        * @return Bool
+        * @return bool
         */
        public function requiresUnblock() {
                return true;
@@ -349,7 +349,7 @@ abstract class Action {
        /**
         * Returns the name that goes in the \<h1\> page title
         *
-        * @return String
+        * @return string
         */
        protected function getPageTitle() {
                return $this->getTitle()->getPrefixedText();
@@ -358,7 +358,7 @@ abstract class Action {
        /**
         * Returns the description that goes below the \<h1\> tag
         *
-        * @return String
+        * @return string
         */
        protected function getDescription() {
                return $this->msg( strtolower( $this->getName() ) )->escaped();
@@ -374,7 +374,7 @@ abstract class Action {
 
        /**
         * Execute the action in a silent fashion: do not display anything or release any errors.
-        * @return Bool whether execution was successful
+        * @return bool whether execution was successful
         */
        abstract public function execute();
 }
index 186ad46..32efc68 100644 (file)
@@ -58,7 +58,7 @@ abstract class CachedAction extends FormlessAction implements ICacheHelper {
         * If the cache is enabled or not.
         *
         * @since 1.20
-        * @var boolean
+        * @var bool
         */
        protected $cacheEnabled = true;
 
@@ -66,7 +66,7 @@ abstract class CachedAction extends FormlessAction implements ICacheHelper {
         * Sets if the cache should be enabled or not.
         *
         * @since 1.20
-        * @param boolean $cacheEnabled
+        * @param bool $cacheEnabled
         */
        public function setCacheEnabled( $cacheEnabled ) {
                $this->cacheHelper->setCacheEnabled( $cacheEnabled );
@@ -78,8 +78,8 @@ abstract class CachedAction extends FormlessAction implements ICacheHelper {
         *
         * @since 1.20
         *
-        * @param integer|null $cacheExpiry Sets the cache expiry, either ttl in seconds or unix timestamp.
-        * @param boolean|null $cacheEnabled Sets if the cache should be enabled or not.
+        * @param int|null $cacheExpiry Sets the cache expiry, either ttl in seconds or unix timestamp.
+        * @param bool|null $cacheEnabled Sets if the cache should be enabled or not.
         */
        public function startCache( $cacheExpiry = null, $cacheEnabled = null ) {
                $this->cacheHelper = new CacheHelper();
@@ -153,7 +153,7 @@ abstract class CachedAction extends FormlessAction implements ICacheHelper {
         *
         * @since 1.20
         *
-        * @param integer $cacheExpiry
+        * @param int $cacheExpiry
         */
        public function setExpiry( $cacheExpiry ) {
                $this->cacheHelper->setExpiry( $cacheExpiry );
@@ -179,7 +179,7 @@ abstract class CachedAction extends FormlessAction implements ICacheHelper {
         *
         * @since 1.20
         *
-        * @param boolean $hasCached
+        * @param bool $hasCached
         */
        public function onCacheInitialized( $hasCached ) {
                if ( $hasCached ) {
index 97c1605..2bb1be4 100644 (file)
@@ -39,7 +39,7 @@ class CreditsAction extends FormlessAction {
        /**
         * This is largely cadged from PageHistory::history
         *
-        * @return String HTML
+        * @return string HTML
         */
        public function onView() {
                wfProfileIn( __METHOD__ );
@@ -58,9 +58,9 @@ class CreditsAction extends FormlessAction {
        /**
         * Get a list of contributors
         *
-        * @param int $cnt maximum list of contributors to show
-        * @param bool $showIfMax whether to contributors if there more than $cnt
-        * @return String: html
+        * @param int $cnt Maximum list of contributors to show
+        * @param bool $showIfMax Whether to contributors if there more than $cnt
+        * @return string html
         */
        public function getCredits( $cnt, $showIfMax = true ) {
                wfProfileIn( __METHOD__ );
@@ -81,7 +81,7 @@ class CreditsAction extends FormlessAction {
        /**
         * Get the last author with the last modification time
         * @param Page $page
-        * @return String HTML
+        * @return string HTML
         */
        protected function getAuthor( Page $page ) {
                $user = User::newFromName( $page->getUserText(), false );
@@ -102,9 +102,9 @@ class CreditsAction extends FormlessAction {
 
        /**
         * Get a list of contributors of $article
-        * @param int $cnt maximum list of contributors to show
-        * @param bool $showIfMax whether to contributors if there more than $cnt
-        * @return String: html
+        * @param int $cnt Maximum list of contributors to show
+        * @param bool $showIfMax Whether to contributors if there more than $cnt
+        * @return string html
         */
        protected function getContributors( $cnt, $showIfMax ) {
                global $wgHiddenPrefs;
@@ -188,8 +188,8 @@ class CreditsAction extends FormlessAction {
 
        /**
         * Get a link to $user's user page
-        * @param $user User object
-        * @return String: html
+        * @param User $user
+        * @return string Html
         */
        protected function link( User $user ) {
                global $wgHiddenPrefs;
@@ -208,8 +208,8 @@ class CreditsAction extends FormlessAction {
 
        /**
         * Get a link to $user's user page
-        * @param $user User object
-        * @return String: html
+        * @param User $user
+        * @return string Html
         */
        protected function userLink( User $user ) {
                $link = $this->link( $user );
@@ -227,7 +227,7 @@ class CreditsAction extends FormlessAction {
 
        /**
         * Get a link to action=credits of $article page
-        * @return String: HTML link
+        * @return string HTML link
         */
        protected function othersLink() {
                return Linker::linkKnown(
index 73bf187..7477d11 100644 (file)
@@ -30,13 +30,13 @@ abstract class FormAction extends Action {
 
        /**
         * Get an HTMLForm descriptor array
-        * @return Array
+        * @return array
         */
        abstract protected function getFormFields();
 
        /**
         * Add pre- or post-text to the form
-        * @return String HTML which will be sent to $form->addPreText()
+        * @return string HTML which will be sent to $form->addPreText()
         */
        protected function preText() {
                return '';
@@ -51,7 +51,7 @@ abstract class FormAction extends Action {
 
        /**
         * Play with the HTMLForm if you need to more substantially
-        * @param $form HTMLForm
+        * @param HTMLForm $form
         */
        protected function alterForm( HTMLForm $form ) {
        }
@@ -91,8 +91,8 @@ abstract class FormAction extends Action {
         * Process the form on POST submission.  If you return false from getFormFields(),
         * this will obviously never be reached.  If you don't want to do anything with the
         * form, just return false here
-        * @param $data Array
-        * @return Bool|Array true for success, false for didn't-try, array of errors on failure
+        * @param array $data
+        * @return bool|array True for success, false for didn't-try, array of errors on failure
         */
        abstract public function onSubmit( $data );
 
@@ -125,8 +125,8 @@ abstract class FormAction extends Action {
        /**
         * @see Action::execute()
         *
-        * @param $data array|null
-        * @param $captureErrors bool
+        * @param array|null $data
+        * @param bool $captureErrors
         * @throws ErrorPageError|Exception
         * @return bool
         */
index 6cab4d1..0039838 100644 (file)
@@ -30,7 +30,7 @@ abstract class FormlessAction extends Action {
 
        /**
         * Show something on GET request.
-        * @return String|null will be added to the HTMLForm if present, or just added to the
+        * @return string|null Will be added to the HTMLForm if present, or just added to the
         *     output if not.  Return null to not add anything
         */
        abstract public function onView();
@@ -44,7 +44,7 @@ abstract class FormlessAction extends Action {
        }
 
        /**
-        * @param $data Array
+        * @param array $data
         * @return bool
         */
        public function onSubmit( $data ) {
@@ -70,10 +70,10 @@ abstract class FormlessAction extends Action {
        /**
         * Execute the action silently, not giving any output.  Since these actions don't have
         * forms, they probably won't have any data, but some (eg rollback) may do
-        * @param array $data values that would normally be in the GET request
-        * @param bool $captureErrors whether to catch exceptions and just return false
+        * @param array $data Values that would normally be in the GET request
+        * @param bool $captureErrors Whether to catch exceptions and just return false
         * @throws ErrorPageError|Exception
-        * @return Bool whether execution was successful
+        * @return bool Whether execution was successful
         */
        public function execute( array $data = null, $captureErrors = true ) {
                try {
index 8e800f9..f1e3c26 100644 (file)
@@ -212,9 +212,9 @@ class HistoryAction extends FormlessAction {
         * direction. This is now only used by the feeds. It was previously
         * used by the main UI but that's now handled by the pager.
         *
-        * @param $limit Integer: the limit number of revisions to get
-        * @param $offset Integer
-        * @param $direction Integer: either HistoryPage::DIR_PREV or HistoryPage::DIR_NEXT
+        * @param int $limit The limit number of revisions to get
+        * @param int $offset
+        * @param int $direction Either HistoryPage::DIR_PREV or HistoryPage::DIR_NEXT
         * @return ResultWrapper
         */
        function fetchRevisions( $limit, $offset, $direction ) {
@@ -303,7 +303,7 @@ class HistoryAction extends FormlessAction {
         * Borrows Recent Changes' feed generation functions for formatting;
         * includes a diff to the previous revision (if any).
         *
-        * @param $row Object: database row
+        * @param stdClass|array $row database row
         * @return FeedItem
         */
        function feedItem( $row ) {
@@ -541,9 +541,9 @@ class HistoryPager extends ReverseChronologicalPager {
        /**
         * Creates a submit button
         *
-        * @param string $message text of the submit button, will be escaped
-        * @param array $attributes attributes
-        * @return String: HTML output for the submit button
+        * @param string $message Text of the submit button, will be escaped
+        * @param array $attributes Attributes
+        * @return string HTML output for the submit button
         */
        function submitButton( $message, $attributes = array() ) {
                # Disable submit button if history has 1 revision only
@@ -726,8 +726,8 @@ class HistoryPager extends ReverseChronologicalPager {
        /**
         * Create a link to view this revision of the page
         *
-        * @param $rev Revision
-        * @return String
+        * @param Revision $rev
+        * @return string
         */
        function revLink( $rev ) {
                $date = $this->getLanguage()->userTimeAndDate( $rev->getTimestamp(), $this->getUser() );
@@ -752,9 +752,9 @@ class HistoryPager extends ReverseChronologicalPager {
        /**
         * Create a diff-to-current link for this revision for this page
         *
-        * @param $rev Revision
-        * @param $latest Boolean: this is the latest revision of the page?
-        * @return String
+        * @param Revision $rev
+        * @param bool $latest This is the latest revision of the page?
+        * @return string
         */
        function curLink( $rev, $latest ) {
                $cur = $this->historyPage->message['cur'];
@@ -776,9 +776,9 @@ class HistoryPager extends ReverseChronologicalPager {
        /**
         * Create a diff-to-previous link for this revision for this page.
         *
-        * @param $prevRev Revision: the previous revision
-        * @param $next Mixed: the newer revision
-        * @return String
+        * @param Revision $prevRev The previous revision
+        * @param mixed $next The newer revision
+        * @return string
         */
        function lastLink( $prevRev, $next ) {
                $last = $this->historyPage->message['last'];
@@ -818,10 +818,10 @@ class HistoryPager extends ReverseChronologicalPager {
        /**
         * Create radio buttons for page history
         *
-        * @param $rev Revision object
-        * @param $firstInList Boolean: is this version the first one?
+        * @param Revision $rev
+        * @param bool $firstInList Is this version the first one?
         *
-        * @return String: HTML output for the radio buttons
+        * @return string HTML output for the radio buttons
         */
        function diffButtons( $rev, $firstInList ) {
                if ( $this->getNumRows() > 1 ) {
index 63f3151..06e3667 100644 (file)
@@ -33,7 +33,7 @@ class InfoAction extends FormlessAction {
        /**
         * Returns the name of the action this object responds to.
         *
-        * @return string lowercase
+        * @return string Lowercase name
         */
        public function getName() {
                return 'info';
@@ -763,7 +763,7 @@ class InfoAction extends FormlessAction {
 
        /**
         * Get a list of contributors of $article
-        * @return string: html
+        * @return string Html
         */
        protected function getContributors() {
                global $wgHiddenPrefs;
index b753407..1b72662 100644 (file)
@@ -125,7 +125,7 @@ class RawAction extends FormlessAction {
         * Get the text that should be returned, or false if the page or revision
         * was not found.
         *
-        * @return String|Bool
+        * @return string|bool
         */
        public function getRawText() {
                global $wgParser;
@@ -198,7 +198,7 @@ class RawAction extends FormlessAction {
        /**
         * Get the ID of the revision that should used to get the text.
         *
-        * @return Integer
+        * @return int
         */
        public function getOldId() {
                $oldid = $this->getRequest()->getInt( 'oldid' );
@@ -230,7 +230,7 @@ class RawAction extends FormlessAction {
        /**
         * Get the content type to use for the response
         *
-        * @return String
+        * @return string
         */
        public function getContentType() {
                $ctype = $this->getRequest()->getVal( 'ctype' );
index 9062ad9..a2641ee 100644 (file)
@@ -52,6 +52,12 @@ class ApiFeedRecentChanges extends ApiBase {
                        $this->dieUsage( 'Invalid subscription feed type', 'feed-invalid' );
                }
 
+               $this->getMain()->setCacheMode( 'public' );
+               if ( !$this->getMain()->getParameter( 'smaxage' ) ) {
+                       // bug 63249: This page gets hit a lot, cache at least 15 seconds.
+                       $this->getMain()->setCacheMaxAge( 15 );
+               }
+
                $feedFormat = $this->params['feedformat'];
                $specialClass = $this->params['target'] !== null
                        ? 'SpecialRecentchangeslinked'
index 6e2c31f..229c07e 100644 (file)
@@ -168,6 +168,20 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                                $params['start'],
                                $params['end']
                        );
+                       // Include in ORDER BY for uniqueness
+                       $this->addWhereRange( 'img_name', $ascendingOrder ? 'newer' : 'older', null, null );
+
+                       if ( !is_null( $params['continue'] ) ) {
+                               $cont = explode( '|', $params['continue'] );
+                               $this->dieContinueUsageIf( count( $cont ) != 2 );
+                               $op = ( $ascendingOrder ? '>' : '<' );
+                               $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
+                               $continueName = $db->addQuotes( $cont[1] );
+                               $this->addWhere( "img_timestamp $op $continueTimestamp OR " .
+                                       "(img_timestamp = $continueTimestamp AND " .
+                                       "img_name $op= $continueName)"
+                               );
+                       }
 
                        // Image filters
                        if ( !is_null( $params['user'] ) ) {
@@ -254,7 +268,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                                if ( $params['sort'] == 'name' ) {
                                        $this->setContinueEnumParameter( 'continue', $row->img_name );
                                } else {
-                                       $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->img_timestamp ) );
+                                       $this->setContinueEnumParameter( 'continue', "$row->img_timestamp|$row->img_name" );
                                }
                                break;
                        }
@@ -270,7 +284,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                                        if ( $params['sort'] == 'name' ) {
                                                $this->setContinueEnumParameter( 'continue', $row->img_name );
                                        } else {
-                                               $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->img_timestamp ) );
+                                               $this->setContinueEnumParameter( 'continue', "$row->img_timestamp|$row->img_name" );
                                        }
                                        break;
                                }
index 6cc0183..cfca140 100644 (file)
@@ -43,6 +43,7 @@ class ApiQueryBlocks extends ApiQueryBase {
        public function execute() {
                global $wgContLang;
 
+               $db = $this->getDB();
                $params = $this->extractRequestParams();
                $this->requireMaxOneParameter( $params, 'users', 'ip' );
 
@@ -61,9 +62,8 @@ class ApiQueryBlocks extends ApiQueryBase {
                $result = $this->getResult();
 
                $this->addTables( 'ipblocks' );
-               $this->addFields( 'ipb_auto' );
+               $this->addFields( array( 'ipb_auto', 'ipb_id' ) );
 
-               $this->addFieldsIf( 'ipb_id', $fld_id );
                $this->addFieldsIf( array( 'ipb_address', 'ipb_user' ), $fld_user || $fld_userid );
                $this->addFieldsIf( 'ipb_by_text', $fld_by );
                $this->addFieldsIf( 'ipb_by', $fld_byid );
@@ -82,8 +82,21 @@ class ApiQueryBlocks extends ApiQueryBase {
                        $params['start'],
                        $params['end']
                );
-
-               $db = $this->getDB();
+               // Include in ORDER BY for uniqueness
+               $this->addWhereRange( 'ipb_id', $params['dir'], null, null );
+
+               if ( !is_null( $params['continue'] ) ) {
+                       $cont = explode( '|', $params['continue'] );
+                       $this->dieContinueUsageIf( count( $cont ) != 2 );
+                       $op = ( $params['dir'] == 'newer' ? '>' : '<' );
+                       $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
+                       $continueId = (int)$cont[1];
+                       $this->dieContinueUsageIf( $continueId != $cont[1] );
+                       $this->addWhere( "ipb_timestamp $op $continueTimestamp OR " .
+                               "(ipb_timestamp = $continueTimestamp AND " .
+                               "ipb_id $op= $continueId)"
+                       );
+               }
 
                if ( isset( $params['ids'] ) ) {
                        $this->addWhereFld( 'ipb_id', $params['ids'] );
@@ -176,7 +189,7 @@ class ApiQueryBlocks extends ApiQueryBase {
                foreach ( $res as $row ) {
                        if ( ++$count > $params['limit'] ) {
                                // We've had enough
-                               $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ipb_timestamp ) );
+                               $this->setContinueEnumParameter( 'continue', "$row->ipb_timestamp|$row->ipb_id" );
                                break;
                        }
                        $block = array();
@@ -234,7 +247,7 @@ class ApiQueryBlocks extends ApiQueryBase {
                        }
                        $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $block );
                        if ( !$fit ) {
-                               $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ipb_timestamp ) );
+                               $this->setContinueEnumParameter( 'continue', "$row->ipb_timestamp|$row->ipb_id" );
                                break;
                        }
                }
@@ -313,6 +326,7 @@ class ApiQueryBlocks extends ApiQueryBase {
                                ),
                                ApiBase::PARAM_ISMULTI => true
                        ),
+                       'continue' => null,
                );
        }
 
@@ -350,6 +364,7 @@ class ApiQueryBlocks extends ApiQueryBase {
                                'Show only items that meet this criteria.',
                                "For example, to see only indefinite blocks on IPs, set {$p}show=ip|!temp"
                        ),
+                       'continue' => 'When more results are available, use this to continue',
                );
        }
 
index 4e942d6..424770f 100644 (file)
@@ -101,6 +101,22 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
                                $dir,
                                $params['start'],
                                $params['end'] );
+                       // Include in ORDER BY for uniqueness
+                       $this->addWhereRange( 'cl_from', $dir, null, null );
+
+                       if ( !is_null( $params['continue'] ) ) {
+                               $cont = explode( '|', $params['continue'] );
+                               $this->dieContinueUsageIf( count( $cont ) != 2 );
+                               $op = ( $dir === 'newer' ? '>' : '<' );
+                               $db = $this->getDB();
+                               $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
+                               $continueFrom = (int)$cont[1];
+                               $this->dieContinueUsageIf( $continueFrom != $cont[1] );
+                               $this->addWhere( "cl_timestamp $op $continueTimestamp OR " .
+                                       "(cl_timestamp = $continueTimestamp AND " .
+                                       "cl_from $op= $continueFrom)"
+                               );
+                       }
 
                        $this->addOption( 'USE INDEX', 'cl_timestamp' );
                } else {
@@ -186,7 +202,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
                                // @todo Security issue - if the user has no right to view next
                                // title, it will still be shown
                                if ( $params['sort'] == 'timestamp' ) {
-                                       $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) );
+                                       $this->setContinueEnumParameter( 'continue', "$row->cl_timestamp|$row->cl_from" );
                                } else {
                                        $sortkey = bin2hex( $row->cl_sortkey );
                                        $this->setContinueEnumParameter( 'continue',
@@ -229,7 +245,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
                                        null, $vals );
                                if ( !$fit ) {
                                        if ( $params['sort'] == 'timestamp' ) {
-                                               $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->cl_timestamp ) );
+                                               $this->setContinueEnumParameter( 'continue', "$row->cl_timestamp|$row->cl_from" );
                                        } else {
                                                $sortkey = bin2hex( $row->cl_sortkey );
                                                $this->setContinueEnumParameter( 'continue',
index 58db035..2ca93f5 100644 (file)
@@ -106,7 +106,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                }
 
                $this->addTables( 'archive' );
-               $this->addFields( array( 'ar_title', 'ar_namespace', 'ar_timestamp', 'ar_deleted' ) );
+               $this->addFields( array( 'ar_title', 'ar_namespace', 'ar_timestamp', 'ar_deleted', 'ar_id' ) );
 
                $this->addFieldsIf( 'ar_parent_id', $fld_parentid );
                $this->addFieldsIf( 'ar_rev_id', $fld_revid );
@@ -214,19 +214,33 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        }
                }
 
-               if ( !is_null( $params['continue'] ) && ( $mode == 'all' || $mode == 'revs' ) ) {
+               if ( !is_null( $params['continue'] ) ) {
                        $cont = explode( '|', $params['continue'] );
-                       $this->dieContinueUsageIf( count( $cont ) != 3 );
-                       $ns = intval( $cont[0] );
-                       $this->dieContinueUsageIf( strval( $ns ) !== $cont[0] );
-                       $title = $db->addQuotes( $cont[1] );
-                       $ts = $db->addQuotes( $db->timestamp( $cont[2] ) );
                        $op = ( $dir == 'newer' ? '>' : '<' );
-                       $this->addWhere( "ar_namespace $op $ns OR " .
-                               "(ar_namespace = $ns AND " .
-                               "(ar_title $op $title OR " .
-                               "(ar_title = $title AND " .
-                               "ar_timestamp $op= $ts)))" );
+                       if ( $mode == 'all' || $mode == 'revs' ) {
+                               $this->dieContinueUsageIf( count( $cont ) != 4 );
+                               $ns = intval( $cont[0] );
+                               $this->dieContinueUsageIf( strval( $ns ) !== $cont[0] );
+                               $title = $db->addQuotes( $cont[1] );
+                               $ts = $db->addQuotes( $db->timestamp( $cont[2] ) );
+                               $ar_id = (int)$cont[3];
+                               $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[3] );
+                               $this->addWhere( "ar_namespace $op $ns OR " .
+                                       "(ar_namespace = $ns AND " .
+                                       "(ar_title $op $title OR " .
+                                       "(ar_title = $title AND " .
+                                       "(ar_timestamp $op $ts OR " .
+                                       "(ar_timestamp = $ts AND " .
+                                       "ar_id $op= $ar_id)))))" );
+                       } else {
+                               $this->dieContinueUsageIf( count( $cont ) != 2 );
+                               $ts = $db->addQuotes( $db->timestamp( $cont[0] ) );
+                               $ar_id = (int)$cont[1];
+                               $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[1] );
+                               $this->addWhere( "ar_timestamp $op $ts OR " .
+                                       "(ar_timestamp = $ts AND " .
+                                       "ar_id $op= $ar_id)" );
+                       }
                }
 
                $this->addOption( 'LIMIT', $limit + 1 );
@@ -236,12 +250,14 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                );
                if ( $mode == 'all' ) {
                        if ( $params['unique'] ) {
+                               // @todo Does this work on non-MySQL?
                                $this->addOption( 'GROUP BY', 'ar_title' );
                        } else {
                                $sort = ( $dir == 'newer' ? '' : ' DESC' );
                                $this->addOption( 'ORDER BY', array(
                                        'ar_title' . $sort,
-                                       'ar_timestamp' . $sort
+                                       'ar_timestamp' . $sort,
+                                       'ar_id' . $sort,
                                ) );
                        }
                } else {
@@ -251,6 +267,8 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                $this->addWhereRange( 'ar_title', $dir, null, null );
                        }
                        $this->addTimestampWhereRange( 'ar_timestamp', $dir, $params['start'], $params['end'] );
+                       // Include in ORDER BY for uniqueness
+                       $this->addWhereRange( 'ar_id', $dir, null, null );
                }
                $res = $this->select( __METHOD__ );
                $pageMap = array(); // Maps ns&title to (fake) pageid
@@ -260,10 +278,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        if ( ++$count > $limit ) {
                                // We've had enough
                                if ( $mode == 'all' || $mode == 'revs' ) {
-                                       $this->setContinueEnumParameter( 'continue', intval( $row->ar_namespace ) . '|' .
-                                               $row->ar_title . '|' . $row->ar_timestamp );
+                                       $this->setContinueEnumParameter( 'continue',
+                                               "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
+                                       );
                                } else {
-                                       $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ar_timestamp ) );
+                                       $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" );
                                }
                                break;
                        }
@@ -371,10 +390,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        }
                        if ( !$fit ) {
                                if ( $mode == 'all' || $mode == 'revs' ) {
-                                       $this->setContinueEnumParameter( 'continue', intval( $row->ar_namespace ) . '|' .
-                                               $row->ar_title . '|' . $row->ar_timestamp );
+                                       $this->setContinueEnumParameter( 'continue',
+                                               "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
+                                       );
                                } else {
-                                       $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ar_timestamp ) );
+                                       $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" );
                                }
                                break;
                        }
@@ -468,7 +488,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        'namespace' => 'Only list pages in this namespace (3)',
                        'user' => 'Only list revisions by this user',
                        'excludeuser' => 'Don\'t list revisions by this user',
-                       'continue' => 'When more results are available, use this to continue (1, 3)',
+                       'continue' => 'When more results are available, use this to continue',
                        'unique' => 'List only one revision for each page (3)',
                        'tag' => 'Only list revisions tagged with this tag',
                );
index b607ca5..ee7fbc0 100644 (file)
@@ -73,13 +73,14 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                        'log_title=page_title' ) ) ) );
 
                $this->addFields( array(
+                       'log_id',
                        'log_type',
                        'log_action',
                        'log_timestamp',
                        'log_deleted',
                ) );
 
-               $this->addFieldsIf( array( 'log_id', 'page_id' ), $this->fld_ids );
+               $this->addFieldsIf( 'page_id', $this->fld_ids );
                $this->addFieldsIf( array( 'log_user', 'log_user_text', 'user_name' ), $this->fld_user );
                $this->addFieldsIf( 'log_user', $this->fld_userid );
                $this->addFieldsIf(
@@ -135,6 +136,21 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        $params['start'],
                        $params['end']
                );
+               // Include in ORDER BY for uniqueness
+               $this->addWhereRange( 'log_id', $params['dir'], null, null );
+
+               if ( !is_null( $params['continue'] ) ) {
+                       $cont = explode( '|', $params['continue'] );
+                       $this->dieContinueUsageIf( count( $cont ) != 2 );
+                       $op = ( $params['dir'] === 'newer' ? '>' : '<' );
+                       $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
+                       $continueId = (int)$cont[1];
+                       $this->dieContinueUsageIf( $continueId != $cont[1] );
+                       $this->addWhere( "log_timestamp $op $continueTimestamp OR " .
+                               "(log_timestamp = $continueTimestamp AND " .
+                               "log_id $op= $continueId)"
+                       );
+               }
 
                $limit = $params['limit'];
                $this->addOption( 'LIMIT', $limit + 1 );
@@ -202,7 +218,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        if ( ++$count > $limit ) {
                                // We've reached the one extra which shows that there are
                                // additional pages to be had. Stop here...
-                               $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->log_timestamp ) );
+                               $this->setContinueEnumParameter( 'continue', "$row->log_timestamp|$row->log_id" );
                                break;
                        }
 
@@ -212,7 +228,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        }
                        $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
                        if ( !$fit ) {
-                               $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->log_timestamp ) );
+                               $this->setContinueEnumParameter( 'continue', "$row->log_timestamp|$row->log_id" );
                                break;
                        }
                }
@@ -497,7 +513,8 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                ApiBase::PARAM_MIN => 1,
                                ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
                                ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
-                       )
+                       ),
+                       'continue' => null,
                );
        }
 
@@ -531,6 +548,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        'prefix' => 'Filter entries that start with this prefix. Disabled in Miser Mode',
                        'limit' => 'How many total event entries to return',
                        'tag' => 'Only list event entries tagged with this tag',
+                       'continue' => 'When more results are available, use this to continue',
                );
        }
 
index 9cdd6b9..6cf7ff3 100644 (file)
@@ -63,6 +63,27 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
                $this->addWhereFld( 'pt_namespace', $params['namespace'] );
                $this->addWhereFld( 'pt_create_perm', $params['level'] );
 
+               // Include in ORDER BY for uniqueness
+               $this->addWhereRange( 'pt_namespace', $params['dir'], null, null );
+               $this->addWhereRange( 'pt_title', $params['dir'], null, null );
+
+               if ( !is_null( $params['continue'] ) ) {
+                       $cont = explode( '|', $params['continue'] );
+                       $this->dieContinueUsageIf( count( $cont ) != 3 );
+                       $op = ( $params['dir'] === 'newer' ? '>' : '<' );
+                       $db = $this->getDB();
+                       $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
+                       $continueNs = (int)$cont[1];
+                       $this->dieContinueUsageIf( $continueNs != $cont[1] );
+                       $continueTitle = $db->addQuotes( $cont[2] );
+                       $this->addWhere( "pt_timestamp $op $continueTimestamp OR " .
+                               "(pt_timestamp = $continueTimestamp AND " .
+                               "(pt_namespace $op $continueNs OR " .
+                               "(pt_namespace = $continueNs AND " .
+                               "pt_title $op= $continueTitle)))"
+                       );
+               }
+
                if ( isset( $prop['user'] ) ) {
                        $this->addTables( 'user' );
                        $this->addFields( 'user_name' );
@@ -83,7 +104,9 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
                        if ( ++$count > $params['limit'] ) {
                                // We've reached the one extra which shows that there are
                                // additional pages to be had. Stop here...
-                               $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->pt_timestamp ) );
+                               $this->setContinueEnumParameter( 'continue',
+                                       "$row->pt_timestamp|$row->pt_namespace|$row->pt_title"
+                               );
                                break;
                        }
 
@@ -122,8 +145,9 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
 
                                $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
                                if ( !$fit ) {
-                                       $this->setContinueEnumParameter( 'start',
-                                               wfTimestamp( TS_ISO_8601, $row->pt_timestamp ) );
+                                       $this->setContinueEnumParameter( 'continue',
+                                               "$row->pt_timestamp|$row->pt_namespace|$row->pt_title"
+                                       );
                                        break;
                                }
                        } else {
@@ -195,6 +219,7 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
                                        'level'
                                )
                        ),
+                       'continue' => null,
                );
        }
 
@@ -216,6 +241,7 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
                                ' level          - Adds the protection level',
                        ),
                        'level' => 'Only list titles with these protection levels',
+                       'continue' => 'When more results are available, use this to continue',
                );
        }
 
index 79a8dc9..80352f2 100644 (file)
@@ -152,15 +152,12 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                if ( !is_null( $params['continue'] ) ) {
                        $cont = explode( '|', $params['continue'] );
-                       if ( count( $cont ) != 2 ) {
-                               $this->dieUsage( 'Invalid continue param. You should pass the ' .
-                                       'original value returned by the previous query', '_badcontinue' );
-                       }
-
-                       $timestamp = $this->getDB()->addQuotes( wfTimestamp( TS_MW, $cont[0] ) );
+                       $this->dieContinueUsageIf( count( $cont ) != 2 );
+                       $db = $this->getDB();
+                       $timestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
                        $id = intval( $cont[1] );
+                       $this->dieContinueUsageIf( $id != $cont[1] );
                        $op = $params['dir'] === 'older' ? '<' : '>';
-
                        $this->addWhere(
                                "rc_timestamp $op $timestamp OR " .
                                "(rc_timestamp = $timestamp AND " .
@@ -254,6 +251,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Add the fields we're concerned with to our query. */
                $this->addFields( array(
+                       'rc_id',
                        'rc_timestamp',
                        'rc_namespace',
                        'rc_title',
@@ -277,7 +275,6 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                );
                        }
 
-                       $this->addFields( 'rc_id' );
                        /* Add fields to our query if they are specified as a needed parameter. */
                        $this->addFieldsIf( array( 'rc_this_oldid', 'rc_last_oldid' ), $this->fld_ids );
                        $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
@@ -371,10 +368,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        if ( ++$count > $params['limit'] ) {
                                // We've reached the one extra which shows that there are
                                // additional pages to be had. Stop here...
-                               $this->setContinueEnumParameter(
-                                       'continue',
-                                       wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) . '|' . $row->rc_id
-                               );
+                               $this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" );
                                break;
                        }
 
@@ -388,10 +382,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                }
                                $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
                                if ( !$fit ) {
-                                       $this->setContinueEnumParameter(
-                                               'continue',
-                                               wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) . '|' . $row->rc_id
-                                       );
+                                       $this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" );
                                        break;
                                }
                        } else {
index 1cd8d98..b7796ee 100644 (file)
@@ -656,12 +656,12 @@ class ApiQuerySiteinfo extends ApiQueryBase {
 
        public function appendSkins( $property ) {
                $data = array();
-               $usable = Skin::getUsableSkins();
+               $allowed = Skin::getAllowedSkins();
                $default = Skin::normalizeKey( 'default' );
                foreach ( Skin::getSkinNames() as $name => $displayName ) {
                        $skin = array( 'code' => $name );
                        ApiResult::setContent( $skin, $displayName );
-                       if ( !isset( $usable[$name] ) ) {
+                       if ( !isset( $allowed[$name] ) ) {
                                $skin['unusable'] = '';
                        }
                        if ( $name === $default ) {
index b58a951..e9fec43 100644 (file)
@@ -108,22 +108,14 @@ class ApiQueryContributions extends ApiQueryBase {
                        if ( ++$count > $limit ) {
                                // We've reached the one extra which shows that there are
                                // additional pages to be had. Stop here...
-                               if ( $this->multiUserMode ) {
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                               } else {
-                                       $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rev_timestamp ) );
-                               }
+                               $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
                                break;
                        }
 
                        $vals = $this->extractRowInfo( $row );
                        $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ), null, $vals );
                        if ( !$fit ) {
-                               if ( $this->multiUserMode ) {
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                               } else {
-                                       $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->rev_timestamp ) );
-                               }
+                               $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
                                break;
                        }
                }
@@ -167,18 +159,34 @@ class ApiQueryContributions extends ApiQueryBase {
                $this->addWhere( 'page_id=rev_page' );
 
                // Handle continue parameter
-               if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
+               if ( !is_null( $this->params['continue'] ) ) {
                        $continue = explode( '|', $this->params['continue'] );
-                       $this->dieContinueUsageIf( count( $continue ) != 2 );
                        $db = $this->getDB();
-                       $encUser = $db->addQuotes( $continue[0] );
-                       $encTS = $db->addQuotes( $db->timestamp( $continue[1] ) );
+                       if ( $this->multiUserMode ) {
+                               $this->dieContinueUsageIf( count( $continue ) != 3 );
+                               $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' ? '<' : '>' );
-                       $this->addWhere(
-                               "rev_user_text $op $encUser OR " .
-                               "(rev_user_text = $encUser AND " .
-                               "rev_timestamp $op= $encTS)"
-                       );
+                       if ( $this->multiUserMode ) {
+                               $this->addWhere(
+                                       "rev_user_text $op $encUser OR " .
+                                       "(rev_user_text = $encUser AND " .
+                                       "(rev_timestamp $op $encTS OR " .
+                                       "(rev_timestamp = $encTS AND " .
+                                       "rev_id $op= $encId)))"
+                               );
+                       } else {
+                               $this->addWhere(
+                                       "rev_timestamp $op $encTS OR " .
+                                       "(rev_timestamp = $encTS AND " .
+                                       "rev_id $op= $encId)"
+                               );
+                       }
                }
 
                // Don't include any revisions where we're not supposed to be able to
@@ -209,6 +217,9 @@ class ApiQueryContributions extends ApiQueryBase {
                }
                $this->addTimestampWhereRange( 'rev_timestamp',
                        $this->params['dir'], $this->params['start'], $this->params['end'] );
+               // Include in ORDER BY for uniqueness
+               $this->addWhereRange( 'rev_id', $this->params['dir'], null, null );
+
                $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
 
                $show = $this->params['show'];
@@ -242,6 +253,7 @@ class ApiQueryContributions extends ApiQueryBase {
                // ns+title checks if the user has access rights for this page
                // user_text is necessary if multiple users were specified
                $this->addFields( array(
+                       'rev_id',
                        'rev_timestamp',
                        'page_namespace',
                        'page_title',
@@ -284,7 +296,6 @@ class ApiQueryContributions extends ApiQueryBase {
 
                $this->addTables( $tables );
                $this->addFieldsIf( 'rev_page', $this->fld_ids );
-               $this->addFieldsIf( 'rev_id', $this->fld_ids || $this->fld_flags );
                $this->addFieldsIf( 'page_latest', $this->fld_flags );
                // $this->addFieldsIf( 'rev_text_id', $this->fld_ids ); // Should this field be exposed?
                $this->addFieldsIf( 'rev_comment', $this->fld_comment || $this->fld_parsedcomment );
@@ -424,8 +435,11 @@ class ApiQueryContributions extends ApiQueryBase {
        }
 
        private function continueStr( $row ) {
-               return $row->rev_user_text . '|' .
-                       wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
+               if ( $this->multiUserMode ) {
+                       return "$row->rev_user_text|$row->rev_timestamp|$row->rev_id";
+               } else {
+                       return "$row->rev_timestamp|$row->rev_id";
+               }
        }
 
        public function getCacheMode( $params ) {
index 6baa87d..2e1ce6c 100644 (file)
@@ -86,6 +86,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                }
 
                $this->addFields( array(
+                       'rc_id',
                        'rc_namespace',
                        'rc_title',
                        'rc_timestamp',
@@ -135,6 +136,22 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
                $this->addTimestampWhereRange( 'rc_timestamp', $params['dir'],
                        $params['start'], $params['end'] );
+               // Include in ORDER BY for uniqueness
+               $this->addWhereRange( 'rc_id', $params['dir'], null, null );
+
+               if ( !is_null( $params['continue'] ) ) {
+                       $cont = explode( '|', $params['continue'] );
+                       $this->dieContinueUsageIf( count( $cont ) != 2 );
+                       $op = ( $params['dir'] === 'newer' ? '>' : '<' );
+                       $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
+                       $continueId = (int)$cont[1];
+                       $this->dieContinueUsageIf( $continueId != $cont[1] );
+                       $this->addWhere( "rc_timestamp $op $continueTimestamp OR " .
+                               "(rc_timestamp = $continueTimestamp AND " .
+                               "rc_id $op= $continueId)"
+                       );
+               }
+
                $this->addWhereFld( 'wl_namespace', $params['namespace'] );
 
                if ( !$params['allrev'] ) {
@@ -236,10 +253,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        if ( ++$count > $params['limit'] ) {
                                // We've reached the one extra which shows that there are
                                // additional pages to be had. Stop here...
-                               $this->setContinueEnumParameter(
-                                       'start',
-                                       wfTimestamp( TS_ISO_8601, $row->rc_timestamp )
-                               );
+                               $this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" );
                                break;
                        }
 
@@ -247,8 +261,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                                $vals = $this->extractRowInfo( $row );
                                $fit = $this->getResult()->addValue( array( 'query', $this->getModuleName() ), null, $vals );
                                if ( !$fit ) {
-                                       $this->setContinueEnumParameter( 'start',
-                                               wfTimestamp( TS_ISO_8601, $row->rc_timestamp ) );
+                                       $this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" );
                                        break;
                                }
                        } else {
@@ -544,6 +557,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        'token' => array(
                                ApiBase::PARAM_TYPE => 'string'
                        ),
+                       'continue' => null,
                );
        }
 
@@ -588,6 +602,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        'owner' => 'The name of the user whose watchlist you\'d like to access',
                        'token' => 'Give a security token (settable in preferences) to ' .
                                'allow access to another user\'s watchlist',
+                       'continue' => 'When more results are available, use this to continue',
                );
        }
 
index 68a7f46..c21b113 100644 (file)
@@ -48,7 +48,7 @@ class RedisConnectionPool {
        protected $password;
        /** @var bool Whether connections persist */
        protected $persistent;
-       /** @var integer Serializer to use (Redis::SERIALIZER_*) */
+       /** @var int Serializer to use (Redis::SERIALIZER_*) */
        protected $serializer;
        /** @} */
 
@@ -408,7 +408,7 @@ class RedisConnRef {
        /**
         * @param string $script
         * @param array $params
-        * @param integer $numKeys
+        * @param int $numKeys
         * @return mixed
         * @throws RedisException
         */
index e9c6ac0..18110ef 100644 (file)
@@ -98,7 +98,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return String The model id
+        * @return string The model id
         */
        public function getModel();
 
@@ -122,7 +122,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return String
+        * @return string
         */
        public function getDefaultFormat();
 
@@ -232,7 +232,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return Content. A copy of this object
+        * @return Content A copy of this object
         */
        public function copy();
 
index 2a0fde3..3909faa 100644 (file)
@@ -29,7 +29,7 @@
  */
 abstract class DBAccessBase implements IDBAccessObject {
        /**
-        * @var String|bool $wiki The target wiki's name. This must be an ID
+        * @var string|bool $wiki The target wiki's name. This must be an ID
         * that LBFactory can understand.
         */
        protected $wiki = false;
@@ -68,7 +68,7 @@ abstract class DBAccessBase implements IDBAccessObject {
         *
         * @since 1.21
         *
-        * @param DatabaseBase $db the database connection to release.
+        * @param DatabaseBase $db The database connection to release.
         */
        protected function releaseConnection( DatabaseBase $db ) {
                if ( $this->wiki !== false ) {
index 52a3298..9254bb4 100644 (file)
@@ -630,8 +630,8 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
        public function setFlag( $flag ) {
                global $wgDebugDBTransactions;
                $this->mFlags |= $flag;
-               if ( ( $flag & DBO_TRX ) & $wgDebugDBTransactions ) {
-                       wfDebug( "Implicit transactions are now disabled.\n" );
+               if ( ( $flag & DBO_TRX ) && $wgDebugDBTransactions ) {
+                       wfDebug( "Implicit transactions are now enabled.\n" );
                }
        }
 
index 716ab6e..c759725 100644 (file)
@@ -1196,8 +1196,7 @@ abstract class FileBackend {
         *
         * @param array $paths Storage paths
         */
-       public function preloadCache( array $paths ) {
-       }
+       abstract public function preloadCache( array $paths );
 
        /**
         * Invalidate any in-process file stat and property cache.
@@ -1207,8 +1206,7 @@ abstract class FileBackend {
         *
         * @param array $paths Storage paths (optional)
         */
-       public function clearCache( array $paths = null ) {
-       }
+       abstract public function clearCache( array $paths = null );
 
        /**
         * Preload file stat information (concurrently if possible) into in-process cache.
index f00ef65..c39bbaf 100644 (file)
@@ -662,8 +662,14 @@ class FileBackendMultiWrite extends FileBackend {
                }
        }
 
+       public function preloadCache( array $paths ) {
+               $realPaths = $this->substPaths( $paths, $this->backends[$this->masterIndex] );
+               $this->backends[$this->masterIndex]->preloadCache( $realPaths );
+       }
+
        public function preloadFileStat( array $params ) {
-               $this->backends[$this->masterIndex]->preloadFileStat( $params );
+               $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+               $this->backends[$this->masterIndex]->preloadFileStat( $realParams );
        }
 
        public function getScopedLocksForOps( array $ops, Status $status ) {
index edf574f..21ff65c 100644 (file)
@@ -842,6 +842,8 @@ abstract class File {
                        return $this->iconThumb();
                }
                $hp['width'] = $width;
+               // be sure to ignore any height specification as well (bug 62258)
+               unset( $hp['height'] );
 
                return $this->transform( $hp );
        }
index b658ac1..8b30e9b 100644 (file)
@@ -48,13 +48,14 @@ class DeleteLogFormatter extends LogFormatter {
                $params = parent::getMessageParameters();
                $subtype = $this->entry->getSubtype();
                if ( in_array( $subtype, array( 'event', 'revision' ) ) ) {
-                       // $params[3] here is 'revision' for page revisions, 'oldimage' for
-                       // file versions, or a comma-separated list of log_ids for log
+                       // $params[3] here is 'revision' or 'archive' for page revisions, 'oldimage' or
+                       // 'filearchive' for file versions, or a comma-separated list of log_ids for log
                        // entries. $subtype here is 'revision' for page revisions and file
                        // versions, or 'event' for log entries.
                        if ( ( $subtype === 'event' && count( $params ) === 6 )
                                || ( $subtype === 'revision' && isset( $params[3] )
-                                       && ( $params[3] === 'revision' || $params[3] === 'oldimage' )
+                                       && ( $params[3] === 'revision' || $params[3] === 'oldimage'
+                                               || $params[3] === 'archive' || $params[3] === 'filearchive' )
                                )
                        ) {
                                $paramStart = $subtype === 'revision' ? 4 : 3;
@@ -63,9 +64,11 @@ class DeleteLogFormatter extends LogFormatter {
                                $new = $this->parseBitField( $params[$paramStart + 2] );
                                list( $hid, $unhid, $extra ) = RevisionDeleter::getChanges( $new, $old );
                                $changes = array();
+                               // messages used: revdelete-content-hid, revdelete-summary-hid, revdelete-uname-hid
                                foreach ( $hid as $v ) {
                                        $changes[] = $this->msg( "$v-hid" )->plain();
                                }
+                               // messages used: revdelete-content-unhid, revdelete-summary-unhid, revdelete-uname-unhid
                                foreach ( $unhid as $v ) {
                                        $changes[] = $this->msg( "$v-unhid" )->plain();
                                }
index 1202c9a..2aeb35d 100644 (file)
@@ -177,7 +177,33 @@ class DjVuHandler extends ImageHandler {
                        );
                }
 
-               $srcPath = $image->getLocalRefPath();
+               // Get local copy source for shell scripts
+               // Thumbnail extraction is very inefficient for large files.
+               // Provide a way to pool count limit the number of downloaders.
+               if ( $image->getSize() >= 1e7 ) { // 10MB
+                       $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $image->getName() ),
+                               array(
+                                       'doWork' => function() use ( $image ) {
+                                               return $image->getLocalRefPath();
+                                       }
+                               )
+                       );
+                       $srcPath = $work->execute();
+               } else {
+                       $srcPath = $image->getLocalRefPath();
+               }
+
+               if ( $srcPath === false ) { // Failed to get local copy
+                       wfDebugLog( 'thumbnail',
+                               sprintf( 'Thumbnail failed on %s: could not get local copy of "%s"',
+                                       wfHostname(), $image->getName() ) );
+
+                       return new MediaTransformError( 'thumbnail_error',
+                               $params['width'], $params['height'],
+                               wfMessage( 'filemissing' )->text()
+                       );
+               }
+
                # Use a subshell (brackets) to aggregate stderr from both pipeline commands
                # before redirecting it to the overall stdout. This works in both Linux and Windows XP.
                $cmd = '(' . wfEscapeShellArg(
@@ -230,6 +256,30 @@ class DjVuHandler extends ImageHandler {
                return $deja;
        }
 
+       /**
+        * Get metadata, unserializing it if neccessary.
+        *
+        * @param File $file The DjVu file in question
+        * @return String XML metadata as a string.
+        */
+       private function getUnserializedMetadata( File $file ) {
+               $metadata = $file->getMetadata();
+               if ( substr( $metadata, 0, 3 ) === '<?xml' ) {
+                       // Old style. Not serialized but instead just a raw string of XML.
+                       return $metadata;
+               }
+
+               wfSuppressWarnings();
+               $unser = unserialize( $metadata );
+               wfRestoreWarnings();
+               if ( is_array( $unser ) ) {
+                       return $unser['xml'];
+               }
+
+               // unserialize failed. Guess it wasn't really serialized after all,
+               return $metadata;
+       }
+
        /**
         * Cache a document tree for the DjVu XML metadata
         * @param File $image
@@ -244,7 +294,7 @@ class DjVuHandler extends ImageHandler {
                        return $image->dejaMetaTree;
                }
 
-               $metadata = $image->getMetadata();
+               $metadata = $this->getUnserializedMetadata( $image );
                if ( !$this->isMetadataValid( $image, $metadata ) ) {
                        wfDebug( "DjVu XML metadata is invalid or missing, should have been fixed in upgradeRow\n" );
 
@@ -307,7 +357,12 @@ class DjVuHandler extends ImageHandler {
        function getMetadata( $image, $path ) {
                wfDebug( "Getting DjVu metadata for $path\n" );
 
-               return $this->getDjVuImage( $image, $path )->retrieveMetaData();
+               $xml = $this->getDjVuImage( $image, $path )->retrieveMetaData();
+               if ( $xml === false ) {
+                       return false;
+               } else {
+                       return serialize( array( 'xml' => $xml ) );
+               }
        }
 
        function getMetadataType( $image ) {
index f992d83..02367e1 100644 (file)
@@ -95,21 +95,41 @@ class ProfileSection {
  * @todo document
  */
 class Profiler {
-       protected $mStack = array(), $mWorkStack = array(), $mCollated = array(),
-               $mCalls = array(), $mTotals = array(), $mPeriods = array();
+       /** @var array List of resolved profile calls with start/end data */
+       protected $mStack = array();
+       /** @var array Queue of open profile calls with start data */
+       protected $mWorkStack = array();
+
+       /** @var array Map of (function name => aggregate data array) */
+       protected $mCollated = array();
+       /** @var bool */
+       protected $mCollateDone = false;
+       /** @var bool */
+       protected $mCollateOnly = false;
+       /** @var array Cache of a standard broken collation entry */
+       protected $mErrorEntry;
+
+       /** @var string wall|cpu|user */
        protected $mTimeMetric = 'wall';
-       protected $mProfileID = false, $mCollateDone = false, $mTemplated = false;
+       /** @var string|bool Profiler ID for bucketing data */
+       protected $mProfileID = false;
+       /** @var bool Whether MediaWiki is in a SkinTemplate output context */
+       protected $mTemplated = false;
 
-       protected $mDBLockThreshold = 5.0; // float; seconds
+       /** @var float seconds */
+       protected $mDBLockThreshold = 5.0;
        /** @var Array DB/server name => (active trx count,timestamp) */
        protected $mDBTrxHoldingLocks = array();
-       /** @var Array DB/server name => list of (method, elapsed time) */
+       /** @var Array DB/server name => list of (function name, elapsed time) */
        protected $mDBTrxMethodTimes = array();
 
        /** @var Profiler */
        public static $__instance = null; // do not call this outside Profiler and ProfileSection
 
-       function __construct( $params ) {
+       /**
+        * @param array $params
+        */
+       public function __construct( array $params ) {
                if ( isset( $params['timeMetric'] ) ) {
                        $this->mTimeMetric = $params['timeMetric'];
                }
@@ -117,6 +137,8 @@ class Profiler {
                        $this->mProfileID = $params['profileID'];
                }
 
+               $this->mCollateOnly = $this->collateOnly();
+
                $this->addInitialStack();
        }
 
@@ -167,13 +189,19 @@ class Profiler {
         * @return Boolean
         */
        public function isPersistent() {
-               return true;
+               return false;
        }
 
+       /**
+        * @param string $id
+        */
        public function setProfileID( $id ) {
                $this->mProfileID = $id;
        }
 
+       /**
+        * @return string
+        */
        public function getProfileID() {
                if ( $this->mProfileID === false ) {
                        return wfWikiID();
@@ -182,20 +210,101 @@ class Profiler {
                }
        }
 
+       /**
+        * Whether to internally just track aggregates and ignore the full stack trace
+        *
+        * @return boolean
+        */
+       protected function collateOnly() {
+               return false;
+       }
+
        /**
         * Add the inital item in the stack.
         */
        protected function addInitialStack() {
-               // Push an entry for the pre-profile setup time onto the stack
-               $initial = $this->getInitialTime();
-               if ( $initial !== null ) {
-                       $this->mWorkStack[] = array( '-total', 0, $initial, 0 );
-                       $this->mStack[] = array( '-setup', 1, $initial, 0, $this->getTime(), 0 );
+               $this->mErrorEntry = $this->getErrorEntry();
+
+               $initialTime = $this->getInitialTime( 'wall' );
+               $initialCpu = $this->getInitialTime( 'cpu' );
+               if ( $initialTime !== null && $initialCpu !== null ) {
+                       $this->mWorkStack[] = array( '-total', 0, $initialTime, $initialCpu, 0 );
+                       if ( $this->mCollateOnly ) {
+                               $this->mWorkStack[] = array( '-setup', 1, $initialTime, $initialCpu, 0 );
+                               $this->profileOut( '-setup' );
+                       } else {
+                               $this->mStack[] = array( '-setup', 1, $initialTime, $initialCpu, 0,
+                                       $this->getTime( 'wall' ), $this->getTime( 'cpu' ), 0 );
+                       }
                } else {
                        $this->profileIn( '-total' );
                }
        }
 
+       /**
+        * @return array Initial collation entry
+        */
+       protected function getZeroEntry() {
+               return array(
+                       'cpu'      => 0.0,
+                       'cpu_sq'   => 0.0,
+                       'real'     => 0.0,
+                       'real_sq'  => 0.0,
+                       'memory'   => 0,
+                       'count'    => 0,
+                       'min_cpu'  => 0.0,
+                       'max_cpu'  => 0.0,
+                       'min_real' => 0.0,
+                       'max_real' => 0.0,
+                       'periods'  => array(), // not filled if mCollateOnly
+                       'overhead' => 0 // not filled if mCollateOnly
+               );
+       }
+
+       /**
+        * @return array Initial collation entry for errors
+        */
+       protected function getErrorEntry() {
+               $entry = $this->getZeroEntry();
+               $entry['count'] = 1;
+               return $entry;
+       }
+
+       /**
+        * Update the collation entry for a given method name
+        *
+        * @param string $name
+        * @param float $elapsedCpu
+        * @param float $elapsedReal
+        * @param integer $memChange
+        * @param integer $subcalls
+        * @param array|null $period Map of ('start','end','memory','subcalls')
+        */
+       protected function updateEntry(
+               $name, $elapsedCpu, $elapsedReal, $memChange, $subcalls = 0, $period = null
+       ) {
+               $entry =& $this->mCollated[$name];
+               if ( !is_array( $entry ) ) {
+                       $entry = $this->getZeroEntry();
+                       $this->mCollated[$name] =& $entry;
+               }
+               $entry['cpu'] += $elapsedCpu;
+               $entry['cpu_sq'] += $elapsedCpu * $elapsedCpu;
+               $entry['real'] += $elapsedReal;
+               $entry['real_sq'] += $elapsedReal * $elapsedReal;
+               $entry['memory'] += $memChange > 0 ? $memChange : 0;
+               $entry['count']++;
+               $entry['min_cpu'] = $elapsedCpu < $entry['min_cpu'] ? $elapsedCpu : $entry['min_cpu'];
+               $entry['max_cpu'] = $elapsedCpu > $entry['max_cpu'] ? $elapsedCpu : $entry['max_cpu'];
+               $entry['min_real'] = $elapsedReal < $entry['min_real'] ? $elapsedReal : $entry['min_real'];
+               $entry['max_real'] = $elapsedReal > $entry['max_real'] ? $elapsedReal : $entry['max_real'];
+               // Apply optional fields
+               $entry['overhead'] += $subcalls;
+               if ( $period ) {
+                       $entry['periods'][] = $period;
+               }
+       }
+
        /**
         * Called by wfProfieIn()
         *
@@ -203,11 +312,19 @@ class Profiler {
         */
        public function profileIn( $functionname ) {
                global $wgDebugFunctionEntry;
+
                if ( $wgDebugFunctionEntry ) {
-                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" );
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) .
+                               'Entering ' . $functionname . "\n" );
                }
 
-               $this->mWorkStack[] = array( $functionname, count( $this->mWorkStack ), $this->getTime(), memory_get_usage() );
+               $this->mWorkStack[] = array(
+                       $functionname,
+                       count( $this->mWorkStack ),
+                       $this->getTime( 'time' ),
+                       $this->getTime( 'cpu' ),
+                       memory_get_usage()
+               );
        }
 
        /**
@@ -217,33 +334,50 @@ class Profiler {
         */
        public function profileOut( $functionname ) {
                global $wgDebugFunctionEntry;
-               $memory = memory_get_usage();
-               $time = $this->getTime();
 
                if ( $wgDebugFunctionEntry ) {
-                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) .
+                               'Exiting ' . $functionname . "\n" );
                }
 
-               $bit = array_pop( $this->mWorkStack );
+               $item = array_pop( $this->mWorkStack );
+               list( $ofname, /* $ocount */, $ortime, $octime, $omem ) = $item;
 
-               if ( !$bit ) {
-                       $this->debugGroup( 'profileerror', "Profiling error, !\$bit: $functionname" );
+               if ( $item === null ) {
+                       $this->debugGroup( 'profileerror', "Profiling error: $functionname" );
                } else {
-                       if ( $functionname == 'close' ) {
-                               if ( $bit[0] != '-total' ) {
-                                       $message = "Profile section ended by close(): {$bit[0]}";
+                       if ( $functionname === 'close' ) {
+                               if ( $ofname !== '-total' ) {
+                                       $message = "Profile section ended by close(): {$ofname}";
                                        $this->debugGroup( 'profileerror', $message );
-                                       $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 );
+                                       if ( $this->mCollateOnly ) {
+                                               $this->mCollated[$message] = $this->mErrorEntry;
+                                       } else {
+                                               $this->mStack[] = array( $message, 0, 0.0, 0.0, 0, 0.0, 0.0, 0 );
+                                       }
                                }
-                       } elseif ( $bit[0] != $functionname ) {
-                               $message = "Profiling error: in({$bit[0]}), out($functionname)";
+                               $functionname = $ofname;
+                       } elseif ( $ofname !== $functionname ) {
+                               $message = "Profiling error: in({$ofname}), out($functionname)";
                                $this->debugGroup( 'profileerror', $message );
-                               $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 );
+                               if ( $this->mCollateOnly ) {
+                                       $this->mCollated[$message] = $this->mErrorEntry;
+                               } else {
+                                       $this->mStack[] = array( $message, 0, 0.0, 0.0, 0, 0.0, 0.0, 0 );
+                               }
+                       }
+                       $realTime = $this->getTime( 'wall' );
+                       $cpuTime = $this->getTime( 'cpu' );
+                       if ( $this->mCollateOnly ) {
+                               $elapsedcpu = $cpuTime - $octime;
+                               $elapsedreal = $realTime - $ortime;
+                               $memchange = memory_get_usage() - $omem;
+                               $this->updateEntry( $functionname, $elapsedcpu, $elapsedreal, $memchange );
+                       } else {
+                               $this->mStack[] = array_merge( $item,
+                                       array( $realTime, $cpuTime,     memory_get_usage() ) );
                        }
-                       $bit[] = $time;
-                       $bit[] = $memory;
-                       $this->mStack[] = $bit;
-                       $this->updateTrxProfiling( $functionname, $time );
+                       $this->updateTrxProfiling( $functionname, $realTime - $ortime );
                }
        }
 
@@ -256,6 +390,13 @@ class Profiler {
                }
        }
 
+       /**
+        * Log the data to some store or even the page output
+        */
+       public function logData() {
+               /* Implement in subclasses */
+       }
+
        /**
         * Mark a DB as in a transaction with one or more writes pending
         *
@@ -338,7 +479,7 @@ class Profiler {
         *
         * @param $t Boolean
         */
-       function setTemplated( $t ) {
+       public function setTemplated( $t ) {
                $this->mTemplated = $t;
        }
 
@@ -349,7 +490,8 @@ class Profiler {
         */
        public function getOutput() {
                global $wgDebugFunctionEntry, $wgProfileCallTree;
-               $wgDebugFunctionEntry = false;
+
+               $wgDebugFunctionEntry = false; // hack
 
                if ( !count( $this->mStack ) && !count( $this->mCollated ) ) {
                        return "No profiling output\n";
@@ -366,8 +508,10 @@ class Profiler {
         * Returns a tree of function call instead of a list of functions
         * @return string
         */
-       function getCallTree() {
-               return implode( '', array_map( array( &$this, 'getCallTreeLine' ), $this->remapCallTree( $this->mStack ) ) );
+       protected function getCallTree() {
+               return implode( '', array_map(
+                       array( &$this, 'getCallTreeLine' ), $this->remapCallTree( $this->mStack )
+               ) );
        }
 
        /**
@@ -376,7 +520,7 @@ class Profiler {
         * @param array $stack profiling array
         * @return array
         */
-       function remapCallTree( $stack ) {
+       protected function remapCallTree( array $stack ) {
                if ( count( $stack ) < 2 ) {
                        return $stack;
                }
@@ -415,13 +559,14 @@ class Profiler {
         * Callback to get a formatted line for the call tree
         * @return string
         */
-       function getCallTreeLine( $entry ) {
-               list( $fname, $level, $start, /* $x */, $end ) = $entry;
-               $delta = $end - $start;
+       protected function getCallTreeLine( $entry ) {
+               list( $fname, $level, $startreal, , , $endreal ) = $entry;
+               $delta = $endreal - $startreal;
                $space = str_repeat( ' ', $level );
                # The ugly double sprintf is to work around a PHP bug,
                # which has been fixed in recent releases.
-               return sprintf( "%10s %s %s\n", trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname );
+               return sprintf( "%10s %s %s\n",
+                       trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname );
        }
 
        /**
@@ -435,7 +580,7 @@ class Profiler {
         *   - false (default): will fall back to default metric
         * @return float|null
         */
-       function getTime( $metric = false ) {
+       protected function getTime( $metric = false ) {
                if ( $metric === false ) {
                        $metric = $this->mTimeMetric;
                }
@@ -496,17 +641,21 @@ class Profiler {
                }
        }
 
+       /**
+        * Populate mCollated
+        */
        protected function collateData() {
                if ( $this->mCollateDone ) {
                        return;
                }
                $this->mCollateDone = true;
+               $this->close(); // set "-total" entry
 
-               $this->close();
+               if ( $this->mCollateOnly ) {
+                       return; // already collated as methods exited
+               }
 
                $this->mCollated = array();
-               $this->mCalls = array();
-               $this->mMemory = array();
 
                # Estimate profiling overhead
                $profileCount = count( $this->mStack );
@@ -515,62 +664,49 @@ class Profiler {
                # First, subtract the overhead!
                $overheadTotal = $overheadMemory = $overheadInternal = array();
                foreach ( $this->mStack as $entry ) {
+                       // $entry is (name,pos,rtime0,cputime0,mem0,rtime1,cputime1,mem1)
                        $fname = $entry[0];
-                       $start = $entry[2];
-                       $end = $entry[4];
-                       $elapsed = $end - $start;
-                       $memory = $entry[5] - $entry[3];
+                       $elapsed = $entry[5] - $entry[2];
+                       $memchange = $entry[7] - $entry[4];
 
-                       if ( $fname == '-overhead-total' ) {
+                       if ( $fname === '-overhead-total' ) {
                                $overheadTotal[] = $elapsed;
-                               $overheadMemory[] = $memory;
-                       } elseif ( $fname == '-overhead-internal' ) {
+                               $overheadMemory[] = max( 0, $memchange );
+                       } elseif ( $fname === '-overhead-internal' ) {
                                $overheadInternal[] = $elapsed;
                        }
                }
-               $overheadTotal = $overheadTotal ? array_sum( $overheadTotal ) / count( $overheadInternal ) : 0;
-               $overheadMemory = $overheadMemory ? array_sum( $overheadMemory ) / count( $overheadInternal ) : 0;
-               $overheadInternal = $overheadInternal ? array_sum( $overheadInternal ) / count( $overheadInternal ) : 0;
+               $overheadTotal = $overheadTotal ?
+                       array_sum( $overheadTotal ) / count( $overheadInternal ) : 0;
+               $overheadMemory = $overheadMemory ?
+                       array_sum( $overheadMemory ) / count( $overheadInternal ) : 0;
+               $overheadInternal = $overheadInternal ?
+                       array_sum( $overheadInternal ) / count( $overheadInternal ) : 0;
 
                # Collate
                foreach ( $this->mStack as $index => $entry ) {
+                       // $entry is (name,pos,rtime0,cputime0,mem0,rtime1,cputime1,mem1)
                        $fname = $entry[0];
-                       $start = $entry[2];
-                       $end = $entry[4];
-                       $elapsed = $end - $start;
-
-                       $memory = $entry[5] - $entry[3];
+                       $elapsedCpu = $entry[6] - $entry[3];
+                       $elapsedReal = $entry[5] - $entry[2];
+                       $memchange = $entry[7] - $entry[4];
                        $subcalls = $this->calltreeCount( $this->mStack, $index );
 
-                       if ( !preg_match( '/^-overhead/', $fname ) ) {
+                       if ( substr( $fname, 0, 9 ) !== '-overhead' ) {
                                # Adjust for profiling overhead (except special values with elapsed=0
                                if ( $elapsed ) {
                                        $elapsed -= $overheadInternal;
                                        $elapsed -= ( $subcalls * $overheadTotal );
-                                       $memory -= ( $subcalls * $overheadMemory );
+                                       $memchange -= ( $subcalls * $overheadMemory );
                                }
                        }
 
-                       if ( !array_key_exists( $fname, $this->mCollated ) ) {
-                               $this->mCollated[$fname] = 0;
-                               $this->mCalls[$fname] = 0;
-                               $this->mMemory[$fname] = 0;
-                               $this->mMin[$fname] = 1 << 24;
-                               $this->mMax[$fname] = 0;
-                               $this->mOverhead[$fname] = 0;
-                               $this->mPeriods[$fname] = array();
-                       }
-
-                       $this->mCollated[$fname] += $elapsed;
-                       $this->mCalls[$fname]++;
-                       $this->mMemory[$fname] += $memory;
-                       $this->mMin[$fname] = min( $this->mMin[$fname], $elapsed );
-                       $this->mMax[$fname] = max( $this->mMax[$fname], $elapsed );
-                       $this->mOverhead[$fname] += $subcalls;
-                       $this->mPeriods[$fname][] = compact( 'start', 'end', 'memory', 'subcalls' );
+                       $period = array( 'start' => $entry[2], 'end' => $entry[5],
+                               'memory' => $memchange, 'subcalls' => $subcalls );
+                       $this->updateEntry( $fname, $elapsedCpu, $elapsedReal, $memchange, $subcalls, $period );
                }
 
-               $this->mCalls['-overhead-total'] = $profileCount;
+               $this->mCollated['-overhead-total']['count'] = $profileCount;
                arsort( $this->mCollated, SORT_NUMERIC );
        }
 
@@ -579,7 +715,7 @@ class Profiler {
         *
         * @return string
         */
-       function getFunctionReport() {
+       protected function getFunctionReport() {
                $this->collateData();
 
                $width = 140;
@@ -589,22 +725,24 @@ class Profiler {
                $prof = "\nProfiling data\n";
                $prof .= sprintf( $titleFormat, 'Name', 'Calls', 'Total', 'Each', '%', 'Mem' );
 
-               $total = isset( $this->mCollated['-total'] ) ? $this->mCollated['-total'] : 0;
+               $total = isset( $this->mCollated['-total'] )
+                       ? $this->mCollated['-total']['real']
+                       : 0;
 
-               foreach ( $this->mCollated as $fname => $elapsed ) {
-                       $calls = $this->mCalls[$fname];
-                       $percent = $total ? 100. * $elapsed / $total : 0;
-                       $memory = $this->mMemory[$fname];
+               foreach ( $this->mCollated as $fname => $data ) {
+                       $calls = $data['count'];
+                       $percent = $total ? 100 * $data['real'] / $total : 0;
+                       $memory = $data['memory'];
                        $prof .= sprintf( $format,
                                substr( $fname, 0, $nameWidth ),
                                $calls,
-                               (float)( $elapsed * 1000 ),
-                               (float)( $elapsed * 1000 ) / $calls,
+                               (float)( $data['real'] * 1000 ),
+                               (float)( $data['real'] * 1000 ) / $calls,
                                $percent,
                                $memory,
-                               ( $this->mMin[$fname] * 1000.0 ),
-                               ( $this->mMax[$fname] * 1000.0 ),
-                               $this->mOverhead[$fname]
+                               ( $data['min_real'] * 1000.0 ),
+                               ( $data['max_real'] * 1000.0 ),
+                               $data['overhead']
                        );
                }
                $prof .= "\nTotal: $total\n\n";
@@ -616,27 +754,48 @@ class Profiler {
         * @return array
         */
        public function getRawData() {
+               // This method is called before shutdown in the footer method on Skins.
+               // If some outer methods have not yet called wfProfileOut(), work around
+               // that by clearing anything in the work stack to just the "-total" entry.
+               // Collate after doing this so the results do not include profile errors.
+               if ( count( $this->mWorkStack ) > 1 ) {
+                       $oldWorkStack = $this->mWorkStack;
+                       $this->mWorkStack = array( $this->mWorkStack[0] ); // just the "-total" one
+               } else {
+                       $oldWorkStack = null;
+               }
                $this->collateData();
+               // If this trick is used, then the old work stack is swapped back afterwards
+               // and mCollateDone is reset to false. This means that logData() will still
+               // make use of all the method data since the missing wfProfileOut() calls
+               // should be made by the time it is called.
+               if ( $oldWorkStack ) {
+                       $this->mWorkStack = $oldWorkStack;
+                       $this->mCollateDone = false;
+               }
+
+               $total = isset( $this->mCollated['-total'] )
+                       ? $this->mCollated['-total']['real']
+                       : 0;
 
                $profile = array();
-               $total = isset( $this->mCollated['-total'] ) ? $this->mCollated['-total'] : 0;
-               foreach ( $this->mCollated as $fname => $elapsed ) {
+               foreach ( $this->mCollated as $fname => $data ) {
                        $periods = array();
-                       foreach ( $this->mPeriods[$fname] as $period ) {
+                       foreach ( $data['periods'] as $period ) {
                                $period['start'] *= 1000;
                                $period['end'] *= 1000;
                                $periods[] = $period;
                        }
                        $profile[] = array(
                                'name' => $fname,
-                               'calls' => $this->mCalls[$fname],
-                               'elapsed' => $elapsed * 1000,
-                               'percent' => $total ? 100. * $elapsed / $total : 0,
-                               'memory' => $this->mMemory[$fname],
-                               'min' => $this->mMin[$fname] * 1000,
-                               'max' => $this->mMax[$fname] * 1000,
-                               'overhead' => $this->mOverhead[$fname],
-                               'periods' => $periods,
+                               'calls' => $data['count'],
+                               'elapsed' => $data['real'] * 1000,
+                               'percent' => $total ? 100 * $data['real'] / $total : 0,
+                               'memory' => $data['memory'],
+                               'min' => $data['min_real'] * 1000,
+                               'max' => $data['max_real'] * 1000,
+                               'overhead' => $data['overhead'],
+                               'periods' => $periods
                        );
                }
 
@@ -662,9 +821,8 @@ class Profiler {
         * @param $stack Array:
         * @param $start Integer:
         * @return Integer
-        * @private
         */
-       function calltreeCount( $stack, $start ) {
+       protected function calltreeCount( $stack, $start ) {
                $level = $stack[$start][1];
                $count = 0;
                for ( $i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i-- ) {
@@ -673,83 +831,12 @@ class Profiler {
                return $count;
        }
 
-       /**
-        * Log the whole profiling data into the database.
-        */
-       public function logData() {
-               global $wgProfilePerHost, $wgProfileToDatabase;
-
-               # Do not log anything if database is readonly (bug 5375)
-               if ( wfReadOnly() || !$wgProfileToDatabase ) {
-                       return;
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               if ( !is_object( $dbw ) ) {
-                       return;
-               }
-
-               if ( $wgProfilePerHost ) {
-                       $pfhost = wfHostname();
-               } else {
-                       $pfhost = '';
-               }
-
-               try {
-                       $this->collateData();
-
-                       foreach ( $this->mCollated as $name => $elapsed ) {
-                               $eventCount = $this->mCalls[$name];
-                               $timeSum = (float)( $elapsed * 1000 );
-                               $memorySum = (float)$this->mMemory[$name];
-                               $name = substr( $name, 0, 255 );
-
-                               // Kludge
-                               $timeSum = $timeSum >= 0 ? $timeSum : 0;
-                               $memorySum = $memorySum >= 0 ? $memorySum : 0;
-
-                               $dbw->update( 'profiling',
-                                       array(
-                                               "pf_count=pf_count+{$eventCount}",
-                                               "pf_time=pf_time+{$timeSum}",
-                                               "pf_memory=pf_memory+{$memorySum}",
-                                       ),
-                                       array(
-                                               'pf_name' => $name,
-                                               'pf_server' => $pfhost,
-                                       ),
-                                       __METHOD__ );
-
-                               $rc = $dbw->affectedRows();
-                               if ( $rc == 0 ) {
-                                       $dbw->insert( 'profiling', array( 'pf_name' => $name, 'pf_count' => $eventCount,
-                                               'pf_time' => $timeSum, 'pf_memory' => $memorySum, 'pf_server' => $pfhost ),
-                                               __METHOD__, array( 'IGNORE' ) );
-                               }
-                               // When we upgrade to mysql 4.1, the insert+update
-                               // can be merged into just a insert with this construct added:
-                               //     "ON DUPLICATE KEY UPDATE ".
-                               //     "pf_count=pf_count + VALUES(pf_count), ".
-                               //     "pf_time=pf_time + VALUES(pf_time)";
-                       }
-               } catch ( DBError $e ) {}
-       }
-
-       /**
-        * Get the function name of the current profiling section
-        * @return
-        */
-       function getCurrentSection() {
-               $elt = end( $this->mWorkStack );
-               return $elt[0];
-       }
-
        /**
         * Add an entry in the debug log file
         *
         * @param string $s to output
         */
-       function debug( $s ) {
+       protected function debug( $s ) {
                if ( function_exists( 'wfDebug' ) ) {
                        wfDebug( $s );
                }
@@ -761,7 +848,7 @@ class Profiler {
         * @param string $group Group to send the message to
         * @param string $s to output
         */
-       function debugGroup( $group, $s ) {
+       protected function debugGroup( $group, $s ) {
                if ( function_exists( 'wfDebugLog' ) ) {
                        wfDebugLog( $group, $s );
                }
index e7ed6e3..67b6034 100644 (file)
  * @since 1.23
  */
 class ProfilerMwprof extends Profiler {
-
        // Message types
-
        const TYPE_SINGLE = 1;
        const TYPE_RUNNING = 2;
 
+       protected function collateOnly() {
+               return false;
+       }
+
        /**
         * Indicate that this Profiler subclass is persistent.
         *
@@ -62,18 +64,7 @@ class ProfilerMwprof extends Profiler {
         */
        public function profileIn( $inName ) {
                $this->mWorkStack[] = array( $inName, count( $this->mWorkStack ),
-                       $this->getTime(), $this->getTime( 'cpu' ) );
-       }
-
-       /**
-        * Produce an empty function report.
-        *
-        * ProfileMwprof does not provide a function report.
-        *
-        * @return string Empty string.
-        */
-       public function getFunctionReport() {
-               return '';
+                       $this->getTime(), $this->getTime( 'cpu' ), 0 );
        }
 
        /**
@@ -96,7 +87,7 @@ class ProfilerMwprof extends Profiler {
 
                $elapsedCpu = $this->getTime( 'cpu' ) - $inCpu;
                $elapsedWall = $this->getTime() - $inWall;
-               $this->updateEntry( $outName, $elapsedCpu, $elapsedWall );
+               $this->updateRunningEntry( $outName, $elapsedCpu, $elapsedWall );
                $this->updateTrxProfiling( $outName, $elapsedWall );
        }
 
@@ -107,7 +98,7 @@ class ProfilerMwprof extends Profiler {
         * @param float $elapsedCpu elapsed CPU time
         * @param float $elapsedWall elapsed wall-clock time
         */
-       public function updateEntry( $name, $elapsedCpu, $elapsedWall ) {
+       public function updateRunningEntry( $name, $elapsedCpu, $elapsedWall ) {
                // If this is the first measurement for this entry, store plain values.
                // Many profiled functions will only be called once per request.
                if ( !isset( $this->mCollated[$name] ) ) {
@@ -138,6 +129,77 @@ class ProfilerMwprof extends Profiler {
                $entry['wall']->push( $elapsedWall );
        }
 
+       /**
+        * Produce an empty function report.
+        *
+        * ProfileMwprof does not provide a function report.
+        *
+        * @return string Empty string.
+        */
+       public function getFunctionReport() {
+               return '';
+       }
+
+       /**
+        * @return array
+        */
+       public function getRawData() {
+               // This method is called before shutdown in the footer method on Skins.
+               // If some outer methods have not yet called wfProfileOut(), work around
+               // that by clearing anything in the work stack to just the "-total" entry.
+               if ( count( $this->mWorkStack ) > 1 ) {
+                       $oldWorkStack = $this->mWorkStack;
+                       $this->mWorkStack = array( $this->mWorkStack[0] ); // just the "-total" one
+               } else {
+                       $oldWorkStack = null;
+               }
+               $this->close();
+               // If this trick is used, then the old work stack is swapped back afterwards.
+               // This means that logData() will still make use of all the method data since
+               // the missing wfProfileOut() calls should be made by the time it is called.
+               if ( $oldWorkStack ) {
+                       $this->mWorkStack = $oldWorkStack;
+               }
+
+               $totalWall = 0.0;
+               $profile = array();
+               foreach ( $this->mCollated as $fname => $data ) {
+                       if ( $data['count'] == 1 ) {
+                               $profile[] = array(
+                                       'name' => $fname,
+                                       'calls' => $data['count'],
+                                       'elapsed' => $data['wall'] * 1000,
+                                       'memory' => 0, // not supported
+                                       'min' => $data['wall'] * 1000,
+                                       'max' => $data['wall'] * 1000,
+                                       'overhead' => 0, // not supported
+                                       'periods' => array() // not supported
+                               );
+                               $totalWall += $data['wall'];
+                       } else {
+                               $profile[] = array(
+                                       'name' => $fname,
+                                       'calls' => $data['count'],
+                                       'elapsed' => $data['wall']->n * $data['wall']->getMean() * 1000,
+                                       'memory' => 0, // not supported
+                                       'min' => $data['wall']->min * 1000,
+                                       'max' => $data['wall']->max * 1000,
+                                       'overhead' => 0, // not supported
+                                       'periods' => array() // not supported
+                               );
+                               $totalWall += $data['wall']->n * $data['wall']->getMean();
+                       }
+               }
+               $totalWall = $totalWall * 1000;
+
+               foreach ( $profile as &$item ) {
+                       $item['percent'] = $totalWall ? 100 * $item['elapsed'] / $totalWall : 0;
+                       $z+= $item['percent'];
+               }
+
+               return $profile;
+       }
+
        /**
         * Serialize profiling data and send to a profiling data aggregator.
         *
@@ -151,6 +213,11 @@ class ProfilerMwprof extends Profiler {
 
                $this->close();
 
+               if ( !function_exists( 'socket_create' ) ) {
+                       #trigger_error( __METHOD__ . ": function \"socket_create\" not found." );
+                       return; // avoid fatal
+               }
+
                $sock = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
                socket_connect( $sock, $wgUDPProfilerHost, $wgUDPProfilerPort );
                $bufferLength = 0;
diff --git a/includes/profiler/ProfilerSimple.php b/includes/profiler/ProfilerSimple.php
deleted file mode 100644 (file)
index 36f4bd4..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-/**
- * Base class for simple profiling.
- *
- * 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 Profiler
- */
-
-/**
- * Simple profiler base class.
- * @todo document methods (?)
- * @ingroup Profiler
- */
-class ProfilerSimple extends Profiler {
-       var $mMinimumTime = 0;
-
-       var $errorEntry;
-
-       public function getZeroEntry() {
-               return array(
-                       'cpu'     => 0.0,
-                       'cpu_sq'  => 0.0,
-                       'real'    => 0.0,
-                       'real_sq' => 0.0,
-                       'count'   => 0
-               );
-       }
-
-       public function getErrorEntry() {
-               $entry = $this->getZeroEntry();
-               $entry['count'] = 1;
-               return $entry;
-       }
-
-       public function updateEntry( $name, $elapsedCpu, $elapsedReal ) {
-               $entry =& $this->mCollated[$name];
-               if ( !is_array( $entry ) ) {
-                       $entry = $this->getZeroEntry();
-                       $this->mCollated[$name] =& $entry;
-               }
-               $entry['cpu'] += $elapsedCpu;
-               $entry['cpu_sq'] += $elapsedCpu * $elapsedCpu;
-               $entry['real'] += $elapsedReal;
-               $entry['real_sq'] += $elapsedReal * $elapsedReal;
-               $entry['count']++;
-       }
-
-       public function isPersistent() {
-               /* Implement in output subclasses */
-               return false;
-       }
-
-       protected function addInitialStack() {
-               $this->errorEntry = $this->getErrorEntry();
-
-               $initialTime = $this->getInitialTime();
-               $initialCpu = $this->getInitialTime( 'cpu' );
-               if ( $initialTime !== null && $initialCpu !== null ) {
-                       $this->mWorkStack[] = array( '-total', 0, $initialTime, $initialCpu );
-                       $this->mWorkStack[] = array( '-setup', 1, $initialTime, $initialCpu );
-
-                       $this->profileOut( '-setup' );
-               } else {
-                       $this->profileIn( '-total' );
-               }
-       }
-
-       function setMinimum( $min ) {
-               $this->mMinimumTime = $min;
-       }
-
-       function profileIn( $functionname ) {
-               global $wgDebugFunctionEntry;
-               if ( $wgDebugFunctionEntry ) {
-                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" );
-               }
-               $this->mWorkStack[] = array( $functionname, count( $this->mWorkStack ), $this->getTime(), $this->getTime( 'cpu' ) );
-       }
-
-       function profileOut( $functionname ) {
-               global $wgDebugFunctionEntry;
-
-               if ( $wgDebugFunctionEntry ) {
-                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
-               }
-
-               list( $ofname, /* $ocount */, $ortime, $octime ) = array_pop( $this->mWorkStack );
-
-               if ( !$ofname ) {
-                       $this->debugGroup( 'profileerror', "Profiling error: $functionname" );
-               } else {
-                       if ( $functionname == 'close' ) {
-                               if ( $ofname != '-total' ) {
-                                       $message = "Profile section ended by close(): {$ofname}";
-                                       $this->debugGroup( 'profileerror', $message );
-                                       $this->mCollated[$message] = $this->errorEntry;
-                               }
-                               $functionname = $ofname;
-                       } elseif ( $ofname != $functionname ) {
-                               $message = "Profiling error: in({$ofname}), out($functionname)";
-                               $this->debugGroup( 'profileerror', $message );
-                               $this->mCollated[$message] = $this->errorEntry;
-                       }
-                       $elapsedcpu = $this->getTime( 'cpu' ) - $octime;
-                       $elapsedreal = $this->getTime() - $ortime;
-                       $this->updateEntry( $functionname, $elapsedcpu, $elapsedreal );
-                       $this->updateTrxProfiling( $functionname, $elapsedreal );
-               }
-       }
-
-       public function getRawData() {
-               // Calling the method of the parent class results in fatal error.
-               // @todo Implement this correctly.
-               return array();
-       }
-
-       public function getFunctionReport() {
-               /* Implement in output subclasses */
-               return '';
-       }
-
-       public function logData() {
-               /* Implement in subclasses */
-       }
-}
diff --git a/includes/profiler/ProfilerSimpleDB.php b/includes/profiler/ProfilerSimpleDB.php
new file mode 100644 (file)
index 0000000..e35eec1
--- /dev/null
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Profiler storing information in the DB.
+ *
+ * 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 Profiler
+ */
+
+/**
+ * $wgProfiler['class'] = 'ProfilerSimpleDB';
+ *
+ * @ingroup Profiler
+ */
+class ProfilerSimpleDB extends Profiler {
+       protected function collateOnly() {
+               return true;
+       }
+
+       public function isPersistent() {
+               return true;
+       }
+
+       /**
+        * Log the whole profiling data into the database.
+        */
+       public function logData() {
+               global $wgProfilePerHost;
+
+               # Do not log anything if database is readonly (bug 5375)
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
+               if ( $wgProfilePerHost ) {
+                       $pfhost = wfHostname();
+               } else {
+                       $pfhost = '';
+               }
+
+               try {
+                       $this->collateData();
+
+                       $dbw = wfGetDB( DB_MASTER );
+                       $useTrx = ( $dbw->getType() === 'sqlite' ); // much faster
+                       if ( $useTrx ) {
+                               $dbw->begin();
+                       }
+                       foreach ( $this->mCollated as $name => $data ) {
+                               $eventCount = $data['count'];
+                               $timeSum = (float)( $data['real'] * 1000 );
+                               $memorySum = (float)$data['memory'];
+                               $name = substr( $name, 0, 255 );
+
+                               // Kludge
+                               $timeSum = $timeSum >= 0 ? $timeSum : 0;
+                               $memorySum = $memorySum >= 0 ? $memorySum : 0;
+
+                               $dbw->update( 'profiling',
+                                       array(
+                                               "pf_count=pf_count+{$eventCount}",
+                                               "pf_time=pf_time+{$timeSum}",
+                                               "pf_memory=pf_memory+{$memorySum}",
+                                       ),
+                                       array(
+                                               'pf_name' => $name,
+                                               'pf_server' => $pfhost,
+                                       ),
+                                       __METHOD__ );
+
+                               $rc = $dbw->affectedRows();
+                               if ( $rc == 0 ) {
+                                       $dbw->insert( 'profiling',
+                                               array(
+                                                       'pf_name' => $name,
+                                                       'pf_count' => $eventCount,
+                                                       'pf_time' => $timeSum,
+                                                       'pf_memory' => $memorySum,
+                                                       'pf_server' => $pfhost
+                                               ),
+                                               __METHOD__,
+                                               array( 'IGNORE' )
+                                       );
+                               }
+                               // When we upgrade to mysql 4.1, the insert+update
+                               // can be merged into just a insert with this construct added:
+                               //     "ON DUPLICATE KEY UPDATE ".
+                               //     "pf_count=pf_count + VALUES(pf_count), ".
+                               //     "pf_time=pf_time + VALUES(pf_time)";
+                       }
+                       if ( $useTrx ) {
+                               $dbw->commit();
+                       }
+               } catch ( DBError $e ) {}
+       }
+}
index 1d57ea8..975d260 100644 (file)
@@ -31,7 +31,7 @@
  *
  * @ingroup Profiler
  */
-class ProfilerSimpleText extends ProfilerSimple {
+class ProfilerSimpleText extends Profiler {
        public $visible = false; /* Show as <PRE> or <!-- ? */
        static private $out;
 
@@ -42,6 +42,10 @@ class ProfilerSimpleText extends ProfilerSimple {
                parent::__construct( $profileConfig );
        }
 
+       protected function collateOnly() {
+               return true;
+       }
+
        public function logData() {
                if ( $this->mTemplated ) {
                        $this->close();
index 5588d1e..8d7f11c 100644 (file)
  */
 
 /**
- * Execution trace
+ * Execution trace profiler
  * @todo document methods (?)
  * @ingroup Profiler
  */
-class ProfilerSimpleTrace extends ProfilerSimple {
-       var $trace = "Beginning trace: \n";
-       var $memory = 0;
+class ProfilerSimpleTrace extends Profiler {
+       protected $trace = "Beginning trace: \n";
+       protected $memory = 0;
 
-       function profileIn( $functionname ) {
+       protected function collateOnly() {
+               return true;
+       }
+
+       public function profileIn( $functionname ) {
                parent::profileIn( $functionname );
+
                $this->trace .= "         " . sprintf( "%6.1f", $this->memoryDiff() ) .
-                               str_repeat( " ", count( $this->mWorkStack ) ) . " > " . $functionname . "\n";
+                       str_repeat( " ", count( $this->mWorkStack ) ) . " > " . $functionname . "\n";
        }
 
-       function profileOut( $functionname ) {
-               global $wgDebugFunctionEntry;
-
-               if ( $wgDebugFunctionEntry ) {
-                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
-               }
+       public function profileOut( $functionname ) {
+               $item = end( $this->mWorkStack );
 
-               list( $ofname, /* $ocount */, $ortime ) = array_pop( $this->mWorkStack );
+               parent::profileOut( $functionname );
 
-               if ( !$ofname ) {
+               if ( !$item ) {
                        $this->trace .= "Profiling error: $functionname\n";
                } else {
+                       list( $ofname, /* $ocount */, $ortime ) = $item;
                        if ( $functionname == 'close' ) {
                                $message = "Profile section ended by close(): {$ofname}";
                                $functionname = $ofname;
                                $this->trace .= $message . "\n";
-                       }
-                       elseif ( $ofname != $functionname ) {
+                       } elseif ( $ofname != $functionname ) {
                                $this->trace .= "Profiling error: in({$ofname}), out($functionname)";
                        }
                        $elapsedreal = $this->getTime() - $ortime;
                        $this->trace .= sprintf( "%03.6f %6.1f", $elapsedreal, $this->memoryDiff() ) .
-                                       str_repeat( " ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n";
-
-                       $this->updateTrxProfiling( $functionname, $elapsedreal );
+                               str_repeat( " ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n";
                }
        }
 
-       function memoryDiff() {
+       protected function memoryDiff() {
                $diff = memory_get_usage() - $this->memory;
                $this->memory = memory_get_usage();
                return $diff / 1024;
        }
 
-       function logData() {
-               if ( PHP_SAPI === 'cli' ) {
-                       print "<!-- \n {$this->trace} \n -->";
-               } elseif ( $this->getContentType() === 'text/html' ) {
-                       print "<!-- \n {$this->trace} \n -->";
-               } elseif ( $this->getContentType() === 'text/javascript' ) {
-                       print "\n/*\n {$this->trace}\n*/";
-               } elseif ( $this->getContentType() === 'text/css' ) {
-                       print "\n/*\n {$this->trace}\n*/";
+       public function logData() {
+               if ( $this->mTemplated ) {
+                       if ( PHP_SAPI === 'cli' ) {
+                               print "<!-- \n {$this->trace} \n -->";
+                       } elseif ( $this->getContentType() === 'text/html' ) {
+                               print "<!-- \n {$this->trace} \n -->";
+                       } elseif ( $this->getContentType() === 'text/javascript' ) {
+                               print "\n/*\n {$this->trace}\n*/";
+                       } elseif ( $this->getContentType() === 'text/css' ) {
+                               print "\n/*\n {$this->trace}\n*/";
+                       }
                }
        }
 }
index 982c6ae..e9bcff6 100644 (file)
  *  http://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile)
  * @ingroup Profiler
  */
-class ProfilerSimpleUDP extends ProfilerSimple {
+class ProfilerSimpleUDP extends Profiler {
+       protected function collateOnly() {
+               return true;
+       }
+
        public function isPersistent() {
                return true;
        }
@@ -37,7 +41,7 @@ class ProfilerSimpleUDP extends ProfilerSimple {
 
                $this->close();
 
-               if ( isset( $this->mCollated['-total'] ) && $this->mCollated['-total']['real'] < $this->mMinimumTime ) {
+               if ( isset( $this->mCollated['-total'] ) ) {
                        # Less than minimum, ignore
                        return;
                }
index 14ac401..bc0b8ff 100644 (file)
@@ -151,8 +151,12 @@ abstract class ChangesListSpecialPage extends SpecialPage {
         * @return array Map of filter URL param names to properties (msg/default)
         */
        protected function getCustomFilters() {
-               // @todo Fire a Special{$this->getName()}Filters hook here
-               return array();
+               if ( $this->customFilters === null ) {
+                       $this->customFilters = array();
+                       wfRunHooks( 'ChangesListSpecialPageFilters', array( $this, &$this->customFilters ) );
+               }
+
+               return $this->customFilters;
        }
 
        /**
@@ -286,13 +290,11 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        ''
                );
 
-               // @todo Fire a Special{$this->getName()}Query hook here
-               // @todo Uncomment and document
-               // if ( !wfRunHooks( 'ChangesListSpecialPageQuery',
-               //      array( &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) )
-               // ) {
-               //      return false;
-               // }
+               if ( !wfRunHooks( 'ChangesListSpecialPageQuery',
+                       array( $this->getName(), &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) )
+               ) {
+                       return false;
+               }
 
                $dbr = $this->getDB();
 
index 51606b7..f20355b 100644 (file)
@@ -244,6 +244,16 @@ class SpecialContributions extends IncludableSpecialPage {
         */
        protected function contributionsSub( $userObj ) {
                if ( $userObj->isAnon() ) {
+                       // Show a warning message that the user being searched for doesn't exists
+                       if ( !User::isIP( $userObj ) ) {
+                               $this->getOutput()->wrapWikiMsg(
+                                       "<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>",
+                                       array(
+                                               'contributions-userdoesnotexist',
+                                               wfEscapeWikiText( $userObj->getName() ),
+                                       )
+                               );
+                       }
                        $user = htmlspecialchars( $userObj->getName() );
                } else {
                        $user = Linker::link( $userObj->getUserPage(), htmlspecialchars( $userObj->getName() ) );
index f13fc59..7ad39d2 100644 (file)
@@ -36,6 +36,9 @@ class SpecialPrefixindex extends SpecialAllpages {
 
        protected $hideRedirects = false;
 
+       // number of columns in output table
+       protected $columns = 3;
+
        // Inherit $maxPerPage
 
        function __construct() {
@@ -63,6 +66,7 @@ class SpecialPrefixindex extends SpecialAllpages {
                $namespace = (int)$ns; // if no namespace given, use 0 (NS_MAIN).
                $this->hideRedirects = $request->getBool( 'hideredirects', $this->hideRedirects );
                $this->stripPrefix = $request->getBool( 'stripprefix', $this->stripPrefix );
+               $this->columns = $request->getInt( 'columns', $this->columns );
 
                $namespaces = $wgContLang->getNamespaces();
                $out->setPageTitle(
@@ -224,17 +228,17 @@ class SpecialPrefixindex extends SpecialAllpages {
                                        } else {
                                                $link = '[[' . htmlspecialchars( $s->page_title ) . ']]';
                                        }
-                                       if ( $n % 3 == 0 ) {
+                                       if ( $n % $this->columns == 0 ) {
                                                $out .= '<tr>';
                                        }
                                        $out .= "<td>$link</td>";
                                        $n++;
-                                       if ( $n % 3 == 0 ) {
+                                       if ( $n % $this->columns == 0 ) {
                                                $out .= '</tr>';
                                        }
                                }
 
-                               if ( $n % 3 != 0 ) {
+                               if ( $n % $this->columns != 0 ) {
                                        $out .= '</tr>';
                                }
 
@@ -265,6 +269,7 @@ class SpecialPrefixindex extends SpecialAllpages {
                                        'prefix' => $prefix,
                                        'hideredirects' => $this->hideRedirects,
                                        'stripprefix' => $this->stripPrefix,
+                                       'columns' => $this->columns,
                                );
 
                                if ( $namespace || $prefix == '' ) {
index 72fa9bc..f1a31a5 100644 (file)
@@ -94,8 +94,8 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         */
        protected function getCustomFilters() {
                if ( $this->customFilters === null ) {
-                       $this->customFilters = array();
-                       wfRunHooks( 'SpecialRecentChangesFilters', array( $this, &$this->customFilters ) );
+                       $this->customFilters = parent::getCustomFilters();
+                       wfRunHooks( 'SpecialRecentChangesFilters', array( $this, &$this->customFilters ), '1.23' );
                }
 
                return $this->customFilters;
@@ -230,7 +230,8 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                );
 
                if ( !wfRunHooks( 'SpecialRecentChangesQuery',
-                       array( &$conds, &$tables, &$join_conds, $opts, &$query_options, &$fields ) )
+                       array( &$conds, &$tables, &$join_conds, $opts, &$query_options, &$fields ),
+                       '1.23' )
                ) {
                        return false;
                }
index 526e949..e73cabc 100644 (file)
@@ -110,7 +110,8 @@ class SpecialRecentChangesLinked extends SpecialRecentChanges {
                );
 
                if ( !wfRunHooks( 'SpecialRecentChangesQuery',
-                       array( &$conds, &$tables, &$join_conds, $opts, &$query_options, &$select ) )
+                       array( &$conds, &$tables, &$join_conds, $opts, &$query_options, &$select ),
+                       '1.23' )
                ) {
                        return false;
                }
index c1fe21a..1345b76 100644 (file)
@@ -107,8 +107,8 @@ class SpecialWatchlist extends ChangesListSpecialPage {
         */
        protected function getCustomFilters() {
                if ( $this->customFilters === null ) {
-                       $this->customFilters = array();
-                       wfRunHooks( 'SpecialWatchlistFilters', array( $this, &$this->customFilters ) );
+                       $this->customFilters = parent::getCustomFilters();
+                       wfRunHooks( 'SpecialWatchlistFilters', array( $this, &$this->customFilters ), '1.23' );
                }
 
                return $this->customFilters;
@@ -258,7 +258,8 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                );
 
                wfRunHooks( 'SpecialWatchlistQuery',
-                       array( &$conds, &$tables, &$join_conds, &$fields, $opts ) );
+                       array( &$conds, &$tables, &$join_conds, &$fields, $opts ),
+                       '1.23' );
 
                return $dbr->select(
                        $tables,
index 06e9058..7a865eb 100644 (file)
@@ -157,6 +157,6 @@ class TitleValue {
                        $name .= '#' . $this->fragment;
                }
 
-               return  $name;
+               return $name;
        }
 }
index a630a37..43bd79a 100644 (file)
     "prefs-skin": "Kulét",
     "skin-preview": "Eu dilèe",
     "datedefault": "Hana geunalak",
-    "prefs-datetime": "Uroe ngön jeum",
     "prefs-user-pages": "Laman ureueng ngui",
     "prefs-personal": "Profil ureueng ngui",
     "prefs-rc": "Ban meuubah",
index 467801a..3ad3f59 100644 (file)
     "prefs-skin": "واجهة",
     "skin-preview": "عرض مسبق",
     "datedefault": "لا تفضيل",
-    "prefs-datetime": "وقت وتاريخ",
     "prefs-labs": "مزايا مختبرية",
     "prefs-user-pages": "صفحات المستخدمين",
     "prefs-personal": "ملف المستخدم",
index 853c4d5..2653a5f 100644 (file)
     "prefs-skin": "ܓܠܕܐ",
     "skin-preview": "ܚܝܪܐ ܩܕܡܝܐ",
     "datedefault": "ܠܐ ܨܒܝܢܝܘܬܐ",
-    "prefs-datetime": "ܣܝܩܘܡܐ ܘܙܒܢܐ",
     "prefs-personal": "ܦܘܓܪܦܐ ܕܡܦܠܚܢܐ",
     "prefs-rc": "ܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ",
     "prefs-watchlist": "ܪ̈ܗܝܬܐ",
index 64f5e01..70c8eb5 100644 (file)
     "prefs-skin": "আৱৰণ",
     "skin-preview": "খচৰা",
     "datedefault": "কোনো পছন্দ নাই",
-    "prefs-datetime": "তাৰিখ আৰু সময়",
     "prefs-labs": "পৰীক্ষাগাৰ বৈশিষ্টসমূহ",
     "prefs-user-pages": "সদস্য পৃষ্ঠাসমূহ",
     "prefs-personal": "সদস্যৰ বিৱৰণ",
index ed3bbf0..5c0a2ec 100644 (file)
     "prefs-skin": "Apariencia",
     "skin-preview": "Vista previa",
     "datedefault": "Ensin preferencia",
-    "prefs-datetime": "Fecha y hora",
     "prefs-labs": "Carauterístiques esperimentales",
     "prefs-user-pages": "Páxines d'usuariu",
     "prefs-personal": "Perfil del usuariu",
index ca4fab6..2c5aa2a 100644 (file)
     "prefs-skin": "قابیق",
     "skin-preview": "اؤن‌گؤستریش",
     "datedefault": "سئچیم‌سیز",
-    "prefs-datetime": "تاریخ و واخت",
     "prefs-labs": "آزماییشی اؤزل‌لیکلر",
     "prefs-user-pages": "ایستیفاده‌چی صحیفه‌لری",
     "prefs-personal": "ایستیفاده‌چی پروفایلی",
index 675057d..7ad7323 100644 (file)
     "permalink": "Сталая спасылка",
     "print": "Друкаваць",
     "view": "Прагляд",
+    "view-foreign": "Паглядзець на старонцы $1",
     "edit": "Рэдагаваць",
+    "edit-local": "Рэдагаваць лякальнае апісаньне",
     "create": "Стварыць",
     "editthispage": "Рэдагаваць гэтую старонку",
     "create-this-page": "Стварыць гэтую старонку",
     "accountcreatedtext": "Рахунак {{GENDER:$1|удзельніка|удзельніцы}} [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|гутаркі]]) быў створаны.",
     "createaccount-title": "Стварэньне рахунку ў {{GRAMMAR:месны|{{SITENAME}}}}",
     "createaccount-text": "Нехта стварыў рахунак «$2» у {{GRAMMAR:месны|{{SITENAME}}}} ($4) для Вашага адрасу электроннай пошты. Пароль для гэтага рахунку — «$3». Вам трэба ўвайсьці і зьмяніць Ваш пароль зараз.\n\nВы можаце праігнараваць гэты ліст, калі гэты рахунак быў створаны памылкова.",
-    "usernamehasherror": "Імя ўдзельніка ня можа ўтрымліваць сымбаль #",
     "login-throttled": "Вы зрабілі надта шмат спробаў уваходу ў сыстэму.\nКалі ласка, пачакайце $1 перад тым як паспрабаваць ізноў.",
     "login-abort-generic": "Не атрымалася ўвайсьці ў сыстэму, скасавана",
     "loginlanguagelabel": "Мова: $1",
     "prefs-skin": "Афармленьне",
     "skin-preview": "Папярэдні прагляд",
     "datedefault": "Па змоўчаньні",
-    "prefs-datetime": "Дата і час",
     "prefs-labs": "Экспэрымэнтальныя магчымасьці",
     "prefs-user-pages": "Старонкі ўдзельніка",
     "prefs-personal": "Асабістыя зьвесткі",
     "upload-permitted": "Дазволеныя тыпы файлаў: $1.",
     "upload-preferred": "Пажаданыя тыпы файлаў: $1.",
     "upload-prohibited": "Забароненыя тыпы файлаў: $1.",
-    "uploadlog": "журнал загрузак",
     "uploadlogpage": "Журнал загрузак",
     "uploadlogpagetext": "Сьпіс апошніх загружаных файлаў.",
     "filename": "Назва файла",
     "filereuploadsummary": "Зьмены ў файле:",
     "filestatus": "Умовы распаўсюджаньня і выкарыстаньня:",
     "filesource": "Крыніца:",
-    "uploadedfiles": "Загружаныя файлы",
     "ignorewarning": "Праігнараваць папярэджаньне і захаваць файл",
     "ignorewarnings": "Ігнараваць усе папярэджаньні",
     "minlength1": "Назва файла павінна ўтрымліваць хаця б адзін сымбаль.",
     "overwroteimage": "загружаная новая вэрсія «[[$1]]»",
     "uploaddisabled": "Загрузка файлаў забароненая",
     "copyuploaddisabled": "Загрузка праз URL-адрас адключаная.",
-    "uploadfromurl-queued": "Ваша загрузка далучаная да чаргі.",
     "uploaddisabledtext": "Загрузка файлаў забароненая.",
     "php-uploaddisabledtext": "Загрузка файлаў была адключаная ў парамэтрах канфігурацыі PHP. Калі ласка, праверце значэньне парамэтра «file_uploads».",
     "uploadscripted": "Гэты файл утрымлівае HTML-код альбо скрыпт, які можа памылкова апрацоўвацца браўзэрам.",
     "upload-misc-error": "Невядомая памылка загрузкі",
     "upload-misc-error-text": "Адбылася невядомая памылка пад час загрузкі.\nКалі ласка, упэўніцеся, што URL-адрас слушны, і паспрабуйце ізноў.\nКалі памылка паўтарыцца, зьвярніцеся да [[Special:ListUsers/sysop|адміністратара]].",
     "upload-too-many-redirects": "URL-адрас утрымлівае зашмат перанакіраваньняў",
-    "upload-unknown-size": "Невядомы памер",
     "upload-http-error": "Узьнікла памылка HTTP: $1",
     "upload-copy-upload-invalid-domain": "Капіяваньне загрузак не дазволенае ў гэтым дамэне.",
     "backend-fail-stream": "Немагчыма накіраваць файл $1.",
     "img-auth-streaming": "Перадача струменя «$1».",
     "img-auth-public": "Функцыя img_auth.php ужываецца для файла выхаду з прыватнай вікі.\nГэта вікі ўсталявана як публічная вікі.\nДля найлепшай бясьпекі img_auth.php выключана.",
     "img-auth-noread": "Удзельнік ня мае доступу на чытаньне «$1».",
-    "img-auth-bad-query-string": "URL-адрас утрымлівае няслушны радок запыту.",
     "http-invalid-url": "Няслушны URL-адрас: $1",
     "http-invalid-scheme": "URL-адрасы схемы «$1» не падтрымліваюцца",
     "http-request-error": "HTTP-запыт не атрымаўся ў выніку невядомай памылкі.",
     "filehist-dimensions": "Памеры",
     "filehist-filesize": "Памер файла",
     "filehist-comment": "Камэнтар",
-    "filehist-missing": "Файл адсутнічае",
     "imagelinks": "Выкарыстаньне файла",
     "linkstoimage": "{{PLURAL:$1|1=Наступная старонка спасылаецца|Наступныя старонкі спасылаюцца}} на гэты файл:",
     "linkstoimage-more": "Больш чым $1 {{PLURAL:$1|старонка спасылаецца|старонкі спасылаюцца|старонак спасылаюцца}} на гэты файл.\nУ гэтым сьпісе толькі $1 {{PLURAL:$1|спасылка|спасылкі|спасылак}} на гэты файл.\nДаступны таксама [[Special:WhatLinksHere/$2|поўны сьпіс]].",
     "emailuser-title-notarget": "Даслаць ліст ўдзельніку ці ўдзельніцы па электроннай пошце",
     "emailpage": "Даслаць ліст ўдзельніку ці ўдзельніцы па электроннай пошце",
     "emailpagetext": "Вы можаце выкарыстаць форму ніжэй, каб даслаць {{GENDER:$1|гэтаму ўдзельніку|гэтай удзельніцы}} ліст па электроннай пошце.\nАдрас электроннай пошты, які Вы пазначалі ў [[Special:Preferences|сваіх наладах]], будзе пазначаны ў полі ліста «Ад», і {{GENDER:$1|ўдзельнік|ўдзельніца}} зможа даслаць на гэты адрас адказ.",
-    "usermailererror": "Пры адсыланьні пошты адбылася памылка:",
     "defemailsubject": "Ліст з {{GRAMMAR:родны|{{SITENAME}}}} ад {{GENDER:$1|удзельніка|удзельніцы}} «$1»",
     "usermaildisabled": "Электронная пошта ўдзельніка адключаная",
     "usermaildisabledtext": "Вы ня можаце дасылаць электронныя лісты іншым удзельнікам {{GRAMMAR:родны|{{SITENAME}}}}",
     "noemailtitle": "Адрас электроннай пошты адсутнічае",
     "noemailtext": "Гэты удзельнік не пазначыў слушны адрас электроннай пошты.",
-    "nowikiemailtitle": "Атрыманьне лістоў па электроннай пошце забароненае",
     "nowikiemailtext": "Гэты ўдзельнік не дазволіў атрымліваць лісты па электроннай пошце ад іншых удзельнікаў.",
     "emailnotarget": "Неіснуючае ці няслушнае імя атрымальніка.",
     "emailtarget": "Увядзіце імя атрымальніка",
     "watching": "Дадаецца ў сьпіс назіраньня…",
     "unwatching": "Выдаляецца са сьпісу назіраньня…",
     "watcherrortext": "Узьнікла памылка падчас зьмены Вашага сьпісу назіраньня для «$1».",
-    "enotif_mailer": "Служба паштовага апавяшчэньня {{GRAMMAR:родны|{{SITENAME}}}}",
     "enotif_reset": "Пазначыць усе старонкі як прагледжаныя",
     "enotif_impersonal_salutation": "Удзельнік {{GRAMMAR:родны|{{SITENAME}}}}",
     "enotif_subject_deleted": "Старонка {{GRAMMAR:родны|{{SITENAME}}}} «$1» была выдаленая {{GENDER:$2|удзельнікам|удзельніцай}} $2",
     "excontent": "колішні зьмест: «$1»",
     "excontentauthor": "зьмест быў: «$1» (і адзіным аўтарам быў '[[Special:Contributions/$2|$2]]')",
     "exbeforeblank": "зьмест да ачысткі: «$1»",
-    "exblank": "старонка была пустая",
     "delete-confirm": "Выдаліць «$1»",
     "delete-legend": "Выдаліць",
     "historywarning": "'''Папярэджаньне''': старонка, якую Вы зьбіраецеся выдаліць, мае гісторыю з прыкладна $1 {{PLURAL:$1|вэрсіі|вэрсіяў|вэрсіяў}}:",
     "importunknownsource": "Невядомы тып крыніцы імпарту",
     "importcantopen": "Немагчыма адкрыць файл імпарту",
     "importbadinterwiki": "Няслушная спасылка на іншую моўную вэрсію",
-    "importnotext": "Тэкст адсутнічае",
     "importsuccess": "Імпартаваньне скончанае!",
-    "importhistoryconflict": "Канфлікт вэрсіяў у гісторыі рэдагаваньняў (магчыма, гэтую старонку імпартавалі раней)",
     "importnosources": "Крыніцы імпарту паміж вікі не былі вызначаныя і наўпроставая загрузка гісторыі адключаная.",
     "importnofile": "Файл для імпартаваньня ня быў загружаны.",
     "importuploaderrorsize": "Не атрымалася загрузіць файл імпартаваньня.\nПамер файла болей за дазволены для загрузкі.",
index 559be8c..5f81c89 100644 (file)
     "prefs-skin": "Gwiskadur",
     "skin-preview": "Rakwelet",
     "datedefault": "Dre ziouer",
-    "prefs-datetime": "Deiziad hag eur",
     "prefs-labs": "Perzhioù \"labs\"",
     "prefs-user-pages": "Pajennoù implijer",
     "prefs-personal": "Titouroù personel",
index 38c410e..8fdc6c2 100644 (file)
     "prefs-skin": "Koža",
     "skin-preview": "Pregled",
     "datedefault": "Nije bitno",
-    "prefs-datetime": "Datum i vrijeme",
     "prefs-labs": "Eksperimentalne mogućnosti",
     "prefs-user-pages": "Korisničke stranice",
     "prefs-personal": "Korisnički podaci",
index e283545..dfb50e7 100644 (file)
     "permalink": "Enllaç permanent",
     "print": "Imprimir",
     "view": "Mostra",
+    "view-foreign": "Mostra en $1",
     "edit": "Modifica",
+    "edit-local": "Modifica la descripció local",
     "create": "Crea",
+    "create-local": "Afegeix una descripció local",
     "editthispage": "Modifica la pàgina",
     "create-this-page": "Crea aquesta pàgina",
     "delete": "Elimina",
     "protectedpagetext": "S'ha protegit la pàgina per evitar-hi modificacions.",
     "viewsourcetext": "Podeu visualitzar i copiar el codi font d’aquesta pàgina:",
     "viewyourtext": "Vostè pot veure i copiar la font de ' ' les modificacions ' ' d'aquesta pàgina:",
-    "protectedinterface": "Aquesta pàgina proporciona el text de la interfície del software d'aquest wiki i està protegida per evitar els abusos.\nPer agregar o canviar les traduccions per a tots els wikis, si us plau fes servir [//translatewiki.net/ translatewiki.net], el projecte de localització de MediaWiki.",
+    "protectedinterface": "Aquesta pàgina proporciona el text de la interfície del software d'aquest wiki i està protegida per evitar els abusos.\nPer afegir o canviar les traduccions per a tots els wikis, feu servir [//translatewiki.net/ translatewiki.net], el projecte de localització de MediaWiki.",
     "editinginterface": "'''Avís:''' Esteu editant una pàgina que conté cadenes de text per a la interfície d'aquest programari. Tingueu en compte que els canvis que es fan a aquesta pàgina afecten a l'aparença de la interfície d'altres usuaris. Per afegir o modificar traduccions a totes les wikis, plantegeu-vos utilitzar la [//translatewiki.net/ translatewiki.net], el projecte de localització de MediaWiki.",
     "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'''.",
     "revdelete-show-file-confirm": "Esteu segurs que voleu veure una revisió esborrada del fitxer «<nowiki>$1</nowiki>» de $2 a $3?",
     "revdelete-show-file-submit": "Sí",
     "revdelete-selected-text": "{{PLURAL:$1|Versió seleccionada|Versions seleccionades}} de [[:$2]]:",
+    "revdelete-selected-file": "{{PLURAL:$1|Versió seleccionada|Versions seleccionades}} del fitxer [[:$2]]:",
     "logdelete-selected": "{{PLURAL:$1|Esdeveniment del registre seleccionat|Esdeveniments del registre seleccionats}}:",
     "revdelete-text-text": "Les versions suprimides encara apareixeran en la pàgina d'historial, però part del seu contingut serà inaccessible al públic.",
     "revdelete-text-file": "Les versions suprimides encara apareixeran en l'historial del fitxer, però part del seu contingut serà inaccessible al públic.",
     "logdelete-text": "Els esdeveniments suprimits encara apareixeran en els registres, però part del seu contingut serà inaccessible al públic.",
+    "revdelete-text-others": "Altres administradors del projecte {{SITENAME}} podran accedir al contingut ocult i podran restaurar-lo amb aquesta mateixa interfície, llevat que s'estableixin restriccions addicionals.",
     "revdelete-confirm": "Si us plau, confirmeu que és això el que desitgeu fer, que enteneu les conseqüències, i que esteu fent-ho d'acord amb [[{{MediaWiki:Policy-url}}|les polítiques acordades]].",
     "revdelete-suppress-text": "Les supressions '''només''' han de ser portades a terme en els següents casos:\n* Informació potencialment difamatòria\n* Informació personal inapropiada\n*: ''adreces personals, números de telèfon, números d'identificació nacional, etc.''",
     "revdelete-legend": "Defineix restriccions en la visibilitat",
     "prefs-skin": "Aparença",
     "skin-preview": "prova",
     "datedefault": "Cap preferència",
-    "prefs-datetime": "Data i hora",
     "prefs-labs": "Característiques de laboratori",
     "prefs-user-pages": "Pàgines d'usuari",
     "prefs-personal": "Perfil d'usuari",
     "unwatchedpages": "Pàgines desateses",
     "listredirects": "Llista de redireccions",
     "listduplicatedfiles": "Llista de fitxers amb duplicats",
+    "listduplicatedfiles-summary": "Aquesta és una llista de fitxers on la darrera versió és un duplicat de la darrera versió d'algun altre fitxer. Es consideren només els fitxers locals.",
     "listduplicatedfiles-entry": "[[:File:$1|$1]] té [[$3|{{PLURAL:$2|un duplicat|$2 duplicats}}]].",
     "unusedtemplates": "Plantilles no utilitzades",
     "unusedtemplatestext": "Aquesta pàgina mostra les pàgines en l'espai de noms {{ns:template}}, que no estan incloses en cap altra pàgina. Recordeu de comprovar les pàgines que hi enllacen abans d'esborrar-les.",
     "listgrouprights-removegroup-self": "Abandona {{PLURAL:$2|el grup|els grups:}} $1",
     "listgrouprights-addgroup-self-all": "Afegir-se a qualsevol grup",
     "listgrouprights-removegroup-self-all": "Abandona tots els grups",
+    "listgrouprights-namespaceprotection-header": "Restriccions dels espais de noms",
+    "listgrouprights-namespaceprotection-namespace": "Espai de noms",
+    "listgrouprights-namespaceprotection-restrictedto": "Permisos que permeten modificar a l'usuari",
     "trackingcategories": "Categories de seguiment",
     "trackingcategories-summary": "Aquesta pàgina llista les categories de seguiment que s'omplen automàticament pel programari MediaWiki. Es poden canviar els seus noms modificant els missatges del sistema corresponents en l'espai de noms {{ns:8}}.",
     "trackingcategories-msg": "Categoria de seguiment",
     "unwatchthispage": "Desatén",
     "notanarticle": "No és una pàgina amb contingut",
     "notvisiblerev": "S'ha suprimit la versió",
-    "watchlist-details": "Teniu $1 {{PLURAL:$1|pàgina vigilada|pàgines vigilades}}, sense comptar les pàgines de discussió.",
+    "watchlist-details": "Teniu $1 {{PLURAL:$1|pàgina|pàgines}} a la llista de seguiment, sense comptar les pàgines de discussió.",
     "wlheader-enotif": "La notificació per correu electrònic està habilitada.",
     "wlheader-showupdated": "Les pàgines que s'han canviat des de la vostra darrera visita es mostren en '''negreta'''.",
     "watchmethod-recent": "s'està comprovant si hi ha pàgines vigilades en les edicions recents",
     "contributions-title": "Contribucions de l'usuari $1",
     "mycontris": "Contribucions",
     "contribsub2": "Per a {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "El compte d'usuari «$1» no està registrat.",
     "nocontribs": "No s'ha trobat canvis que encaixessin amb aquests criteris.",
     "uctop": "(actual)",
     "month": "Mes (i anteriors):",
index a512613..24de11f 100644 (file)
     "hidden-categories": "{{PLURAL:$1|1=Къайлаха категори|Къайлаха йолу категореш}}",
     "hidden-category-category": "Къайлаха йолу категореш",
     "category-subcat-count": "{{PLURAL:$2|ХӀокху категори чохь ю хӀокхуьнан бухара категори.|ХӀокху категори чохь ю $1 {{PLURAL:$1|бухара категори|бухара категореш}} $2 массо нах.}}",
-    "category-subcat-count-limited": "Хlокх категори чохь {{PLURAL:$1|$1 бухар категори|$1 бухар категореш|$1 бухар категореша}}.",
+    "category-subcat-count-limited": "ХӀокх категори чохь {{PLURAL:$1|бухар категори|$1 бухар категореш}} ю.",
     "category-article-count": "{{PLURAL:$2|ХӀокху категори чохь яц цхьа агӀо бе.|{{PLURAL:$1|Гойту $1 агӀо|Гойту $1 агӀонаш}} хӀокху категорешца кху $2.}}",
     "category-article-count-limited": "ХӀокху категори чохь {{PLURAL:$1|$1 агӀо|$1 агӀонаш}} цхьа агӀо бен яц.",
     "category-file-count": "{{PLURAL:$2|ХӀокху категори чохь цхьа файл бе яц.|{{PLURAL:$1|Гойту $1 файл|Гойту $1 файлаш}} хӀокху категорешца кху $2.}}",
     "permalink": "Даиман йолу хьажораг",
     "print": "Зорба тоха",
     "view": "Хьажа",
+    "view-foreign": "Сайтехь $1 хьажа",
     "edit": "Нисъе",
+    "edit-local": "ТӀетоха локальни цуьнах лаьцна",
     "create": "Кхолла",
+    "create-local": "ТӀетоха локальни цуьнах лаьцна",
     "editthispage": "Нисъе хӀъара агӀо",
     "create-this-page": "Кхолла хlара агlо",
     "delete": "ДӀаяккха",
     "deletethispage": "ДӀаяккха хӀара агӀо",
     "undeletethispage": "ХӀара агӀо меттахӀоттор",
-    "undelete_short": "МеттахӀоттайé $1 {{PLURAL:$1|1=нисйинарг|нисйинарш}}",
+    "undelete_short": "МеттахӀоттайé $1 {{PLURAL:$1|нисйинарг|нисйинарш}}",
     "viewdeleted_short": "Хьажар {{PLURAL:$1|$1 дlадаьккхина нийсдар|$1 дlадаьхна нийсдарш|$1 дlадаьхна нийсдарш}}",
     "protect": "Гlаролла дé",
     "protect_change": "хийца",
     "pool-timeout": "Блоктоха еза хан тӀех йаьлла",
     "pool-queuefull": "Дехаршан чоь юьззина ю",
     "pool-errorunknown": "Дойзаш доцу гlалат",
+    "pool-servererror": "Пулан ларар тӀекхочучехь дац ($1).",
     "aboutsite": "{{grammar:genitive|{{SITENAME}}}} лаьцна",
     "aboutpage": "Project:Цуьнах лаьцна",
     "copyright": "Чулацам лело мега $1 лицензица (кхениг билгалйина яцахь).",
     "password-login-forbidden": "Иштта декъашхочун цӀе а пароль а лелаян цамаго.",
     "mailmypassword": "Пароль кхоссар",
     "passwordremindertitle": "Декъашхочун {{grammar:genitive|{{SITENAME}}}}  пароль дагайаийтар",
+    "passwordremindertext": "Цхьам (ахь хила мега IP-адрес $1 тӀера) керла пароль кхоллар дехна {{grammar:genitive|{{SITENAME}}}} ($4) чохь. Декъашхочун $2\nкхоьллина керла хана пароль: $3. Иза дехар ахь динехь,\nсистемин чугӀой хийца пароль.\nХьан керла пароль белх беш хира ю $5 {{PLURAL:$5|дийнахь}}.\n\nХьой дехар дийна дацахь хӀума маде Ӏад бита хӀара хаам.",
     "noemail": "ЦӀе $1 йолу декъашхочун электронан адрес яздина дац.",
     "noemailcreate": "Ахьа нийса электронан почтан адрес дӀаяздан деза",
     "passwordsent": "Керла пароль декъашхочун $1 электронан адрес тӀе дӀахьажина. Дехар до, керла пароль еъча юху системин чугӀо.",
     "eauthentsent": "ДӀаяздинчу электронан адрес тӀе хаам баийтина.\nДаиман хаамаш баийта хааман чохь де бохург дан деза адрес хьай хилар бакъдеш.",
     "throttled-mailpassword": "Пароль дага йоуьйту функци {{PLURAL:$1|тӀехьара $1 сахьтехь}} лелина.\nЗулам цахилийта $1 {{PLURAL:$1|сахьтан чохь}} цӀа бен функци лело йиш яц.",
     "mailerror": "Кехат дохьуьйтуш гӀалат ду: $1",
+    "acct_creation_throttle_hit": "Де-буьйса хена чохь хьа IP-адрес тӀера {{PLURAL:$1|кхоьллина $1 декъашхочун дӀаяздар|кхоьллина $1 декъашхочун дӀаяздарш}} оьцу хана юкъахь кхин дукха дӀаяздарш кхолла магийна дац.\nЦундела и IP-адрес лелочарна кхин керла дӀаяздарш кхолла цало.",
     "emailauthenticated": "Хьан электронан почтан адрес бакъдина $2 $3.",
     "emailnotauthenticated": "Хьан электронан почтан адрес хӀинца а бакъдина дац.\nХаамаш кхоьхьуьйтура бац.",
+    "noemailprefs": "Электронан почтан адрес яздина дац, эл. почтан белхан функцеш дӀаяйина ю.",
     "emailconfirmlink": "Бакъде хьай электронан почтан адрес",
+    "invalidemailaddress": "Электронан почтан адрес тӀелаца йиш яц, цуна формат нийса цахилар бахьнехь.\nДехар до, язъе нийса электронан адрес я и меттиг есса йита.",
+    "cannotchangeemail": "ХӀокху декъашхочун дӀаяздарца долу электронан почтан адресаш хуьйцийла дац хӀокху вики чохь",
     "emaildisabled": "ХӀокху сайтан таро яц электронан почте хаамаш бахьийта.",
     "accountcreated": "Декъашхочун дӀаяздар кхоьллина",
     "accountcreatedtext": "Кхоьллина декъашхочун [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|дийцаре.]]) дӀаяздар.",
     "search-error": "Лохуш гӀалат даьлла: $1",
     "preferences": "Гlирс нисбан",
     "mypreferences": "ГӀирс нисбан",
-    "prefs-edits": "Нисдарши дукхалла:",
+    "prefs-edits": "Нисдарийн дукхалла:",
     "prefsnologintext2": "Оьшу $1, гӀирс дӀанисбан.",
     "prefs-skin": "Кечяран тема",
     "skin-preview": "Хьалха муха ю хьажа",
     "datedefault": "Iад йитарца",
-    "prefs-datetime": "Терахь а хан а",
     "prefs-labs": "Муха ю хьажарна таронаш",
     "prefs-user-pages": "Декъашхочун агӀо",
     "prefs-personal": "Долахь болу хаамаш",
     "listgrouprights-removegroup": "{{PLURAL:$2|тобан чура дӀабаха|тобанаш чура дӀабаха}} ло: $1",
     "listgrouprights-addgroup-all": "массо тобанийн юкъатоха йиш ю",
     "listgrouprights-removegroup-all": "тобан чура дӀабаха ло",
+    "listgrouprights-namespaceprotection-header": "ЦӀеран анан бехкам",
+    "listgrouprights-namespaceprotection-namespace": "ЦӀерийн ана",
+    "listgrouprights-namespaceprotection-restrictedto": "Декъашхочун хийцамаш бан таро хуьлуьйту бакъонаш",
+    "trackingcategories-msg": "Категореш зер",
+    "expensive-parserfunction-category-desc": "АгӀорахь тӀех дуккха ресурсийн функцеш лелош ю (<code>#ifexist</code> саниш). Мадарра ду — [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit] агӀонгахь.",
     "mailnologintext": "Электронан кехаташ кхехьийта йиш хилийта [[Special:UserLogin|системин чугӀо]] кхин декъашхошка хаамаш кхехьийта хьа [[Special:Preferences|гӀирса чохь]] бакъалла долу электронан почтан адрес хила деза.",
     "emailuser": "Декъашхочун хааман кехат",
     "emailuser-title-target": "Декъашхочунга кехат яздар",
     "unwatchthispage": "ДӀадаккха терго яр",
     "notanarticle": "Бац яззам",
     "notvisiblerev": "Верси дӀаяьккхина хила",
-    "watchlist-details": "Ð¥Ñ\8cан Ñ\82еÑ\80гаме Ð¼Ð¾Ð³Ó\80амÑ\86а $1 {{PLURAL:$1|агÓ\80о|агонаÑ\88}} Ñ\8e, Ð´Ð¸Ð¹Ñ\86аÑ\80е Ð°Ð³Ó\80онаÑ\88а йоцуш.",
+    "watchlist-details": "Ð¥Ñ\8cан Ñ\82еÑ\80гаме Ð¼Ð¾Ð³Ó\80анÑ\86а $1 {{PLURAL:$1|агÓ\80о}} Ñ\8e, Ð´Ð¸Ð¹Ñ\86аÑ\80е Ð°Ð³Ó\80онаÑ\88 йоцуш.",
     "wlheader-enotif": "Электронан почте хаамаш байтар латина ду.",
     "wlheader-showupdated": "Хийцам бина агӀонаш '''Ӏаьржа''' шрифтцан билгальяха ю.",
     "watchlistcontains": "Хьан тергаме могӀам чохь ю $1 {{PLURAL:$1|агӀо|агӀонаш}}.",
     "revertpage": "Нисдарш [[Special:Contributions/$2|$2]] ([[User talk:$2|дийцаре]]) юха даьхна башхаллийн [[User:$1|$1]]",
     "revertpage-nouser": "Нисдарш (декъашхочун цӀе хьулйина) юхадаьхина башхаллин {{GENDER:$1|[[User:$1|$1]]}}",
     "rollback-success": "Юхадаьхна $1; нисдарш, $2 версен.",
+    "sessionfailure-title": "Сеансан гӀалат",
+    "sessionfailure": "Карара белхан сеансан гӀалат деллачух тера ду;\nиза дешдерг сацийна «сеанс долаерзийтта».\nДехар до, тӀетаӀе «ЮхугӀо» кнопка, кхин агӀо карлаяккха.",
     "protectlogpage": "Гlаролли тептар",
     "protectlogtext": "Лахахь гойту агӀона гӀоралла дарна бина хийцамаш чохь болу тептар.\nХьа кхин йиш ю [[Special:ProtectedPages|хӀинца гӀоралла дина йолу агӀонийн могӀаме хьажа]].",
     "protectedarticle": "гlаролла дина агlо «[[$1]]»",
     "unprotectedarticle": "ГӀоролла дӀадаьстина «[[$1]]»",
     "movedarticleprotection": "«[[$2]]» агӀона тӀера гӀаролла «[[$1]]» агӀона тӀе даьккхина",
     "protect-title": "Оцунна «$1» гӀоралла дар",
-    "prot_1movedto2": "«[[$1]]» цӀе хийцина оцу «[[$2]]»",
+    "prot_1movedto2": "«[[$1]]» цӀе хийцина  «[[$2]]»",
     "protect-legend": "Бакъде гӀоралла дар",
     "protectcomment": "Бахьна:",
     "protectexpiry": "Чекхйолу:",
     "movepagetalktext": "ТӀе хӀоьттина йолу дийцаре агӀо ишта цӀе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''\n\n*Йаьсса йоцу дийцаре агӀо йолуш ю оцу цӀарца йа\n*Ахьа къастаман харжам цабиняхь а къастам хӀотточехь.\n\nИшта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хӀоттайар, нагахь иза хьашт йалахь.",
     "movearticle": "Цle хийца хlокху агlон",
     "moveuserpage-warning": "'''Тергам бе.''' Хьо декъашхочун агӀона цӀе хийца гӀерта. Дехар до, тергам бе, декъашхочун агӀона цӀе бен хийца лур яц, декъашхочун дӀаяздаран цӀе хийца лур яц.",
+    "movenologintext": "АгӀона цӀе хийца [[Special:UserLogin|системин чугӀо]].",
+    "movenotallowed": "Хьан бакъо яц керла агӀонаш кхолла.",
+    "movenotallowedfile": "Хьан файлийн цӀераш хийца бакъо яц.",
+    "cant-move-user-page": "Хьан бакъо яц декъашхойн коьрта агӀонийн цӀераш хийца.",
+    "cant-move-to-user-page": "Хьан бакъо яц агӀона цӀе декъашхочун агӀон тӀе хийца (бухара агӀон тӀе хийца мега).",
     "newtitle": "Керла цlе",
     "move-watch": "Латайé хӀара агӀо тергаме могӀанан юкъахь",
     "movepagebtn": "АгӀон цӀе хийца",
     "imported-log-entries": "{{PLURAL:$1|Тептар чура импорт дина $1 дӀаяздар|Тептар чура импорт дина $1 дӀаяздарш}}.",
     "importfailed": "Импорт ян цаелира: $1",
     "importnosources": "Юкъаравики-импортан хьост хаьржина яцара, дуьхьала хийцамашан истори чуяккхар дӀадайина ду.",
+    "import-noarticle": "Импорт ян агӀонаш яц!",
+    "xml-error-string": "$1 $2 могӀан чохь, позицеш $3 (байт $4): $5",
+    "import-upload": "Чуяха XML-хаамаш",
+    "import-token-mismatch": "Сеансан хаамаш дӀадайна. Дехар до, юху гӀорта.",
+    "import-invalid-interwiki": "Билгалйина вики чура импорт ян йиш яц.",
     "import-error-special": "«$1» агӀо импорт йина яц, и къастина цӀерийн меттигашан юкъайогӀуш хиларна.",
     "importlogpage": "Импортан тептар",
     "importlogpagetext": "Куьйгалхоша агӀонаш импорт яр царна бина хийцамашца кхечу википедеш чура.",
     "tooltip-ca-nstab-image": "Хlуман агlо",
     "tooltip-ca-nstab-mediawiki": "Хааман агlо MediaWiki",
     "tooltip-ca-nstab-template": "Куцкепа агlо",
+    "tooltip-ca-nstab-help": "ГӀоьна агӀо",
     "tooltip-ca-nstab-category": "Категорешан агӀо",
     "tooltip-minoredit": "Къастам бé хlокху хийцамна кlеззиг боуш санна",
     "tooltip-save": "Хьан хийцамаш lалашбой",
     "tooltip-diff": "Гайта долуш долу йозанах бина болу хийцам.",
     "tooltip-compareselectedversions": "Хlокху шина хаьржина агlона башхо муха ю хьажа.",
     "tooltip-watch": "ТӀетоха хӀара агӀо сан тергаме могӀанан юкъа",
+    "tooltip-watchlistedit-normal-submit": "Билгалйина цӀераш дӀаяха",
     "tooltip-watchlistedit-raw-submit": "Тергаме могӀам карлабаккха",
+    "tooltip-recreate": "АгӀо дӀаяьккхина хиларе ца хьоьжуш меттахӀоттае агӀо",
     "tooltip-upload": "Доладе чуяккхар",
     "tooltip-rollback": "Цхьоз тlетаlийча дlабаккха кхечо бина болу тlаьххьара хийцам",
     "tooltip-undo": "ДӀабаккха бина болу хийцам а хьалхьажар гойтуш, дӀаяккхарна бахьна гайта аьтту беш",
+    "tooltip-preferences-save": "ГӀирс нисбар Ӏалашде",
     "tooltip-summary": "Язъе йоца цӀе",
     "common.css": "/** Чуйиллина йолу кхузе CSS хир ю лелош масхьа кечйечу чохь */",
     "monobook.css": "/* Чуйиллина йолу кхузе CSS хир ю лелош масхьа Monobook чохь */",
     "spamprotectiontitle": "Совбиларна литтар",
     "spamprotectiontext": "Хьо дӀаязъян гӀерта агӀо спам-литтаро дӀакъоьвлина.\nЦуна бахьна хила там бу агӀона чохь зулам литтаран чутоьхна йолу хьажораг хилар.",
     "spambot_username": "Спам дӀацӀаняр",
+    "pageinfo-title": "Хаамаш цу «$1»",
+    "pageinfo-not-current": "Шира версийн оьцу хааме хьажа таро яц.",
     "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-views": "Хьажаран дукхалла",
     "pageinfo-watchers": "Хьоьжучера дукхалла",
     "pageinfo-few-watchers": "{{PLURAL:$1|ТӀаьхьадогӀучерал}} $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-magic-words": "{{PLURAL:$1|Бозбуунчаллин дош|Бозбуунчаллин дешнаш}} ($1)",
+    "pageinfo-hidden-categories": "{{PLURAL:$1|Къайла категори|Къайла категореш}} ($1)",
+    "pageinfo-templates": "{{PLURAL:$1|1=Кеп|Кепаш}} ($1)",
+    "pageinfo-transclusions": "{{PLURAL:$1|1=Юкъатохало агӀо|Юкъатохало агӀонаш}} ($1)",
     "pageinfo-toolboxlink": "Агlонах болу бовзам",
     "pageinfo-redirectsto": "ДӀасахьажорг",
     "pageinfo-redirectsto-info": "Хаам",
     "pageinfo-protect-cascading-yes": "ХӀаъ",
     "pageinfo-protect-cascading-from": "Чахчарин гӀоралла тӀера",
     "pageinfo-category-info": "Категорех лаьцна хаам",
+    "pageinfo-category-pages": "АгӀонийн дукхалла",
+    "pageinfo-category-subcats": "Бухара категорийн дукхалла",
+    "pageinfo-category-files": "Файлийн дукхалла",
     "skinname-cologneblue": "Кёльнин сингаттам",
     "skinname-modern": "Кхузаманан",
     "skinname-vector": "Векторни",
+    "markaspatrolleddiff": "Билгалйе теллина санна",
     "markaspatrolledtext": "Билгала йе хӀара агӀо хьаьжна сана",
+    "markedaspatrolled": "ДӀадахка теллина санна хилар",
+    "markedaspatrolledtext": "Хаьржина [[:$1]] агӀона верси къобалйина сана билгалйина.",
+    "rcpatroldisabled": "ТӀехьара бина хийцамаш къобалбан магийна дац",
+    "rcpatroldisabledtext": "ТӀехьара бина хийцамаш къобалбар хӀинца дӀадайина ду.",
+    "markedaspatrollederror": "теллина сана билгалъян цало",
     "markedaspatrollednotify": "АгӀо «$1» пайдане хилар билгалдина",
     "patrol-log-page": "ТӀехьажаран тептар",
     "patrol-log-header": "Хьажжина версеш йолу тептар.",
     "show-big-image-preview": "Барам хьажале: $1.",
     "show-big-image-other": "{{PLURAL:$2|1=Кхин шоралла|Кхин шоралла}}: $1.",
     "show-big-image-size": "$1 × $2 пиксель",
+    "file-info-gif-frames": "$1 {{PLURAL:$1|фрейм|фреймаш}}",
+    "file-info-png-repeat": "локху $1 {{PLURAL:$1|за}}",
+    "file-info-png-frames": "$1 {{PLURAL:$1|кадр|кадраш}}",
     "newimages": "Керлачу файлийн галерей",
     "newimages-summary": "ХӀокху белхан агӀона чохь гойтуш ю дукха хан йоццуш чуйаьхна файлаш.",
     "newimages-legend": "Литтар",
     "exif-colorspace": "Беснашан хьал",
     "exif-componentsconfiguration": "Бесара компонентин конфигураци",
     "exif-compressedbitsperpixel": "Бесан кIоргалла дацдина чул тӀехьа",
+    "exif-pixelydimension": "Суьртан шоралла",
     "exif-pixelxdimension": "Суьртан локхалла",
     "exif-datetimeoriginal": "Дуьххьарлера терахь а хан",
     "exif-datetimedigitized": "Оцифровк йина терахь а хан а",
     "table_pager_limit_submit": "Кхочушдé",
     "table_pager_empty": "Цакарийна",
     "autosumm-blank": "Агӏон чулацам дӏабяккхина",
-    "autosumm-replace": "АгӀона чуьраниг хийцина оцу «$1»",
+    "autosumm-replace": "АгӀона чуьраниг хийцина  «$1»",
     "autoredircomment": "ДӀасахьажийна цуна [[$1]] тӏе",
     "autosumm-new": "Керла агlо: «$1»",
     "livepreview-loading": "Чуйолуш…",
     "revdelete-unrestricted": "куьйгалхойн доза тохар дӀаяьккхина",
     "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 дӀасахьажоран тӀохул",
-    "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|цӀе хийцина|цӀе хийцина}} $3 оцу $4 дӀасахьажоран тӀохул а дӀасахьажийнарг цаюьтуш а",
+    "logentry-move-move_redir": "$1 {{GENDER:$2|цӀе хийцина}} $3 → $4 дӀасахьажоран тӀохул",
+    "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|цӀе хийцина}} $3 → $4 дӀасахьажоран тӀохул а дӀасахьажийнарг цаюьтуш а",
     "logentry-patrol-patrol-auto": "$1 автоматически {{GENDER:$2|хьаьжина}} $3 агӀона версега $4",
     "logentry-newusers-newusers": "{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1",
     "logentry-newusers-create": "{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1",
index 659b1d9..c72c3df 100644 (file)
     "login-throttled": "ژمارەیەکی زۆر هەوڵت داوە بۆ چوونە ژوورەوە.\nتکایە پێش هەوڵی دووبارە، نەختێک بوەستە.",
     "loginlanguagelabel": "زمان: $1",
     "pt-login": "بچۆ ژوورەوە",
+    "pt-login-button": "بچۆ ژوورەوە",
     "pt-createaccount": "ھەژمار دروست بکە",
     "pt-userlogout": "بچۆ دەرەوە",
     "changepassword": "تێپەڕوشە بگۆڕە",
     "prefs-skin": "پێستە",
     "skin-preview": "پێش بینین",
     "datedefault": "ھەڵنەبژێردراو",
-    "prefs-datetime": "کات و ڕێکەوت",
     "prefs-labs": "کەرەسەکانی تاقیگەکان",
     "prefs-user-pages": "پەڕە بەکارھێنەرییەکان",
     "prefs-personal": "پرۆفایلی بەکارھێنەر",
     "recentchangescount": "ژمارەی گۆڕانکارییەکان کە نیشان ئەدرێن لە حاڵەتی دیفاڵت:",
     "prefs-help-recentchangescount": "ئەمە دوایین گۆڕانکارییەکان، مێژووی پەڕەکان و لۆگەکانیش لەبەردەگرێت.",
     "savedprefs": "ھەڵبژاردەکانت پاشەکەوت کران",
-    "timezonelegend": "ناوچەکات:",
-    "localtime": "کاتی ناوچەیی:",
+    "timezonelegend": "ناوچەی کاتی:",
+    "localtime": "کاتی خۆماڵی:",
     "timezoneuseserverdefault": "دیفاڵتی ویکی بەکاربێنە ($1)",
     "timezoneuseoffset": "دیکە (ناتەواویەکان دیاری بکە)",
     "servertime": "کاتی ڕاژەکار:",
     "prefs-custom-js": "JSی دڵخواز",
     "prefs-common-css-js": "سی‌ئێس‌ئێس/جاڤاسکریپتی ھاوبەش بۆ گشت پێستەکان:",
     "prefs-reset-intro": "دەتوانی لەم لاپەڕە بۆ گەڕانەوەی هەڵبژاردەکانت بۆ بنچینەیی ماڵپەر کەڵک وەرگریت.\nگەر ئەوە بکەی ئیتر گۆڕانەکەت ناگەڕێتەوە.",
-    "prefs-emailconfirm-label": "پشتڕاست کردنەوەی ئیمەیل:",
+    "prefs-emailconfirm-label": "پشتڕاستکردنەوەی ئیمەیل:",
     "youremail": "ئیمەیل:",
     "username": "{{GENDER:$1|ناوی به‌کارھێنەر}}:",
     "uid": "پێناسەی {{GENDER:$1|به‌کارھێنەر}}:",
     "prefs-help-email-others": "ھەروەھا دەتوانی ھەڵبژێری کە بەکارھێنەرانی دیکە لە ڕێگەی پەڕەی بەکارھێنەرییەکەت یان لێدوانەکەت بێ ئاشکراکردنی کەسایەتیت پێوەندیت لەگەڵ بگرن.",
     "prefs-help-email-required": "ناونیشانی ئیمەیل پێویستە.",
     "prefs-info": "زانیاریی سەرەتایی",
-    "prefs-i18n": "نێونەتەویی کردن",
+    "prefs-i18n": "نێونەتەوییکردن",
     "prefs-signature": "واژوو",
     "prefs-dateformat": "ڕازاندنەوەی ڕێکەوت",
     "prefs-timeoffset": "قەرەبووکەری کات",
     "prefs-advancedediting": "ھەڵبژاردە گشتییەکان",
+    "prefs-editor": "دەستکاریکەر",
+    "prefs-preview": "پێشبینین",
     "prefs-advancedrc": "ھەڵبژاردەکانی پێشکەوتوو",
     "prefs-advancedrendering": "هەڵبژاردە پێشکەوتووەکان",
     "prefs-advancedsearchoptions": "هەڵبژاردە پێشکەوتووەکان",
     "prefs-displayrc": "ھەڵبژاردەکانی نیشاندان",
     "prefs-displaysearchoptions": "ھەڵبژاردەکانی نیشاندان",
     "prefs-displaywatchlist": "ھەڵبژاردەکانی نیشاندان",
+    "prefs-tokenwatchlist": "نیشانە",
     "prefs-diffs": "جیاوازییەکان",
     "email-address-validity-valid": "ناونیشانی ئیمەیل دروست وە بەر چاو دێت",
     "email-address-validity-invalid": "ناونیشانێکی دروستی ئیمەیل بنووسە",
     "action-userrights-interwiki": "دەستکاری مافەکانی بەکارهێنەریی بەکارهێنەران لە ویکی‌یەکانی دیکە‌دا",
     "action-siteadmin": "داخستن یا کردنەوەی بنکەدراو",
     "action-sendemail": "ناردنی ئیمەیلەکان",
+    "action-viewmywatchlist": "دیتنی پێرستی چاودێریت",
     "nchanges": "$1 {{PLURAL:$1|گۆڕانکاری}}",
     "recentchanges": "دوایین گۆڕانکارییەکان",
     "recentchanges-legend": "ھەڵبژاردەکانی دوایین گۆڕانکارییەکان",
     "listgrouprights-removegroup-self": "لابردنی {{PLURAL:$2|گرووپ|گرووپەکان}} لە سەر ھەژماری خۆی: $1",
     "listgrouprights-addgroup-self-all": "زیادکردنی ھەموو گرووپەکان بۆ سەر ھەژماری خۆی",
     "listgrouprights-removegroup-self-all": "لابردنی هەموو گرووپەکان له‌ سه‌ر هه‌ژماری خۆ",
+    "listgrouprights-namespaceprotection-namespace": "بۆشاییی ناو",
+    "trackingcategories-name": "ناوی پەیام",
     "mailnologin": "ناونیشان بۆ ناردن نییه‌",
     "mailnologintext": "ده‌بێ له‌ [[Special:UserLogin|ژووره‌وه‌]] بیت و ناونیشانێکی بڕواپێ‌کراوی ئی‌مه‌یلت له‌ ناو [[Special:Preferences|هه‌ڵبژارده‌کان]] دیاری کردبێت تا بتوانی ئی‌مه‌یل بنێریت بۆ به‌کارهێنه‌رانی دیکه‌.",
     "emailuser": "ئیمەیل بنێرە بۆ ئەم بەکارھێنەرە",
     "pageinfo-header-edits": "مێژووی دەستکاری",
     "pageinfo-header-restrictions": "پاراستنی پەڕە",
     "pageinfo-header-properties": "تایبەتمەندییەکانی پەڕە",
-    "pageinfo-display-title": "Ù\86اÙ\88Ù\86Û\8cشاÙ\86 Ù\86Û\8cشاÙ\86بدÛ\95",
+    "pageinfo-display-title": "Ù¾Û\8eشاÙ\86داÙ\86Û\8c Ø³Û\95ردÛ\8eÚ\95",
     "pageinfo-default-sort": "کلیلی ڕیزکردنی بەرگریمانە",
     "pageinfo-length": "قەبارەی پەڕە (بایت)",
     "pageinfo-article-id": "زنجیرەی پەڕە",
     "pageinfo-language": "زمانی ناوەرۆکی پەڕە",
+    "pageinfo-content-model": "شێوازی ناوەرۆکی پەڕە",
     "pageinfo-robot-policy": "پێرستکردن بە بۆتەکان",
     "pageinfo-robot-index": "ڕێ پێدراو",
     "pageinfo-robot-noindex": "ڕێ پێنەدراوه",
index 098cc5b..02374b0 100644 (file)
     "prefs-skin": "Resimleme",
     "skin-preview": "Baqıp çıquv",
     "datedefault": "Standart",
-    "prefs-datetime": "Tarih ve saat",
     "prefs-personal": "Qullanıcı malümatı",
     "prefs-rc": "Soñki deñiştirmeler",
     "prefs-watchlist": "Közetüv cedveli",
index a7484e2..37cfee2 100644 (file)
     "prefs-skin": "Vzhled",
     "skin-preview": "Náhled",
     "datedefault": "Implicitní",
-    "prefs-datetime": "Datum a čas",
     "prefs-labs": "Funkce z Labs",
     "prefs-user-pages": "Uživatelské stránky",
     "prefs-personal": "Údaje o uživateli",
     "enhancedrc-history": "historie",
     "recentchanges": "Poslední změny",
     "recentchanges-legend": "Možnosti posledních změn",
-    "recentchanges-summary": "Sledujte poslední změny {{grammar:2sg|{{SITENAME}}}} na této stránce.",
+    "recentchanges-summary": "Na této stránce sledujte poslední změny na {{grammar:6sg|{{SITENAME}}}}.",
     "recentchanges-noresult": "V daném období neodpovídaly zadaným kritériím žádné změny.",
     "recentchanges-feed-description": "Na tomto kanále sledujte poslední změny na {{grammar:6sg|{{SITENAME}}}}.",
     "recentchanges-label-newpage": "Touto editací byla založena nová stránka",
     "http-curl-error": "Chyba při čtení z URL: $1",
     "http-bad-status": "Při provádění HTTP požadavku nastal problém: $1 $2",
     "upload-curl-error6": "Z URL nelze číst",
-    "upload-curl-error6-text": "Ze zadané URL nelze číst. Zkontrolujte, zda je URL správně napsané a server je dostupný",
+    "upload-curl-error6-text": "Zadané URL není dostupné.\nZkontrolujte, zda je URL správné a server funguje.",
     "upload-curl-error28": "Čas pro nahrání vypršel",
-    "upload-curl-error28-text": "Server dlouho neodpovídá. Zkontrolujte, zda je dostupný, chvíli počkejte a zkuste to znovu.",
+    "upload-curl-error28-text": "Server dlouho neodpovídá.\nZkontrolujte, zda funguje, chvíli počkejte a zkuste to znovu.\nMožná to budete chtít zkusit v době menšího provozu.",
     "license": "Licence:",
     "license-header": "Licence",
     "nolicense": "Bez udání licence",
     "unwatchthispage": "Nesledovat tuto stránku",
     "notanarticle": "Toto není stránka",
     "notvisiblerev": "Verze byla smazána",
-    "watchlist-details": "Na vašem seznamu sledovaných stránek {{PLURAL:$1|je $1 stránka|jsou $1 stránky|je $1 stránek}}, nepočítají se diskusní stránky.",
+    "watchlist-details": "Na vašem seznamu sledovaných stránek {{PLURAL:$1|je $1 stránka|jsou $1 stránky|je $1 stránek}}, nepočítaje v to diskusní stránky.",
     "wlheader-enotif": "Upozorňování e-mailem je zapnuto.",
     "wlheader-showupdated": "Stránky, které se změnily od vaší poslední návštěvy, jsou zobrazeny '''tučně'''.",
     "watchmethod-recent": "hledají se sledované stránky mezi posledními změnami",
     "enotif_body_intro_restored": "V $PAGEEDITDATE {{gender:$2|obnovil|obnovila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, vizte aktuální verzi na $3 .",
     "enotif_body_intro_changed": "V $PAGEEDITDATE {{gender:$2|změnil|změnila}} $2 na {{grammar:6sg|{{SITENAME}}}} stránku $1, vizte aktuální verzi na $3 .",
     "enotif_lastvisited": "Vizte $1 pro seznam všech změn od minulé návštěvy.",
-    "enotif_lastdiff": "Tuto změnu vizte na $1 .",
+    "enotif_lastdiff": "Na $1 si tuto změnu můžete prohlédnout.",
     "enotif_anon_editor": "anonymní uživatel $1",
     "enotif_body": "Vážený uživateli $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nShrnutí editace: $PAGESUMMARY $PAGEMINOREDIT\n\nUživatele, který změnu provedl, můžete kontaktovat:\ne-mailem: $PAGEEDITOR_EMAIL\nna wiki: $PAGEEDITOR_WIKI\n\nDo doby, než stránku navštívíte jako přihlášený uživatel, vám další oznámení k této stránce nebudou zasílána. Případně si můžete vynulovat příznaky ve svém seznamu sledovaných stránek.\n\nS pozdravem váš zasílač hlášení {{grammar:2sg|{{SITENAME}}}}\n\n--\nZměnit nastavení e-mailových oznámení můžete na\n{{canonicalurl:{{#special:Preferences}}}}\n\nNastavení sledovaných stránek může změnit na\n{{canonicalurl:Special:Watchlist/edit}}\n\nStránku můžete ze svých sledovaných vyřadit na\n$UNWATCHURL\n\nRady a kontakt:\n{{canonicalurl:{{MediaWiki:Helppage}}}}",
     "created": "vytvořil",
     "undeleteviewlink": "prohlédnout",
     "undeleteinvert": "Invertovat výběr",
     "undeletecomment": "Důvod:",
-    "undeletedrevisions": "{{PLURAL:$1|Obnovena $1 verze|Obnoveny $1 verze|Obnoveno $1 verzí}}",
-    "undeletedrevisions-files": "{{PLURAL:$1|Obnovena jedna verze|Obnoveny $1 verze|Obnoveno $1 verzí}} a $2 {{PLURAL:$2|soubor|soubory|souborů}}.",
-    "undeletedfiles": "{{PLURAL:$1|obnoven $1 soubor|obnoveny $1 soubory|obnoveno $1 souborů}}",
+    "undeletedrevisions": "{{PLURAL:$1|Obnovena jedna verze|Obnoveny $1 verze|Obnoveno $1 verzí}}",
+    "undeletedrevisions-files": "{{PLURAL:$1|Obnovena jedna verze|Obnoveny $1 verze|Obnoveno $1 verzí}} a {{PLURAL:$2|jeden soubor|$2 soubory|$2 souborů}}.",
+    "undeletedfiles": "{{PLURAL:$1|Obnoven jeden soubor|Obnoveny $1 soubory|Obnoveno $1 souborů}}",
     "cannotundelete": "Obnovení se nezdařilo:\n$1",
     "undeletedpage": "'''$1 byla obnovena'''\n\nZáznam o posledních mazáních a obnoveních najdete v [[Special:Log/delete|knize smazaných stránek]].",
     "undelete-header": "Vizte nedávno smazané stránky v [[Special:Log/delete|knize smazaných stránek]].",
     "undelete-filename-mismatch": "Nelze obnovit verzi souboru s časovou značkou $1: jméno souboru neodpovídá",
     "undelete-bad-store-key": "Nelze obnovit verzi souboru s časovou značkou $1: soubor před smazáním chyběl.",
     "undelete-cleanup-error": "Chyba při mazání nepoužívaného archivního souboru „$1“.",
-    "undelete-missing-filearchive": "Nepodařilo se obnovit soubor archivu s identifikací $1 , protože není v databázi. Možná již byl obnoven.",
+    "undelete-missing-filearchive": "Nepodařilo se obnovit soubor archivu s identifikací $1, protože není v databázi. Možná již byl obnoven.",
     "undelete-error": "Chyba při obnovování stránky",
     "undelete-error-short": "Chyba při obnovování souboru: $1",
     "undelete-error-long": "Vyskytla se chyba při obnovování souboru:\n\n$1",
     "contributions-title": "Příspěvky uživatele $1",
     "mycontris": "Příspěvky",
     "contribsub2": "{{GENDER:$3|uživatele|uživatelky}} $1 ($2)",
+    "contributions-userdoesnotexist": "Uživatelský účet „$1“ není zaregistrován.",
     "nocontribs": "Nenalezeny žádné změny vyhovující kritériím.",
     "uctop": "(aktuální)",
     "month": "Do měsíce:",
     "unblockip": "Odblokovat uživatele",
     "unblockiptext": "Tímto formulářem je možno obnovit právo blokované IP adresy či uživatele opět přispívat do {{grammar:2sg|{{SITENAME}}}}.",
     "ipusubmit": "Odblokovat",
-    "unblocked": "{{GENDER:$1|||Uživatel}} [[User:$1|$1]] {{GENDER:$1|byl odblokován|byla odblokována|byl odblokován}}",
+    "unblocked": "{{GENDER:$1|||Uživatel}} [[User:$1|$1]] {{GENDER:$1|byl odblokován|byla odblokována|byl odblokován}}.",
     "unblocked-range": "$1 bylo odblokováno",
     "unblocked-id": "Blok $1 byl zrušen",
     "blocklist": "Zablokovaní uživatelé",
     "ipb-otherblocks-header": "{{PLURAL:$1|Jiné zablokování|Jiná zablokování}}",
     "unblock-hideuser": "Tohoto uživatele nemůžete odblokovat, protože jeho uživatelské jméno bylo skryto.",
     "ipb_cant_unblock": "Chyba: Blokování s ID $1 nebylo nalezeno. Uživatel již možná byl odblokován.",
-    "ipb_blocked_as_range": "Chyba: IP adresa $1 není blokována přímo a tak ji nelze odblokovat. Je částí zablokovaného rozsahu $2, který může být odblokován.",
+    "ipb_blocked_as_range": "Chyba: IP adresa $1 není blokována přímo, a tak ji nelze odblokovat. Je částí zablokovaného rozsahu $2, který může být odblokován.",
     "ip_range_invalid": "Neplatný IP rozsah.",
     "ip_range_toolarge": "Blokování rozsahů větších než /$1 není dovoleno.",
     "proxyblocker": "Blokování proxy serverů",
index 2aa2fc1..da1e5de 100644 (file)
     "prefs-skin": "Benutzeroberfläche",
     "skin-preview": "Vorschau",
     "datedefault": "Standard",
-    "prefs-datetime": "Datum und Zeit",
     "prefs-labs": "Alpha-Funktionen",
     "prefs-user-pages": "Benutzerseiten",
     "prefs-personal": "Benutzerdaten",
     "unwatchthispage": "Nicht mehr beobachten",
     "notanarticle": "Keine Seite",
     "notvisiblerev": "Version wurde gelöscht",
-    "watchlist-details": "Du beobachtest {{PLURAL:$1|eine Seite|$1 Seiten}}, ohne dass Diskussionsseiten gezählt werden.",
+    "watchlist-details": "Du beobachtest {{PLURAL:$1|eine Seite|$1 Seiten}}, ohne dass Diskussionsseiten getrennt gezählt werden.",
     "wlheader-enotif": "Der E-Mail-Benachrichtigungsdienst ist aktiviert.",
     "wlheader-showupdated": "Seiten mit noch nicht gesehenen Änderungen werden '''fett''' dargestellt.",
     "watchmethod-recent": "Überprüfen der letzten Bearbeitungen für die Beobachtungsliste",
     "contributions-title": "Benutzerbeiträge von „$1“",
     "mycontris": "Beiträge",
     "contribsub2": "Von {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "Das Benutzerkonto „$1“ ist nicht registriert.",
     "nocontribs": "Es wurden keine Benutzerbeiträge mit diesen Kriterien gefunden.",
     "uctop": "(aktuell)",
     "month": "und Monat:",
index c2f023b..e3bb913 100644 (file)
     "aboutpage": "Project:Heqa {{SITENAME}} de",
     "copyright": "Zerrekacı $1 bındı not biya.",
     "copyrightpage": "{{ns:project}}:Heqa telifi",
-    "currentevents": "Veng u vac",
+    "currentevents": "Veng û vac",
     "currentevents-url": "Project:Rocani hadisey",
     "disclaimers": "Redê mesuliyeti",
     "disclaimerpage": "Project:Reddê mesuliyetê bıngey",
     "cantcreateaccount-text": "Hesabvıraştışê na IP adrese ('''$1''') terefê [[User:$3|$3]] kılit biyo.\n\nSebebo ke terefê $3 ra diyao ''$2''",
     "viewpagelogs": "Heqa na pele de qeydan bıvêne",
     "nohistory": "Verê vurnayışanê na pele çıniyo.",
-    "currentrev": "Halo nıkayên",
+    "currentrev": "Çımraviyarnayışo rocane",
     "currentrev-asof": "Revizyonanê peniyan, tarixê $1",
     "revisionasof": "Verziyonê roca $1ine",
     "revision-info": "Vıraştena cı karber $2 ra rewizyona $1",
     "prefs-skin": "Çerme",
     "skin-preview": "Verasayış",
     "datedefault": "Tercih çıniyo",
-    "prefs-datetime": "Tarix u wext",
     "prefs-labs": "Xacetê labs",
     "prefs-user-pages": "Pela Karberi",
     "prefs-personal": "Pela karberi",
     "rightslogtext": "Ena listeyê loganê ke heqqa karbaranî mucneno.",
     "action-read": "ena pela wanayış",
     "action-edit": "ena pela bıvurnê",
-    "action-createpage": "pelan vıraze",
+    "action-createpage": "pelan vıraze",
     "action-createtalk": "pelanê werênayışi bıvıraze",
     "action-createaccount": "hesabê nê karberi bıvıraze",
     "action-minoredit": "nê vurnayışi be qıckek işaret ke",
     "sourceurl": "URLyê çımey:",
     "destfilename": "Destînasyonê nameyêdosya",
     "upload-maxfilesize": "Ebatêî dosya tewr girdî: $1",
-    "upload-description": "Deskripsiyonê dosyayî",
+    "upload-description": "Arezekerdışê dosya",
     "upload-options": "Tercihanê bar kerdişî",
     "watchthisupload": "Ena dosya seyr bike",
     "filewasdeleted": "no name de yew dosya yew wexto nızdi de bar biya u dıma zi serkaran hewn a kerdo. wexya ke şıma dosya bar keni bıewnê no pel $1.",
     "pageswithprop-submit": "Şo",
     "pageswithprop-prophidden-long": "Erca metinda derger nımneya ($1)",
     "pageswithprop-prophidden-binary": "Erca dıdıyına ($1) nımneyé",
-    "doubleredirects": "Hetenayışê dıletıni",
+    "doubleredirects": "Serşıkıtışê dıleti",
     "doubleredirectstext": "no pel pelê ray motışani liste keno.\ngıreyê her satıri de gıreyi; raş motışê yewın u dıyıni esto.\n<del>serê ey nuşteyi</del> safi biye.",
     "double-redirect-fixed-move": "[[$1]] kırışiya, hıni ray dana [[$2]] no pel",
     "double-redirect-fixed-maintenance": "raçarnayışo dıletê [[$1]] ra  pela da [[$2]] timarêno",
     "delete-legend": "Bestere",
     "historywarning": "'''Teme:''' Pela ke şıma esterenê tede yew viyarte be teqriben $1 {{PLURAL:$1|versiyon esto|versiyoni estê}}:",
     "confirmdeletetext": "Tı ho yew pele u tarixê pele wederneno.\nTı ra rica keno, tı zani tı ho sekeno, tı zani neticeyanê eno wedarnayışi u tı zani tı ser [[{{MediaWiki:Policy-url}}|poliçe]] kar keno.",
-    "actioncomplete": "Xebten temam biyo",
+    "actioncomplete": "Kar bi temam",
     "actionfailed": "kar nêbı",
     "deletedtext": "\"$1\" biya wedariya.\nQe qeydê wedarnayışi, $2 bevinin.",
     "dellogpage": "Qeydê esterniye",
index 6dec0ef..41c12b3 100644 (file)
     "contributions-title": "User contributions for $1",
     "mycontris": "Contributions",
     "contribsub2": "For {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "User account \"$1\" is not registered.",
     "nocontribs": "No changes were found matching these criteria.",
     "uctop": "(current)",
     "month": "From month (and earlier):",
index 7cf96e1..96d19a9 100644 (file)
     "prefs-skin": "Etoso",
     "skin-preview": "Antaŭrigardo",
     "datedefault": "Nenia prefero",
-    "prefs-datetime": "Dato kaj horo",
     "prefs-labs": "Ecoj el Laboratorio",
     "prefs-user-pages": "Uzantopaĝoj",
     "prefs-personal": "Uzanta profilo",
index 2715793..ef62a4b 100644 (file)
             "XalD",
             "XanaG",
             "לערי ריינהארט",
-            "Chocolate con galleta"
+            "Chocolate con galleta",
+            "Csbotero"
         ]
     },
     "tog-underline": "Subrayar los enlaces:",
     "prefs-skin": "Apariencia",
     "skin-preview": "Previsualizar",
     "datedefault": "Sin preferencia",
-    "prefs-datetime": "Fecha y hora",
     "prefs-labs": "Características de los laboratorios",
     "prefs-user-pages": "Páginas de usuario",
     "prefs-personal": "Perfil de usuario",
     "listgrouprights-removegroup-self": "Eliminar {{PLURAL:$2|grupo|grupos}} de tu propia cuenta: $1",
     "listgrouprights-addgroup-self-all": "Agregar todos los grupos a tu propia cuenta",
     "listgrouprights-removegroup-self-all": "Eliminar todos los grupos de tu propia cuenta",
+    "listgrouprights-namespaceprotection-header": "Restricciones del espacio de nombre",
+    "listgrouprights-namespaceprotection-namespace": "Espacio de nombre",
+    "listgrouprights-namespaceprotection-restrictedto": "Derechos de usuario para editar",
     "trackingcategories": "Categorías de seguimiento",
     "trackingcategories-msg": "Categoría de seguimiento",
     "trackingcategories-name": "Nombre del mensaje",
     "noindex-category-desc": "La página contiene la palabra mágica <code><nowiki>__NOINDEX__</nowiki></code> (y está en un espacio de nombres donde la función está activada); y por ello los robots no la indizan.",
     "post-expand-template-inclusion-category-desc": "Después de expandir todas las plantillas, el tamaño de la página es más grande que <code>$wgMaxArticleSize</code>, así que algunas plantillas no se expandieron.",
     "post-expand-template-argument-category-desc": "Después de expandir un argumento de plantilla (algunos en tres llaves, como <code>{{{Foo}}})</code>, la página es más grande que <code>$wgMaxArticleSize</code>.",
+    "hidden-category-category-desc": "Esta es una categoría con <code><nowiki>__HIDDENCAT__</nowiki></code> en ella, que evita que aparezca en el cuadro de enlace de la categoría en las páginas, de forma predeterminada.",
     "trackingcategories-nodesc": "No hay descripción disponible.",
     "trackingcategories-disabled": "La categoría está desactivada",
     "mailnologin": "Ninguna dirección de envio",
index 58b269b..6b895d6 100644 (file)
     "prefs-skin": "Kujundus",
     "skin-preview": "eelvaade",
     "datedefault": "Eelistus puudub",
-    "prefs-datetime": "Kuupäev ja kellaaeg",
     "prefs-labs": "Katsefunktsioonid",
     "prefs-user-pages": "Kasutajaleheküljed",
     "prefs-personal": "Kasutaja andmed",
     "listgrouprights-removegroup-self": "Eemaldada enda konto {{PLURAL:$2|rühmast|rühmadest}}: $1",
     "listgrouprights-addgroup-self-all": "Oma konto kõigisse rühmadesse lisada",
     "listgrouprights-removegroup-self-all": "Eemaldada ennast kõigist rühmadest",
+    "listgrouprights-namespaceprotection-header": "Nimeruumipiirangud",
+    "listgrouprights-namespaceprotection-namespace": "Nimeruum",
+    "listgrouprights-namespaceprotection-restrictedto": "Redigeerimiseks vajalikud õigused",
     "trackingcategories": "Süsteemikategooriad",
     "trackingcategories-summary": "Siin leheküljel on loetletud süsteemikategooriad, millesse MediaWiki tarkvara ise lehekülgi arvab. Nende kategooriate nimesid saab muuta, kui vahetada {{ns:8}}-nimeruumis vastavaid süsteemisõnumeid.",
     "trackingcategories-msg": "Süsteemikategooria",
     "unwatchthispage": "Ära jälgi",
     "notanarticle": "Pole artikkel",
     "notvisiblerev": "Redaktsioon on kustutatud",
-    "watchlist-details": "Jälgimisloendis on {{PLURAL:$1|$1 lehekülg|$1 lehekülge}} (ei arvestata arutelulehekülgi).",
+    "watchlist-details": "Jälgimisloendis on {{PLURAL:$1|üks lehekülg|$1 lehekülge}}. Arutelulehekülgi pole eraldi välja toodud.",
     "wlheader-enotif": "E-posti teel teavitamine on lubatud.",
     "wlheader-showupdated": "Leheküljed, mida on muudetud peale sinu viimast külastust, on '''rasvases kirjas'''.",
     "watchmethod-recent": "jälgitud lehekülgedel tehtud viimaste muudatuste läbivaatamine",
     "contributions-title": "Kasutaja $1 kaastöö",
     "mycontris": "Kaastöö",
     "contribsub2": "Kasutaja {{GENDER:$3|$1}} ($2) jaoks",
+    "contributions-userdoesnotexist": "Kasutajakonto \"$1\" pole registreeritud.",
     "nocontribs": "Antud kriteeriumitele vastavaid muudatusi ei leitud.",
     "uctop": "(praegune)",
     "month": "Alates kuust (ja varasemad):",
index 5b43754..b44678d 100644 (file)
     "prefs-skin": "Itxura",
     "skin-preview": "Aurrebista",
     "datedefault": "Hobespenik ez",
-    "prefs-datetime": "Data eta ordua",
     "prefs-labs": "Labs ezaugarriak",
     "prefs-user-pages": "Erabiltzaile orriak",
     "prefs-personal": "Erabiltzaile profila",
index 1949be9..0e52928 100644 (file)
     "resetpass-abort-generic": "تغییر گذرواژه به دست یکی از افزونه‌ها لغو شده است.",
     "resetpass-expired": "رمز عبور شما منقضی شده‌است. لطفاً برای ورود رمز عبور جدیدی را تنظیم کنید.",
     "resetpass-expired-soft": "رمز عبور شما منقضی شده‌است، و نیاز به تنظیم مجدد دارد. لطفاً اکنون رمز عبور جدیدی را انتخاب کنید، یا برای تنظیم مجدد آن بعدآً، دکمه \"{{int:resetpass-submit-cancel}}\" را کلیک کنید.",
+    "resetpass-validity-soft": "گذرواهٔ شما صحیح نیست: $1\n\nلطفاً یک گذرواژهٔ جدید الآن انتخاب کنید یا بر «{{int:resetpass-submit-cancel}}» کلیک کنید که دوباره آن را بعداً انتخاب کنید.",
     "passwordreset": "بازنشانی گذرواژه",
     "passwordreset-text-one": "برای بازنشانی گذرواژه‌تان این فرم را کامل کنید.",
     "passwordreset-text-many": "{{PLURAL:$1|برای دریافت یک گذرواژهٔ موقت از راه رایانامه، یکی از زمینه‌ها را پر کنید.}}",
     "revdelete-no-file": "پروندهٔ مشخص شده وجود ندارد.",
     "revdelete-show-file-confirm": "آیا مطمئن هستید که می‌خواهید یک نسخهٔ حذف شده از پروندهٔ «<nowiki>$1</nowiki>» مورخ $2 ساعت $3 را ببینید؟",
     "revdelete-show-file-submit": "بله",
+    "revdelete-selected-text": "{{PLURAL:$1|نسخهٔ انتخاب‌شده|نسخه‌های انتخابی}} [[:$2]]:",
+    "revdelete-selected-file": "{{PLURAL:$1|نسخهٔ انتخاب‌شدهٔ|نسخه‌های انتخابی}} [[:$2]]:",
     "logdelete-selected": "{{PLURAL:$1|مورد|موارد}} انتخاب شده از سیاهه:",
+    "revdelete-text-text": "نسخه‌های حذف‌شده همچنان در تارییخچه نمایان خواند بود ولی قسمت‌هایی از محتویات غبرقابل دسترس برای عموم خواهد بود.",
+    "revdelete-text-file": "نسخه‌های حذف‌شده همچنان در تاریخچهٔ پرونده نمایان خواهد بود ولی قسمت‌هایی از محتویات آن‌ها برای عموم غیرقابل دسترس خواهد بود.",
+    "logdelete-text": "نسخه‌های حذف‌شده همچنان در سیاهه‌های نمایان خواهد بود ولی قسمت‌هایی از محتویات آن‌ها غیرقابل دسترس برای عموم خواهد بود.",
     "revdelete-text-others": "سایر مدیران {{SITENAME}} هنوز می‌توانند این محتوای پنهان را ببینند و از همین طریق موارد حذف شده را احیا کنند، مگر آن که محدودیت‌های دیگری اعمال گردد.",
     "revdelete-confirm": "لطفاً تأیید کنید که می‌خواهید این کار را انجام دهید، عواقب آن را درک می‌کنید و این کار را طبق [[{{MediaWiki:Policy-url}}|سیاست‌ها]] انجام می‌دهید.",
     "revdelete-suppress-text": "فرونشانی باید '''تنها''' برای موارد زیر استفاده شود:\n* اطلاعات به طور بالقوه افتراآمیز\n* اطلاعات نامناسب شخصی\n*: ''نشانی منزل، شماره تلفن، کد ملی و غیره.''",
     "prefs-skin": "پوسته",
     "skin-preview": "پیش‌نمایش",
     "datedefault": "بدون ترجیح",
-    "prefs-datetime": "تاریخ و زمان",
     "prefs-labs": "گزینه‌های آزمایشی",
     "prefs-user-pages": "صفحه‌های کاربری",
     "prefs-personal": "داده‌های کاربر",
     "download": "دریافت",
     "unwatchedpages": "صفحه‌های پی‌گیری‌نشده",
     "listredirects": "فهرست صفحه‌های تغییرمسیر",
+    "listduplicatedfiles": "فهرست همهٔ پرونده‌ها به‌همراه تکراری‌ها",
+    "listduplicatedfiles-summary": "این فهرست پرونده‌هایی با نسخه‌های اخیر این پرونده تکراری است که نسخه‌های اخبر سایر پرونده‌ها است. فقط پرونده‌های محلی در نظر گرفته شده‌اند.",
+    "listduplicatedfiles-entry": "[[:File:$1|$1]][[$3|{{PLURAL:$2|یک تکرار|$2 تکرار}}]] دارد.",
     "unusedtemplates": "الگوهای استفاده‌نشده",
     "unusedtemplatestext": "این صفحه همهٔ صفحه‌هایی در فضای نام {{ns:template}} را که در هیچ صفحه‌ای به کار نرفته‌اند، فهرست می‌کند.\nبه یاد داشته باشید که پیش از پاک‌کردن این صفحه‌ها پیوندهای دیگر به آنها را هم وارسی کنید.",
     "unusedtemplateswlh": "پیوندهای دیگر",
     "listgrouprights-removegroup-self": "می‌تواند حساب خود را از این {{PLURAL:$2|گروه|گروه‌ها}} حذف کند: $1",
     "listgrouprights-addgroup-self-all": "می‌تواند حساب خود را به تمام گروه‌ها اضافه کند",
     "listgrouprights-removegroup-self-all": "می‌تواند حساب خود را از تمام گروه‌ها حذف کند",
+    "listgrouprights-namespaceprotection-header": "محدودیت فضای نام",
+    "listgrouprights-namespaceprotection-namespace": "فضای نام",
+    "listgrouprights-namespaceprotection-restrictedto": "دسترسی(های) مجاز کاربر برای ویرایش",
+    "trackingcategories": "رده‌های ردیابی",
+    "trackingcategories-summary": "این صفحه فهرست رده‌هایی ردیابی است که به‌صورت خودکار توسط مدیاویکی پر می‌شوند است. نام‌هایشان می‌تواند پس از تغییر پیام‌های سامانه‌ای مرتبط در فضای نام {{ns:8}} تغییر یابد.",
+    "trackingcategories-msg": "ردهٔ ردیابی",
+    "trackingcategories-name": "نام پیام",
+    "trackingcategories-desc": "معیارهای گنجایش رده",
+    "noindex-category-desc": "این صفحه توسط ربات‌ها فهرست‌نشده‌است به این دلیل که واژه جادویی <code><nowiki>__NOINDEX__</nowiki></code> در آن یا در فضای که پرچم مجاز است دارد.",
+    "index-category-desc": "این صفحه <code><nowiki>__INDEX__</nowiki></code> درونش دارد (و در فضای نامی است که پرچم مجاز است)، و به این دلیل توسط ربات مجاز است که به‌صورت عادی نباید می‌شد.",
+    "post-expand-template-inclusion-category-desc": "پس از گسترش همهٔ الگوها، حجم صفحه بزرگتر از <code>$wgMaxArticleSize</code> است بنابراین بعضی از الگو گسترش نیافته‌اند.",
+    "post-expand-template-argument-category-desc": "پس از گسترش یک آرگومان الگو (چیزی بین آکولادهای سه‌تایی، مانند <code>{{{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": "رده افزود می‌شود اگر صفحه شامل یک پیوند شکسته باشد (یا یک پبوند به پروندهٔ توکاری است که وجود ندارد)",
+    "hidden-category-category-desc": "این یک ردهٔ <code><nowiki>__HIDDENCAT__</nowiki></code> درونش است که از نمایشش در جعبهٔ پیوندهای رده به‌صورت پیش‌فرض جلوگیری می‌کند.",
+    "trackingcategories-nodesc": "توضیحی وجود ندارد.",
+    "trackingcategories-disabled": "رده غیرفعال‌شده است",
     "mailnologin": "نشانی‌ای از فرستنده موجود نیست",
     "mailnologintext": "برای فرستادن رایانامه به کاربران دیگر باید [[Special:UserLogin|به سامانه وارد شوید]] و نشانی رایانامهٔ معتبری در [[Special:Preferences|ترجیحات]] خود داشته باشید.",
     "emailuser": "فرستادن نامه به این کاربر",
     "unwatchthispage": "توقف پی‌گیری",
     "notanarticle": "صفحه محتوایی نیست",
     "notvisiblerev": "آخرین نسخه توسط کاربری دیگر حذف شده‌است",
-    "watchlist-details": "بدون احتساب صفحه‌های بحث، {{PLURAL:$1|$1 صفحه|$1 صفحه}} در فهرست پی‌گیری‌های شما قرار {{PLURAL:$1|دارد|دارند}}.",
+    "watchlist-details": "بدÙ\88Ù\86 Ø§Ø­ØªØ³Ø§Ø¨ ØµÙ\81Ø­Ù\87â\80\8cÙ\87اÛ\8c Ø¬Ø¯Ø§Ú¯Ø§Ù\86Ù\87Ù\94 Ø¨Ø­Ø«Ø\8c {{PLURAL:$1|$1 ØµÙ\81Ø­Ù\87|$1 ØµÙ\81Ø­Ù\87}} Ø¯Ø± Ù\81Ù\87رست Ù¾Û\8câ\80\8cÚ¯Û\8cرÛ\8câ\80\8cÙ\87اÛ\8c Ø´Ù\85ا Ù\82رار {{PLURAL:$1|دارد|دارÙ\86د}}.",
     "wlheader-enotif": "آگاه‌سازی رایانامه‌ای فعال است.",
     "wlheader-showupdated": "صفحه‌هایی که پس از آخرین بازدید شما تغییر کرده‌اند '''پررنگ''' نمایش داده شده‌اند.",
     "watchmethod-recent": "بررسی ویرایش‌های اخیر برای صفحه‌های مورد پی‌گیری",
     "protect-locked-blocked": "شما در مدتی که دسترسی‌تان قطع است نمی‌توانید سطح محافظت صفحه‌ها را تغییر دهید.\nتنظیمات فعلی صفحهٔ '''$1''' از این قرار است:",
     "protect-locked-dblock": "به دلیل قفل شدن پایگاه داده، امکان تغییر سطح محافظت صفحه وجود ندارد.\nتنظیمات فعلی صفحهٔ '''$1''' به این قرار است:",
     "protect-locked-access": "حساب کاربری شما اجازهٔ تغییر سطح محافظت صفحه را ندارد.\nتنظیمات فعلی صفحهٔ '''$1''' به این قرار است:",
-    "protect-cascadeon": "اÛ\8cÙ\86 ØµÙ\81Ø­Ù\87  Ø¯Ø± Ø­Ø§Ù\84 Ø­Ø§Ø¶Ø± Ù\85حاÙ\81ظت Ø´Ø¯Ù\87â\80\8cاست Ø²Û\8cرا Ø¯Ø± {{PLURAL:$1|صÙ\81Ø­Ù\87Ù\94|صÙ\81Ø­Ù\87â\80\8cÙ\87اÛ\8c}} Ø²Û\8cر Ú©Ù\87 Ú¯Ø²Û\8cÙ\86Ù\87Ù\94 Ù\85حاÙ\81ظت Ø¢Ø¨Ø´Ø§Ø±Û\8c {{PLURAL:$1|Ø¢Ù\86|Ø¢Ù\86â\80\8cÙ\87ا}} Ù\81عاÙ\84 Ø§Ø³ØªØ\8c Ú¯Ù\86جاÙ\86دÙ\87 Ø´Ø¯Ù\87 Ø§Ø³Øª.\nØ´Ù\85ا Ù\85Û\8câ\80\8cتÙ\88اÙ\86Û\8cد Ø³Ø·Ø­ Ù\85حاÙ\81ظت Ø§Û\8cÙ\86 ØµÙ\81Ø­Ù\87 Ø±Ø§ ØªØºÛ\8cÛ\8cر Ø¨Ø¯Ù\87Û\8cد Ø§Ù\85ا Ø§Û\8cÙ\86 Ú©Ø§Ø± ØªØ§Ø«Û\8cرÛ\8c Ø¨Ø± Ù\85حاÙ\81ظت Ø¢Ø¨Ø´Ø§Ø±Û\8c ØµÙ\81Ø­Ù\87 نخواهد گذاشت.",
+    "protect-cascadeon": "اÛ\8cÙ\86 ØµÙ\81Ø­Ù\87  Ø¯Ø± Ø­Ø§Ù\84 Ø­Ø§Ø¶Ø± Ù\85حاÙ\81ظت Ø´Ø¯Ù\87â\80\8cاست Ø²Û\8cرا Ø¯Ø± {{PLURAL:$1|صÙ\81Ø­Ù\87Ù\94|صÙ\81Ø­Ù\87â\80\8cÙ\87اÛ\8c}} Ø²Û\8cر Ú©Ù\87 Ú¯Ø²Û\8cÙ\86Ù\87Ù\94 Ù\85حاÙ\81ظت Ø¢Ø¨Ø´Ø§Ø±Û\8c {{PLURAL:$1|Ø¢Ù\86|Ø¢Ù\86â\80\8cÙ\87ا}} Ù\81عاÙ\84 Ø§Ø³ØªØ\8c Ú¯Ù\86جاÙ\86دÙ\87 Ø´Ø¯Ù\87 Ø§Ø³Øª.\nتغÛ\8cÛ\8cراتÛ\8c Ø¨Ù\87 Ø³Ø·Ø­ Ù\85حاÙ\81ظت Ø§Û\8cÙ\86 ØµÙ\81Ø­Ù\87 Ø¨Ù\87 Ù\85حاÙ\81ظت Ø§Ø¨Ø´Ø§Ø±Û\8c ØªØ£Ø«Û\8cر نخواهد گذاشت.",
     "protect-default": "همهٔ کاربرها",
     "protect-fallback": "فقط به کاربرهایی که دسترسی «$1» دارند، اجازه داده می‌شود",
     "protect-level-autoconfirmed": "تنها کاربران تأییدشده",
     "contributions-title": "مشارکت‌های کاربری $1",
     "mycontris": "مشارکت‌ها",
     "contribsub2": "برای {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "حساب کاربری «$1» ثبت نشده‌است.",
     "nocontribs": "هیچ تغییری با این مشخصات یافت نشد.",
     "uctop": "(نسخه کنونی)",
     "month": "در این ماه (و پیش از آن):",
index 0c5c0c4..c9ee274 100644 (file)
     "content-model-javascript": "JavaScript",
     "content-model-css": "CSS",
     "expensive-parserfunction-warning": "Tällä sivulla on liian monta hitaiden laajennusfunktioiden kutsua.\nKutsuja pitäisi olla alle $2 {{PLURAL:$2|kappale|kappaletta}}, mutta nyt niitä on $1 {{PLURAL:$1|kappale|kappaletta}}.",
-    "expensive-parserfunction-category": "Liiaksi hitaita jäsentimen laajennusfunktioita käyttävät sivut",
+    "expensive-parserfunction-category": "Sivut, joissa on liian monta vaativaa jäsenninfunktiota",
     "post-expand-template-inclusion-warning": "'''Varoitus:''' Sisällytettyjen mallineiden koko on liian suuri.\nJoitakin mallineita ei ole sisällytetty.",
     "post-expand-template-inclusion-category": "Mallineiden sisällytyksen kokorajan ylittävät sivut",
     "post-expand-template-argument-warning": "'''Varoitus:''' Tällä sivulla on ainakin yksi mallineen muuttuja, jonka sisällytetty koko on liian suuri.\nNämä muuttujat on jätetty käsittelemättä.",
     "prefs-skin": "Ulkoasu",
     "skin-preview": "esikatselu",
     "datedefault": "Ei omaa määrittelyä",
-    "prefs-datetime": "Aika ja päiväys",
     "prefs-labs": "Testattavana olevat ominaisuudet",
     "prefs-user-pages": "Käyttäjäsivut",
     "prefs-personal": "Käyttäjätiedot",
     "noindex-category-desc": "Tätä sivua eivät hakurobotit indeksoi, koska sivulla on taikasana <code><nowiki>__NOINDEX__</nowiki></code> ja koska sivu on sellaisessa nimiavaruudessa, jossa taikasanan käyttö on sallittua.",
     "index-category-desc": "Tällä sivulla on koodi <code><nowiki>__INDEX__</nowiki></code> ja sivu on sellaisessa nimiavaruudessa, jossa koodin käyttö on sallittua. Tämän vuoksi hakurobotit indeksoivat tämän sivun, vaikka ilman koodia sivua ei indeksoitaisi normaalisti.",
     "post-expand-template-inclusion-category-desc": "Jos kaikki mallineet laajennetaan, sivun koko on suurempi kuin <code>$wgMaxArticleSize</code>. Tämän vuoksi kaikkia mallineita ei laajennettu.",
-    "post-expand-template-argument-category-desc": "Kun mallineen argumentti on laajennettu (argumentti on merkkijono kolmen kaarisulun sisällä kuten <code>{{{Foo}}})</code>, sivu on suurempi kuin <code>$wgMaxArticleSize</code>.",
+    "post-expand-template-argument-category-desc": "Kun mallineen argumentti on laajennettu (argumentti on merkkijono kolmen kaarisulun sisällä kuten <code>{{{Foo}}}</code>), sivu on suurempi kuin <code>$wgMaxArticleSize</code>.",
+    "expensive-parserfunction-category-desc": "Liian monta resursseja vaativaa jäsenninfunktiota (esimerkiksi <code>#ifexist</code>) on sisällytetty sivulle. Katso [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
     "broken-file-category-desc": "Tämä luokka sisältää ne sivut, joissa on rikkinäinen tiedostolinkki. Tällä tarkoitetaan linkkiä sellaiseen tiedostoon, jota ei olemassa.",
     "hidden-category-category-desc": "Tämä on luokka, joka sisältää koodin <code><nowiki>__HIDDENCAT__</nowiki></code>. Koodi estää luokan näkymisen sivujen alareunassa olevassa luokkien laatikossa oletusarvoisesti.",
     "trackingcategories-nodesc": "Ei kuvausta olemassa.",
     "unwatchthispage": "Lopeta tarkkailu",
     "notanarticle": "Ei ole sivu",
     "notvisiblerev": "Versio on poistettu",
-    "watchlist-details": "Tarkkailulistalla on {{PLURAL:$1|$1 sivu|$1 sivua}} keskustelusivuja mukaan laskematta.",
+    "watchlist-details": "Tarkkailulistallasi on {{PLURAL:$1|$1 sivu|$1 sivua}}. Keskustelusivuja ei lasketa mukaan.",
     "wlheader-enotif": "Sähköposti-ilmoitus on käytössä.",
     "wlheader-showupdated": "Sivut, joita on muokattu viimeisen käyntisi jälkeen, on '''lihavoitu'''.",
     "watchmethod-recent": "tarkistetaan tuoreimpia muutoksia tarkkailluille sivuille",
     "rollbacklinkcount-morethan": "palauta yli $1 {{PLURAL:$1|muutos|muutosta}}",
     "rollbackfailed": "Palautus epäonnistui",
     "cantrollback": "Aiempaan versioon ei voi palauttaa, koska viimeisin kirjoittaja on sivun ainoa tekijä.",
-    "alreadyrolled": "Käyttäjän [[User:$2|$2]] ([[User talk:$2|keskustelu]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tekemiä muutoksia sivuun [[:$1]] ei voi kumota, koska joku muu on muuttanut sivua.\n\nViimeisimmän muokkauksen on tehnyt käyttäjä [[User:$3|$3]] ([[User talk:$3|keskustelu]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
+    "alreadyrolled": "Käyttäjän [[User:$2|$2]] ([[User talk:$2|keskustelu]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tekemiä muutoksia sivuun [[:$1]] ei voida kumota, koska joku toinen käyttäjä on joko muuttanut sivua tai palauttanut muokkauksen.\n\nViimeisimmän muokkauksen on tehnyt käyttäjä [[User:$3|$3]] ([[User talk:$3|keskustelu]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
     "editcomment": "Muokkauksen yhteenveto oli: ''$1''.",
     "revertpage": "Käyttäjän [[Special:Contributions/$2|$2]] ([[User talk:$2|keskustelu]]) muokkaukset kumottiin ja sivu palautettiin viimeisimpään käyttäjän [[User:$1|$1]] tekemään versioon.",
     "revertpage-nouser": "Käyttäjän (käyttäjänimi poistettu) muokkaukset kumottiin ja sivu palautettiin viimeisimpään käyttäjän {{GENDER:$1|[[User:$1|$1]]}} tekemään versioon",
     "contributions-title": "Käyttäjän $1 muokkaukset",
     "mycontris": "Omat muokkaukset",
     "contribsub2": "Käyttäjän {{GENDER:$3|$1}} ($2) muokkaukset",
+    "contributions-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
     "nocontribs": "Näihin ehtoihin sopivia muokkauksia ei löytynyt.",
     "uctop": "(uusin)",
     "month": "Kuukausi",
index 4ad6826..c82636c 100644 (file)
     "permalink": "Adresse de cette version",
     "print": "Imprimer",
     "view": "Lire",
+    "view-foreign": "Voir sur $1",
     "edit": "Modifier",
+    "edit-local": "Modifier la description locale",
     "create": "Créer",
+    "create-local": "ajouter une description locale",
     "editthispage": "Modifier cette page",
     "create-this-page": "Créer cette page",
     "delete": "Supprimer",
     "prefs-skin": "Habillage",
     "skin-preview": "Prévisualiser",
     "datedefault": "Aucune préférence",
-    "prefs-datetime": "Date et heure",
     "prefs-labs": "Fonctionnalités « labs »",
     "prefs-user-pages": "Pages utilisateur",
     "prefs-personal": "Informations personnelles",
     "listgrouprights-removegroup-self": "Peut se retirer {{PLURAL:$2|le groupe|les groupes}} de son propre compte : $1",
     "listgrouprights-addgroup-self-all": "Peut s'ajouter tous les groupes à son propre compte",
     "listgrouprights-removegroup-self-all": "Peut se retirer tous les groupes de son propre compte",
+    "listgrouprights-namespaceprotection-header": "Restrictions d'espace de noms",
+    "listgrouprights-namespaceprotection-namespace": "Espace de noms",
+    "listgrouprights-namespaceprotection-restrictedto": "Droit(s) permettant à l'utilisateur de modifier",
     "trackingcategories": "Catégories de suivi",
-    "trackingcategories-summary": "Cette page liste les catégories de suivi qui sont remplies automatiquement par le logiciel MédiaWiki. Leurs noms peuvent être changés en modifiant les messages systèmes correspondants dans l’espace de noms {{ns:8}}.",
+    "trackingcategories-summary": "Cette page liste les catégories de suivi qui sont remplies automatiquement par [[MediaWiki]]. Leurs noms peuvent être changés en modifiant les messages systèmes correspondants dans l’espace de noms {{ns:8}}.",
     "trackingcategories-msg": "Catégorie de suivi",
     "trackingcategories-name": "Nom du message",
     "trackingcategories-desc": "Critère d’inclusion de la catégorie",
-    "noindex-category-desc": "La page contient un mot magique <code><nowiki>__NOINDEX__</nowiki></code> (et est dans un espace de noms où ce marquage est autorisé), et donc ne sera pas indexée par les robots.",
-    "index-category-desc": "La page contient un <code><nowiki>__INDEX__</nowiki></code> (et est dans un espace de noms où ce marquage est autorisé), et sera donc indexée par les robots alors qu’elle ne l’aurait pas été normalement.",
+    "noindex-category-desc": "La page contient <code><nowiki>__NOINDEX__</nowiki></code> et est dans un espace de noms où ce marquage est autorisé ; elle ne sera donc pas indexée par les robots.",
+    "index-category-desc": "La page contient <code><nowiki>__INDEX__</nowiki></code> et est dans un espace de noms où ce marquage est autorisé ; elle sera donc indexée par les robots alors qu’elle ne l’aurait pas été normalement.",
     "post-expand-template-inclusion-category-desc": "Après avoir développé tous les modèles, la taille de la page dépasse <code>$wgMaxArticleSize</code> ; certains modèles n’ont donc pas été développés.",
     "post-expand-template-argument-category-desc": "Après avoir développé l’argument d’un modèle (quelque chose entre accolades triples, comme <code>{{{Foo}}}</code>), la page dépasse <code>$wgMaxArticleSize</code>.",
     "expensive-parserfunction-category-desc": "Trop de fonctions coûteuses de l’analyseur (comme <code>#ifexist</code>) sont incluses dans une page. Voyez [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
-    "broken-file-category-desc": "Catégorie ajoutée su la page contient un lien de fichier incorrect (un lien pour inclure un fichier alors que celui-ci n’existe pas).",
-    "hidden-category-category-desc": "C’est une catégorie contenant <code><nowiki>__HIDDENCAT__</nowiki></code>, qui empêche son affichage dans la zone des liens de catégorie sur les pages, par défaut.",
+    "broken-file-category-desc": "La catégorie ajoutée sur la page contient un lien de fichier incorrect (un lien pour inclure un fichier alors que celui-ci n’existe pas).",
+    "hidden-category-category-desc": "Catégorie contenant <code><nowiki>__HIDDENCAT__</nowiki></code>, qui empêche son affichage dans la zone des liens de catégorie sur les pages, par défaut.",
     "trackingcategories-nodesc": "Aucune description disponible.",
     "trackingcategories-disabled": "La catégorie est désactivée",
     "mailnologin": "Pas d'adresse d'expéditeur",
     "unwatchthispage": "Ne plus suivre",
     "notanarticle": "Ce n'est pas une page de contenu",
     "notvisiblerev": "La version a été supprimée",
-    "watchlist-details": "Votre liste de suivi référence $1 page{{PLURAL:$1||s}}, sans compter les pages de discussion.",
+    "watchlist-details": "{{PLURAL:$1|$1 page|$1 pages}} dans votre liste de suivi, sans compter les pages de discussion.",
     "wlheader-enotif": "La notification par courriel est activée.",
     "wlheader-showupdated": "Les pages qui ont été modifiées depuis votre dernière visite sont affichées en '''gras'''.",
     "watchmethod-recent": "vérification des modifications récentes pour y trouver des pages suivies",
     "contributions-title": "Liste des contributions de l’utilisat{{GENDER:$1|eur|rice|eur}} $1",
     "mycontris": "Contributions",
     "contribsub2": "Pour {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "Le compte utilisateur « $1 » n’est pas enregistré.",
     "nocontribs": "Aucune modification correspondant à ces critères n'a été trouvée.",
     "uctop": "(actuel)",
     "month": "À partir du mois (et précédents) :",
index ce9aa63..e2fd0e8 100644 (file)
     "prefs-skin": "Skak",
     "skin-preview": "Föörskau",
     "datedefault": "Föör-iinstelang",
-    "prefs-datetime": "Dai an klooktidj",
     "prefs-labs": "Alpha mögelkhaiden",
     "prefs-user-pages": "Brükersidjen",
     "prefs-personal": "Brüker dooten",
index 12b457c..f3a11a6 100644 (file)
     "prefs-skin": "Side-oansjen",
     "skin-preview": "Proefbyld",
     "datedefault": "Gjin foarkar",
-    "prefs-datetime": "Datum en tiid",
     "prefs-personal": "Persoanlike gegevens",
     "prefs-rc": "Koartlyn feroare",
     "prefs-watchlist": "Folchlist",
index 37f5124..2feec0a 100644 (file)
     "prefs-skin": "Aparencia",
     "skin-preview": "Vista previa",
     "datedefault": "Ningunha preferencia",
-    "prefs-datetime": "Data e hora",
     "prefs-labs": "Características experimentais",
     "prefs-user-pages": "Páxinas de usuario",
     "prefs-personal": "Información de usuario",
index 88225fe..75e3690 100644 (file)
     "prefs-skin": "Benutzeroberflechi",
     "skin-preview": "Vorschou",
     "datedefault": "kei Aagab",
-    "prefs-datetime": "Datum un Zyt",
     "prefs-labs": "Alphafunktione",
     "prefs-user-pages": "Benutzersyte",
     "prefs-personal": "Benutzerdate",
index aee8136..6cf8776 100644 (file)
     "prefs-skin": "ફલક",
     "skin-preview": "ફેરફાર બતાવો",
     "datedefault": "મારી પસંદ",
-    "prefs-datetime": "તારીખ અને સમય",
     "prefs-labs": "પ્રયોગશાળા લક્ષણો",
     "prefs-user-pages": "સભ્ય પાનાંઓ",
     "prefs-personal": "સભ્ય ઓળખ",
index a378633..1025467 100644 (file)
     "prefs-skin": "ʻIli",
     "skin-preview": "Nāmua",
     "datedefault": "ʻAʻohe makemake",
-    "prefs-datetime": "Ka lā a me ka hola",
     "prefs-user-pages": "ʻAoʻao mea ho‘ohana",
     "prefs-personal": "ʻAoʻao mea hoʻohana",
     "prefs-rc": "Nā loli hou",
index c2b0d37..27d259b 100644 (file)
     "prefs-skin": "עיצוב",
     "skin-preview": "תצוגה מקדימה",
     "datedefault": "ברירת המחדל",
-    "prefs-datetime": "תאריך ושעה",
     "prefs-labs": "אפשרויות מעבדה",
     "prefs-user-pages": "דפי משתמש",
     "prefs-personal": "פרטי המשתמש",
     "unwatchthispage": "הפסקת המעקב אחרי דף זה",
     "notanarticle": "זהו אינו דף תוכן",
     "notvisiblerev": "הגרסה האחרונה שנוצרה על־ידי משתמש אחר נמחקה",
-    "watchlist-details": "ברשימת המעקב יש {{PLURAL:$1|דף אחד|$1 דפים}} (לא כולל דפי שיחה).",
+    "watchlist-details": "ברשימת המעקב יש {{PLURAL:$1|דף אחד|$1 דפים}}, כאשר דפי השיחה אינם נספרים בנפרד.",
     "wlheader-enotif": "הודעות דוא\"ל מאופשרות.",
     "wlheader-showupdated": "דפים שהשתנו מאז ביקורך האחרון בהם מוצגים ב'''הדגשה'''.",
     "watchmethod-recent": "בודק את הדפים שברשימת המעקב לשינויים אחרונים.",
     "contributions-title": "תרומות של ה{{GENDER:$1|משתמש|משתמשת}} $1",
     "mycontris": "תרומות",
     "contribsub2": "עבור {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "החשבון \"$1\" אינו רשום.",
     "nocontribs": "לא נמצאו שינויים המתאימים לקריטריונים אלו.",
     "uctop": "(נוכחי)",
     "month": "עד החודש:",
index a357506..ad2d99c 100644 (file)
     "permalink": "स्थायी कड़ी",
     "print": "प्रिंट करें",
     "view": "दर्शाव",
+    "view-foreign": "$1 पर देखें",
     "edit": "सम्पादन",
     "create": "बनाएँ",
     "editthispage": "इस पृष्ठ को बदलें",
     "prefs-skin": "त्वचा",
     "skin-preview": "झलक",
     "datedefault": "खा़स पसंद नहीं",
-    "prefs-datetime": "दिनांक तथा समय",
     "prefs-labs": "लैब विशेषताएँ",
     "prefs-user-pages": "सदस्य पृष्ठ",
     "prefs-personal": "सदस्य व्यक्तिरेखा",
     "listgrouprights-removegroup-self": " अपने  खाते से {{PLURAL:$2|समूह}} हटाएँ: $1",
     "listgrouprights-addgroup-self-all": "अपने खाते में सभी समूह शामिल करें",
     "listgrouprights-removegroup-self-all": "अपने खाते से सभी समूह हटाएँ",
+    "listgrouprights-namespaceprotection-namespace": "नामस्थान",
     "trackingcategories-nodesc": "कोई वर्णन उपलब्ध नहीं।",
     "mailnologin": "पाने वाले का एड्रेस दिया नहीं",
     "mailnologintext": "अन्य सदस्यों को इ-मेल भेजने के लिये [[Special:UserLogin|लॉग इन]] करना आवश्यक है और आपकी [[Special:Preferences|वरीयताओं]] में वैध ई-मेल पता होना आवश्यक है।",
     "version-entrypoints-header-url": "यू॰आर॰एल",
     "redirect-submit": "जायें",
     "redirect-lookup": "ढूँढें:",
+    "redirect-value": "मूल्य:",
     "redirect-user": "सदस्य आई॰डी",
     "redirect-revision": "पृष्ठ अवतरण संख्या",
     "redirect-file": "फ़ाइल नाम",
     "fileduplicatesearch-result-n": "फ़ाईल \"$1\" में {{PLURAL:$2|1 द्विरावृत्ति|$2 द्विरावृत्तियाँ}} मिले हैं।",
     "fileduplicatesearch-noresults": "कोई फ़ाइल नाम \"$1\" मिला नहीं ।",
     "specialpages": "विशेष पृष्ठ",
+    "specialpages-note-top": "कुंजी",
     "specialpages-note": "* साधारण विशेष पृष्ठ।\n* <span class=\"mw-specialpagerestricted\">प्रतिबंधित विशेष पृष्ठ।</span>",
     "specialpages-group-maintenance": "अनुरक्षण रिपोर्ट",
     "specialpages-group-other": "अन्य विशेष पृष्ठ",
index 92564f9..ea7a0e1 100644 (file)
     "prefs-skin": "Izgled",
     "skin-preview": "Pregled",
     "datedefault": "Nemoj postaviti",
-    "prefs-datetime": "Datum i vrijeme",
     "prefs-labs": "Labs mogućnosti",
     "prefs-user-pages": "Suradničke stranice",
     "prefs-personal": "Podaci o suradniku",
index ed2c375..0d36406 100644 (file)
     "showhideselectedversions": "Kiválasztott változatok láthatóságának beállítása",
     "editundo": "visszavonás",
     "diff-empty": "(Nincs különbség)",
+    "diff-multi-sameuser": "({{PLURAL:$1|Egy közbenső módosítás|$1 közbenső módosítás}} ugyanattól a szerkesztőtől nincs mutatva)",
     "diff-multi-manyusers": "({{PLURAL:$1|Egy közbeeső változat|$1 közbeeső változat}} nincs mutatva, amit $2 szerkesztő módosított)",
     "difference-missing-revision": "A(z) \"{{PAGENAME}}\" nevű oldal #$1 $2 változata nem létezik.\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",
     "prefs-skin": "Felület",
     "skin-preview": "előnézet",
     "datedefault": "Nincs beállítás",
-    "prefs-datetime": "Dátum és idő",
     "prefs-labs": "Kísérleti funkciók",
     "prefs-user-pages": "Felhasználói lapok",
     "prefs-personal": "Felhasználói adatok",
index 535c491..20c78f0 100644 (file)
     "prefs-skin": "Kulit",
     "skin-preview": "Pratayang",
     "datedefault": "Tak ada preferensi",
-    "prefs-datetime": "Tanggal dan waktu",
     "prefs-labs": "Fitur Labs",
     "prefs-user-pages": "Halaman pengguna",
     "prefs-personal": "Profil",
index aa8c0cd..a200043 100644 (file)
     "prefs-skin": "Þema",
     "skin-preview": "Forskoða",
     "datedefault": "Sjálfgefið",
-    "prefs-datetime": "Tímasnið og tímabelti",
     "prefs-labs": "Stillingar á tilraunastigi",
     "prefs-user-pages": "Notendasíður",
     "prefs-personal": "Notandaupplýsingar",
index 426ccc8..49b4309 100644 (file)
     "content-model-javascript": "JavaScript",
     "content-model-css": "CSS",
     "expensive-parserfunction-warning": "'''Attenzione:''' Questa pagina contiene troppe chiamate alle parser functions.\n\nDovrebbe averne meno di $2, al momento ce {{PLURAL:$1|n'è $1|ne sono $1}}.",
-    "expensive-parserfunction-category": "Pagine con troppe chiamate alle parser functions",
+    "expensive-parserfunction-category": "Pagine con troppe chiamate alle funzioni parser",
     "post-expand-template-inclusion-warning": "'''Attenzione:''' la dimensione dei template inclusi è troppo grande.\nAlcuni template non verranno inclusi.",
     "post-expand-template-inclusion-category": "Pagine per le quali la dimensione dei template inclusi supera il limite consentito",
     "post-expand-template-argument-warning": "'''Attenzione:''' questa pagina contiene uno o più argomenti di template troppo grandi per essere espansi. Tali argomenti verranno omessi.",
     "prefs-skin": "Aspetto grafico (skin)",
     "skin-preview": "Anteprima",
     "datedefault": "Nessuna preferenza",
-    "prefs-datetime": "Data e ora",
     "prefs-labs": "Funzionalità sperimentali",
     "prefs-user-pages": "Pagine utente",
     "prefs-personal": "Profilo utente",
     "contributions-title": "Contributi di $1",
     "mycontris": "contributi",
     "contribsub2": "Per {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "L'account utente \"$1\" non è registrato.",
     "nocontribs": "Non sono state trovate modifiche che soddisfino i criteri di ricerca.",
     "uctop": "(attuale)",
     "month": "Dal mese (e precedenti):",
index ca4e4cc..76266a5 100644 (file)
     "prefs-skin": "外装",
     "skin-preview": "プレビュー",
     "datedefault": "選択なし",
-    "prefs-datetime": "日付と時刻",
     "prefs-labs": "ラボの機能",
     "prefs-user-pages": "利用者ページ",
     "prefs-personal": "利用者情報",
     "listgrouprights-removegroup-self": "自身のアカウントから{{PLURAL:$2|グループ}}を除去: $1",
     "listgrouprights-addgroup-self-all": "自身のアカウントに全グループを追加可能",
     "listgrouprights-removegroup-self-all": "自身のアカウントから全グループを除去可能",
+    "listgrouprights-namespaceprotection-namespace": "名前空間",
     "trackingcategories": "追跡用カテゴリ",
     "trackingcategories-summary": "このページでは、MediaWiki ソフトウェアが自動的に追加した追跡用カテゴリを列挙します。これらの名前は、{{ns:8}} 名前空間内の対応するシステム メッセージを修正することで変更できます。",
     "trackingcategories-msg": "追跡用カテゴリ",
     "contributions-title": "$1の投稿記録",
     "mycontris": "投稿記録",
     "contribsub2": "利用者: {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "利用者アカウント「$1」は登録されていません。",
     "nocontribs": "これらの条件に一致する変更は見つかりませんでした。",
     "uctop": "(最新)",
     "month": "この月以前:",
index bc36adb..60e6af4 100644 (file)
     "prefs-skin": "გარეკანი",
     "skin-preview": "წინასწარი გადახედვა",
     "datedefault": "წყარო მითითებული არაა",
-    "prefs-datetime": "თარიღი და დრო",
     "prefs-labs": "ექსპერიმენტალური ფუნქციები",
     "prefs-user-pages": "მომხმარებლის გვერდები",
     "prefs-personal": "მომხმარებლის მონაცემები",
index 0a2f07f..d50a58b 100644 (file)
     "post-expand-template-argument-warning": "Hişyari: No pel de tewr tay yew şablono herayi esto.",
     "post-expand-template-argument-category": "Pelê ke şablonê eyi qebul niye",
     "viewpagelogs": "Qeydê ke na pele ra alaqedarê, inu bıasne",
-    "currentrev": "Çımraviarnaoğo rozane",
+    "currentrev": "Çımraviyarnayiso rozane",
     "currentrev-asof": "$1 ra gore pele be halo nıkaên",
     "revisionasof": "Halê roca $1ine",
     "revision-info": "Tesdiq kerdışê roca $1ine be terefê $2",
     "prefs-skin": "Çerme",
     "skin-preview": "Verqayt",
     "datedefault": "Tercihi çinê",
-    "prefs-datetime": "Tarix u zeman",
     "prefs-personal": "Dosya karberi",
     "prefs-rc": "Vurnaisê peyêni",
     "prefs-watchlist": "Lista şêrkerdene",
index c3dac10..3d7ea16 100644 (file)
     "permalink": "Тұрақты сілтеме",
     "print": "Басып шығару",
     "view": "Қарау",
+    "view-foreign": "$1 сайтынан қарау",
     "edit": "Өңдеу",
+    "edit-local": "Жергілікті сипаттамасын өңдеу",
     "create": "Бастау",
+    "create-local": "Жергілікті сипаттамасын қосу",
     "editthispage": "Бұл бетті өңдеу",
     "create-this-page": "Осы бетті бастау",
     "delete": "Жою",
     "newarticle": "(Жаңа)",
     "newarticletext": "Сілтемеге еріп әлі басталмаған бетке келіпсіз.\nБетті бастау үшін, төменгі терезеде мәтініңізді теріңіз (көбірек ақпарат үшін [$1 анықтама бетін] қараңыз).\nЕгер жаңылғаннан осында келген болсаңыз, браузердің «артқа» деген батырмасын басыңыз.",
     "anontalkpagetext": "----''Бұл тіркелгісіз (немесе тіркелгісін қолданбаған) қатысушы талқылау беті. Осы қатысушыны біз тек сандық IP мекенжайымен теңдестіреміз.\nОсындай IP мекенжай бірнеше қатысушыға ортақтастырылған болуы мүмкін.\nЕгер сіз тіркелгісіз қатысушы болсаңыз және сізге қатыссыз мәндемелер жіберілгенін сезсеңіз, басқа тіркелгісіз қатысушылармен араластырмауы үшін [[{{#special:Userlogin}}|тіркеліңіз не кіріңіз]].''",
-    "noarticletext": "Ағымда бұл бетте еш мәтін жоқ.\n* Басқа беттерден [[Special:Search/{{PAGENAME}}|бұл бет атауын іздеу]],\n* <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} Журналдардан бұл бетке қатысты сәйкес жазбаларды табу]</span>,\n* <span class=\"plainlinks\">'''[{{fullurl:{{FULLPAGENAME}}|action=edit}} Бұл бетті жаңадан бастау]'''</span>.",
+    "noarticletext": "Қазіргі уақытта бұл бетте еш мәтін жоқ.\n* Басқа беттерден [[Special:Search/{{PAGENAME}}|бұл бет атауын іздеу]],\n* <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} Журналдардан бұл бетке қатысты сәйкес жазбаларды табу]</span>,\n* <span class=\"plainlinks\">'''[{{fullurl:{{FULLPAGENAME}}|action=edit}} Бұл бетті жаңадан бастау]'''</span>.",
     "noarticletext-nopermission": "Ағымда бұл бетте еш мәтін жоқ.\nСіз [[Special:Search/{{PAGENAME}}|бұл бет атауын]] басқа беттерден іздей аласыз, немесе <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} журналдардан бұл бетке қатысты сәйкес жазбаларды таба аласыз]</span>. Ал бұл бетті жаңадан бастауға сізде рұқсат жоқ.",
     "userpage-userdoesnotexist": "«<nowiki>$1</nowiki>» қатысушы тіркелгісі жазып алынбаған. Бұл бетті бастау/өңдеу талабыңызды тексеріп шығыңыз.",
     "userpage-userdoesnotexist-view": "«$1» қатысушы есімі тіркелмеген.",
     "revertmerge": "Біріктіруді болдырмау",
     "mergelogpagetext": "Төменде бір беттің тарихы өзге бетке біріктіру ең соңғы тізімі келтіріледі.",
     "history-title": "«$1» дегеннің өңдеу тарихы",
-    "difference-title": "Нұсқалар арасындағы айырмашылық: \"$1\"",
+    "difference-title": "Нұсқалар арасындағы айырмашылық: <<$1>>",
     "difference-title-multipage": "\"$1\" және \"$2\" беттерінің арасындағы айырмашылық",
     "difference-multipage": "(Беттер арасындағы айырмашылық)",
     "lineno": "Жол нөмірі $1:",
     "prefs-skin": "Мәнерлер",
     "skin-preview": "Қарап шығу",
     "datedefault": "Еш қалаусыз",
-    "prefs-datetime": "Уақыт",
     "prefs-labs": "Тәжірибелік мүмкіндіктер",
     "prefs-user-pages": "Қатысушы беттері",
     "prefs-personal": "Жеке деректері",
     "upload-misc-error": "Жүктеу кезіндегі белгісіз қате",
     "upload-misc-error-text": "Жүктеу кезінде белгісіз қатеге ұшырасты.\nURL жарамды және қатынаулы екенін тексеріп шығыңыз да қайта байқап көріңіз.\nЕгер бұл мәселе әлде де қалса, [[Special:ListUsers/sysop|жүйе әкімшімен]] қатынасыңыз.",
     "upload-too-many-redirects": "URL шектен тыс жылжытуларға ие",
+    "backend-fail-notexists": "$1 файлы бар емес.",
     "backend-fail-delete": "«$1» файлы жойылмайды.",
     "backend-fail-describe": "\"$1\" файлы үшін метадерегі өзгертілмейді.",
     "backend-fail-alreadyexists": "\"$1\" файлы бұрыннан бар.",
index 6eafe4f..f9e475f 100644 (file)
     "vector-action-delete": "삭제",
     "vector-action-move": "옮기기",
     "vector-action-protect": "보호",
-    "vector-action-undelete": "되살리기",
+    "vector-action-undelete": "삭제 취소",
     "vector-action-unprotect": "보호 설정 바꾸기",
     "vector-view-create": "만들기",
     "vector-view-edit": "편집",
     "blocked-mailpassword": "당신의 IP 주소는 편집을 할 수 없게 차단되어 있어서 악용하지 못하도록 비밀번호 되살리기 기능 사용이 금지됩니다.",
     "eauthentsent": "입력한 이메일로 확인 이메일을 보냈습니다.\n다른 모든 형태의 이메일을 당신의 계정으로 보내기 전에, 계정이 정말 당신의 것인지 확인하기 위해 이메일 내용의 지시대로 계정 확인 절차를 실행해 주셔야 합니다.",
     "throttled-mailpassword": "비밀번호 재설정 이메일을 이미 최근 {{PLURAL:$1|$1시간}} 안에 보냈습니다.\n악용을 방지하기 위해 비밀번호 재설정 메일은 {{PLURAL:$1|$1시간}}마다 오직 하나씩만 보낼 수 있습니다.",
-    "mailerror": "메일 보내기 오류: $1",
+    "mailerror": "메일을 보내는 중 오류: $1",
     "acct_creation_throttle_hit": "당신의 IP 주소를 이용한 방문자가 이전에 이미 {{PLURAL:$1|계정 $1개}}를 만들어, 계정 만들기 한도를 초과하였습니다.\n따라서 지금은 이 IP 주소로는 더 이상 계정을 만들 수 없습니다.",
     "emailauthenticated": "이메일 주소는 $2 에 $3 에서 인증되었습니다.",
     "emailnotauthenticated": "이메일 주소를 인증하지 않았습니다.\n이메일 확인 절차를 거치지 않으면 다음 이메일 기능을 사용할 수 없습니다.",
     "resetpass_header": "비밀번호 바꾸기",
     "oldpassword": "이전 비밀번호:",
     "newpassword": "새 비밀번호:",
-    "retypenew": "새 비밀번호 입력:",
+    "retypenew": "새 비밀번호 다시 입력:",
     "resetpass_submit": "비밀번호를 설정하고 로그인하기",
     "changepassword-success": "비밀번호가 성공적으로 바뀌었습니다!",
     "changepassword-throttled": "최근 너무 많이 로그인을 시도했습니다.\n$1 뒤에 다시 시도하세요.",
     "passwordreset-emailsent-capture": "비밀번호 재설정 이메일이 발송되었으며, 아래에 나타나 있습니다.",
     "passwordreset-emailerror-capture": "비밀번호 재설정 이메일이 생성되어 아래에 보여져 있지만, {{GENDER:$2|사용자}}에게 발송하는 데에는 실패했습니다: $1",
     "changeemail": "이메일 주소 바꾸기",
-    "changeemail-header": "계정 메일 주소 바꾸기",
+    "changeemail-header": "계정 메일 주소 바꾸기",
     "changeemail-text": "이메일 주소를 바꾸려면 이 양식을 채우세요. 이 바뀜을 확인하기 위해 비밀번호를 입력해야 합니다.",
     "changeemail-no-info": "이 특수 문서에 직접 접근하려면 반드시 로그인해야 합니다.",
     "changeemail-oldemail": "현재 이메일 주소 :",
     "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}}}} 삭제 기록]에서 확인할 수 있습니다.",
-    "userpage-userdoesnotexist": "\"$1\" 계정은 등록되어 있지 않습니다.\n이 문서를 만들거나 편집하려면 계정이 존재 하는지 확인해주세요.",
+    "userpage-userdoesnotexist": "\"$1\" 사용자 계정은 등록되어 있지 않습니다.\n이 문서를 만들거나 편집하려면 계정이 존재하는지 확인해주세요.",
     "userpage-userdoesnotexist-view": "\"$1\" 사용자 계정은 등록되지 않았습니다.",
     "blocked-notice-logextract": "이 사용자는 현재 차단되어 있습니다.\n해당 사용자의 최근 차단 기록을 참고하십시오:",
     "clearyourcache": "'''참고:''' 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.\n* '''파이어폭스 / 사파리''': ''Shift'' 키를 누르면서 새로 고침을 클릭하거나, ''Ctrl-F5'' 또는 ''Ctrl-R'' 을 입력 (Mac에서는 ''⌘-R'')\n* '''구글 크롬''': ''Ctrl-Shift-R''키를 입력 (Mac에서는 ''⌘-Shift-R'')\n* '''인터넷 익스플로러''': ''Ctrl'' 키를 누르면서 새로 고침을 클릭하거나, ''Ctrl-F5''를 입력.\n* '''오페라''': ''도구→설정''에서 캐시를 비움",
     "prefs-skin": "스킨",
     "skin-preview": "미리 보기",
     "datedefault": "기본 값",
-    "prefs-datetime": "날짜와 시각",
     "prefs-labs": "실험 중인 기능",
     "prefs-user-pages": "사용자 문서",
     "prefs-personal": "사용자 정보",
     "fileexists": "같은 이름의 파일이 이미 있습니다. 파일을 바꾸고 싶지 않다면 <strong>[[:$1]]</strong> 파일을 확인해 주세요.\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": "이 파일은 원본 그림이 아닌, 다른 그림의 크기를 줄인 섬네일 파일인 것 같습니다.\n[[$1|thumb]]\n<strong>[[:$1]]</strong> 파일을 확인하세요.\n해당 파일이 현재 올리려는 파일과 같다면 더 작은 크기의 그림을 올릴 필요는 없습니다.",
-    "file-thumbnail-no": "파일 이름이 <strong>$1</strong>으로 시작합니다.\n이 파일은 원본 그림이 아닌, 다른 그림의 크기를 줄인 섬네일 파일인 것 같습니다.\n더 해상도가 좋은 파일이 있다면 그 파일을 올리거나 아니면 올리려는 파일 이름을 바꾸세요.",
+    "fileexists-thumbnail-yes": "파일은 그림의 크기를 줄인 (섬네일) 파일인 것 같습니다.\n[[$1|thumb]]\n<strong>[[:$1]]</strong> 파일을 확인하세요.\n해당 파일이 현재 올리려는 파일과 같다면 더 작은 크기의 그림을 올릴 필요는 없습니다.",
+    "file-thumbnail-no": "파일 이름이 <strong>$1</strong>으로 시작합니다.\n이 파일은 그림의 크기를 줄인 (섬네일) 파일인 것 같습니다.\n더 해상도가 좋은 파일이 있다면 그 파일을 올리거나 아니면 올리려는 파일 이름을 바꾸세요.",
     "fileexists-forbidden": "같은 이름의 파일이 이미 있고, 덮어쓸 수 없습니다.\n그래도 파일을 올리시려면, 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다.\n[[File:$1|thumb|center|$1]]",
     "fileexists-shared-forbidden": "같은 이름의 파일이 이미 위키미디어 공용에 있습니다.\n그래도 파일을 올리려면 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다.\n[[File:$1|thumb|center|$1]]",
     "file-exists-duplicate": "현재 올리고 있는 {{PLURAL:$1|파일}}이 아래 파일과 중복됩니다:",
     "listgrouprights-removegroup-self": "자신에게서 다음 {{PLURAL:$2|권한}}을 해제: $1",
     "listgrouprights-addgroup-self-all": "자신에게 모든 권한을 부여",
     "listgrouprights-removegroup-self-all": "자신의 계정에서 모든 권한을 해제",
-    "trackingcategories-name": "메시지",
+    "trackingcategories-name": "메시지 이름",
     "mailnologin": "보낼 이메일 주소가 없음",
     "mailnologintext": "다른 사용자에게 이메일을 보내려면 [[Special:UserLogin|로그인]]한 다음 [[Special:Preferences|사용자 환경 설정]]에서 자신의 이메일 주소를 저장해야 합니다.",
     "emailuser": "이메일 보내기",
     "emailmessage": "내용:",
     "emailsend": "보내기",
     "emailccme": "사본을 내 이메일로도 보내기",
-    "emailccsubject": "$1ì\97\90ê²\8c ë³´ë\82¸ ë©\94ì\9d¼ 사본: $2",
+    "emailccsubject": "$1ì\97\90ê²\8c ë³´ë\82¸ ë©\94ì\8b\9cì§\80ì\9d\98 ë³µ사본: $2",
     "emailsent": "이메일 보냄",
     "emailsenttext": "이메일을 보냈습니다.",
     "emailuserfooter": "이 이메일은 {{SITENAME}}의 $1 사용자가 $2 사용자에게 \"이메일 보내기\" 기능을 통해 보냈습니다.",
     "thumbnail_error_remote": "$1에서 반환한 오류 메시지:\n$2",
     "djvu_page_error": "DjVu 페이지 범위 벗어남",
     "djvu_no_xml": "DjVu 파일의 XML 정보를 읽을 수 없음",
-    "thumbnail-temp-create": "임시 섬네일 파일을 만들 수 없습니다.",
+    "thumbnail-temp-create": "임시 섬네일 파일을 만들 수 없습니다",
     "thumbnail-dest-create": "대상 경로에 섬네일을 저장할 수 없습니다.",
-    "thumbnail_invalid_params": "ì\84¬ë\84¤ì\9d¼ ë§¤ê°\9cë³\80ì\88\98ê°\80 ì\9e\98못ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤.",
+    "thumbnail_invalid_params": "ì\84¬ë\84¤ì\9d¼ ë³\80ì\88\98ê°\80 ì\9e\98못ë\90\98ì\97\88ì\8aµë\8b\88ë\8b¤",
     "thumbnail_dest_directory": "새 목적 디렉터리를 만들 수 없습니다.",
     "thumbnail_image-type": "그림 형식이 지원되지 않습니다",
     "thumbnail_gd-library": "GD 라이브러리 설정이 잘못되었습니다: $1 함수를 찾을 수 없습니다.",
     "api-error-illegal-filename": "이 파일 이름을 사용할 수 없습니다.",
     "api-error-internal-error": "내부 오류: 올린 파일을 위키에서 처리하는 중 어떤 문제가 발생했습니다.",
     "api-error-invalid-file-key": "내부 오류: 임시 저장소에서 파일을 찾지 못했습니다.",
-    "api-error-missingparam": "내부 오류: 요청 중 매개변수가 누락되었습니다.",
+    "api-error-missingparam": "내부 오류: 요청에 변수가 없습니다.",
     "api-error-missingresult": "내부 오류: 파일의 복제가 성공했는지 판단할 수 없습니다.",
     "api-error-mustbeloggedin": "파일을 올리려면 로그인해야 합니다.",
     "api-error-mustbeposted": "내부 오류: HTTP POST에 요청이 필요합니다.",
index afbf0ab..cc31857 100644 (file)
     "nstab-main": "Статья",
     "nstab-user": "Къошулуучуну бети",
     "nstab-media": "Мультимедиа",
-    "nstab-special": "Къуллукъчу бет",
+    "nstab-special": "Къуллукъ бет",
     "nstab-project": "Проектни бети",
     "nstab-image": "Файл",
     "nstab-mediawiki": "Билдириу",
     "nospecialpagetext": "<strong>Сиз излеген къуллукъ бет джокъду.</strong>\n\nБолгъан къуллукъ бетлени тизмеси: [[Special:SpecialPages|{{int:specialpages}}]].",
     "error": "Халат",
     "databaseerror": "Информация базада халат",
+    "databaseerror-query": "Соруулау: $1",
+    "databaseerror-error": "Халат: $1",
     "laggedslavemode": "Эс бёлюгюз! Бу бетге ахыр джангыртыула болмазгъа боллукъдула.",
     "readonly": "Информация база джабыкъды",
     "enterlockreason": "Блок этилиуню чурумун эм заманын белгилегиз.",
     "user-mail-no-body": "Бош неда магъанасыз къысха джазыу бла билдириу иерге изледи.",
     "changepassword": "Паролну ауушдур",
     "resetpass_announce": "Сиз, электрон почта бла ийилген, болджаллы пароль бла киргенсиз. Системагъа кириуню тамамларча, джангы пароль къурагъыз.",
+    "resetpass_text": "<!-- Текстни былайгъа къошугъуз -->",
     "resetpass_header": "Тергеу джазыуну (аккаунтну) паролун тюрлендириу",
     "oldpassword": "Эски пароль:",
     "newpassword": "Джангы пароль:",
     "changeemail-password": "«{{SITENAME}}» проектде паролугъуз:",
     "changeemail-submit": "Адресни тюрлендир",
     "changeemail-cancel": "Ызына алыу",
+    "resettokens-tokens": "Токенле:",
     "bold_sample": "Къалын джазыу",
     "bold_tip": "Къалын джазыу",
     "italic_sample": "Курсив джазыу",
     "compareselectedversions": "Сайланнган версияланы тенглешдириу",
     "showhideselectedversions": "Сайланнган версияланы кёргюз/джашыр",
     "editundo": "ызына алыу",
+    "diff-empty": "(башхалыкъ джокъ)",
     "diff-multi-manyusers": "($2 {{PLURAL:$2|къошулуучудан}} кёб этген {{PLURAL:$1|бир аралыкъ тюрлениу|$1 аралыкъ тюрлениу}} кёргюзюлмегенди)",
     "difference-missing-revision": "Бу тенглешдириу ($1) ючюн {{PLURAL:$2|бир версия|$2 версия}} {{PLURAL:$2|табылмады}}.\n\n\nБу, эскирген джибериу бла кетерилген бетни версияларын тенглешдириуге кёчген сагъатда кёбюсюне болады.\nТолуракъ информация [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} кетериулени журналында] болургъа боллукъду.",
     "searchresults": "Излеуню эсеби",
     "prefs-skin": "Джасауу",
     "skin-preview": "Ал къарау",
     "datedefault": "Сайлау джокъду",
-    "prefs-datetime": "Дата бла сагъат",
     "prefs-labs": "Эксперимент амалла",
     "prefs-user-pages": "Къошулуучуну бетлери",
     "prefs-personal": "Энчи билгиле",
     "recentchangesdays-max": "(максимум $1 {{PLURAL:$1|1=кюн|кюн}})",
     "recentchangescount": "Тынгылау бла кёргюзюллюк тюрлениулени саны:",
     "prefs-help-recentchangescount": "Бу, ахыр тюрлениулени, бетни тарихлерин эмда журналланы ичине къошады.",
+    "prefs-help-watchlist-token2": "Бу, сизни кёздеги тизмегизни веб-каналыны тахсалы ачхычыды.\nБу ачхычны билген хар ким да сизни кёздеги тизмегизни окъуяллыкъды, аны себебли башха кишиге билдирмегиз. [[Special:ResetTokens|Аны джиберирге керек эсе, былайдан басыгъыз]].",
     "savedprefs": "Джарашдырыуларыгъыз сакъландыла.",
     "timezonelegend": "Заман бел:",
     "localtime": "Джерли заман:",
     "prefs-dateformat": "Датаны форматы",
     "prefs-timeoffset": "Заманны офсети",
     "prefs-advancedediting": "Кенгленнген джарашдырыула",
+    "prefs-editor": "Редактор",
+    "prefs-preview": "ал къарау",
     "prefs-advancedrc": "Кенгленнген джарашдырыула",
     "prefs-advancedrendering": "Кенгленнген джарашдырыула",
     "prefs-advancedsearchoptions": "Кенгленнген джарашдырыула",
     "prefs-displaysearchoptions": "Кёрюнюуню джарашдырыулары",
     "prefs-displaywatchlist": "Кёрюнюуню джарашдырыулары",
     "prefs-diffs": "Версияланы башхалыкълары",
+    "prefs-help-prefershttps": "Бу джарашдырыу эндиги авторизацияны ётгенден сора сингдирилликди.",
     "email-address-validity-valid": "E-mail адрес тюзге ушайды",
     "email-address-validity-invalid": "Тюз e-mail адрес джазыгъыз!",
     "userrights": "Къошулуучуну хакъларына оноу этиу",
     "action-siteadmin": "билгилени базасын блокга салыу эм блокдан алыу",
     "action-sendemail": "E-mail джибериу",
     "nchanges": "$1 {{PLURAL:$1|тюрлениу|тюрлениу}}",
+    "enhancedrc-history": "тарих",
     "recentchanges": "Ахыр тюрлениуле",
     "recentchanges-legend": "Ахыр тюрлениулени джарашдырыулары",
     "recentchanges-summary": "Тюбюнде, Википедияда этилген ахыр тюрлениуле хронология бла тизилиб турадыла.",
     "listfiles_size": "Ёлчем",
     "listfiles_description": "Ачыкълау",
     "listfiles_count": "Версияла",
+    "listfiles-latestversion-yes": "Хоу",
+    "listfiles-latestversion-no": "Огъай",
     "file-anchor-link": "Файл",
     "filehist": "Файлны тарихи",
     "filehist-help": "Датагъа/заманнга басыгъыз, ол сагъатда файл къаллай болгъанын кёрюр ючюн.",
     "filehist-filesize": "Файлны ёлчеми",
     "filehist-comment": "Эсгериу",
     "imagelinks": "Файлны хайырланыуу",
-    "linkstoimage": "Бу файлгъа {{PLURAL:$1|1=бет|$1 бет}} джибередиле:",
+    "linkstoimage": "Бу файлгъа {{PLURAL:$1|бет|$1 бет}} джибередиле:",
     "linkstoimage-more": "$1 дегенден артыкъ {{PLURAL:$1|бет}} бу файлгъа джибериу береди.\nБу тизмеде бу файлгъа {{PLURAL:$1|къуру $1 джибериу}} кёргюзюледи.\n[[Special:WhatLinksHere/$2|Толу тизме]] да барды.",
     "nolinkstoimage": "Бу файлгъа джиберген бет джокъду.",
     "morelinkstoimage": "Бу файлгъа [[Special:WhatLinksHere/$1|къалгъан джибериулеге]] къара.",
     "unusedtemplateswlh": "башха джибериуле",
     "randompage": "Эсде болмагъан бет",
     "randompage-nopages": "{{PLURAL:$2|1=Ат аланында|Ат аланында}} чырт бир бет джокъду: $1.",
+    "randomincategory-selectcategory-submit": "Кёч",
     "randomredirect": "Сакъланмагъан джибериу",
     "randomredirect-nopages": "«$1» ат аланда чырт бир джибериу джокъду.",
     "statistics": "Статистика",
     "statistics-views-peredit": "Тюрлендириуге къарауну саны",
     "statistics-users": "Регистрация этилген [[Special:ListUsers|къошулуучула]]",
     "statistics-users-active": "Актив къошулуучула",
-    "statistics-users-active-desc": "Ахыр {{PLURAL:$1|1=1 кюнде|$1 кюнде}} ишлеме этген къошулуучула",
+    "statistics-users-active-desc": "Ахыр {{PLURAL:$1|кюнде|$1 кюнде}} ишлеме этген къошулуучула",
     "statistics-mostpopular": "Эм кёб къаралгъан бетле",
     "pageswithprop-submit": "Таб",
     "doubleredirects": "Джибериу болгъан джибериуле",
     "protectedpages-indef": "Къуру болджалсыз къоруу",
     "protectedpages-cascade": "Джангыз секиртме къоруу",
     "protectedpagesempty": "Бусагъатда бу параметрле бла джакъланнган бет джекъду.",
+    "protectedpages-page": "Бет",
+    "protectedpages-expiry": "Бошалыу датасы",
+    "protectedpages-reason": "Чурум",
+    "protectedpages-unknown-timestamp": "Билинмейди",
     "protectedtitles": "Джакъланнган башлыкъла",
     "protectedtitlesempty": "Бусагъатда, бу параметрле бла джакъланнган башлыкъ джокъду.",
     "listusers": "Къошулуучуланы тизмеси",
     "listgrouprights-removegroup-self": "кесини тергеу джазыуундан {{PLURAL:$2|1=къауум|къауумланы}} къораталлыкъды: $1",
     "listgrouprights-addgroup-self-all": "Бютеу къауумланы кесини тергеу джазыууна къошаллыкъды",
     "listgrouprights-removegroup-self-all": "Кесини тергеу джазыуундан бютеу къауумланы къораталлыкъды",
+    "listgrouprights-namespaceprotection-namespace": "Атла алам",
+    "trackingcategories-name": "Билдириуню аты",
     "mailnologin": "Джиберирге адрес джокъду",
     "mailnologintext": "Башха къошулуучулагъа эл. почта джиберелир ючюн [[Special:UserLogin|системагъа кирирге]] керексиз эм [[Special:Preferences|джарашдырыуланы]] бетинде джараулу эл. почта адрес болургъа керекди.",
     "emailuser": "Къошулуучугъа письмо",
     "tooltip-t-contributions": "Къошулуучуну тюрлендирген бетлерине къара",
     "tooltip-t-emailuser": "Бу къошулуучугъа письмо джибер",
     "tooltip-t-upload": "Файлланы джюклеу",
-    "tooltip-t-specialpages": "Бютеу къуллукъчу бетлени тизмеси",
+    "tooltip-t-specialpages": "Бютеу къуллукъ бетлени тизмеси",
     "tooltip-t-print": "Бу бетни басмагъа версиясы",
     "tooltip-t-permalink": "Бетни бу версиясына дайым джибериу",
     "tooltip-ca-nstab-main": "Статьяны ичиндеги",
     "tooltip-ca-nstab-user": "Къошулуучуну бетине къарау",
     "tooltip-ca-nstab-media": "Медиа-файл",
-    "tooltip-ca-nstab-special": "Бу къуллукъчу бетди, тюрлендирилмейди",
+    "tooltip-ca-nstab-special": "Бу къуллукъ бетди, тюрлендирилмейди",
     "tooltip-ca-nstab-project": "Проектни бетине къара",
     "tooltip-ca-nstab-image": "Файлны бетине къара",
     "tooltip-ca-nstab-mediawiki": "Система билдириуге къара",
     "specialpages": "Къуллукъ бетле",
     "specialpages-note": "* Тюз къуллукъ бетле.\n* <span class=\"mw-specialpagerestricted\">Кирирге эркинлик чекленнген къуллукъ бетле.</span>",
     "specialpages-group-maintenance": "Техника баджарыуну отчетлары",
-    "specialpages-group-other": "Башха къуллукъчу бетле",
+    "specialpages-group-other": "Башха къуллукъ бетле",
     "specialpages-group-login": "Системагъа кириу / Аккаунт къурау",
     "specialpages-group-changes": "Ахыр тюрлендириуле бла журналла",
     "specialpages-group-media": "Медиа-материалланы юсюнден отчетла бла джюклеуле",
     "specialpages-group-pages": "Бетлени тизмелери",
     "specialpages-group-pagetools": "Бет адырла",
     "specialpages-group-wiki": "Билгиле эм адырла",
-    "specialpages-group-redirects": "Ð\94жибеÑ\80ген ÐºÑ\8aÑ\83ллÑ\83кÑ\8aÑ\87Ñ\83 бетле",
+    "specialpages-group-redirects": "Ð\94жибеÑ\80иÑ\83Ñ\87Ñ\8e ÐºÑ\8aÑ\83ллÑ\83кÑ\8a бетле",
     "specialpages-group-spam": "Спамгъа къаршчы адырла",
     "blankpage": "Бош бет",
     "intentionallyblankpage": "Бу бет, иш этиб, бош къоюлгъанды.",
index b74d19f..24aeaa9 100644 (file)
     "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.\nVersicht et w.e.g. nach eng Kéier.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen.'''",
-    "session_fail_preview_html": "'''Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.'''\n\n''Well op {{SITENAME}} ''raw HTML'' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.''\n\n'''Wann dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen.'''",
+    "session_fail_preview_html": "<strong>Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.</strong>\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.\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen.</strong>",
     "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",
     "prefs-skin": "Skin",
     "skin-preview": "Kucken",
     "datedefault": "Egal (Standard)",
-    "prefs-datetime": "Datum an Auerzäit",
     "prefs-labs": "\"Labs\"-Funktiounen",
     "prefs-user-pages": "Benotzersäiten",
     "prefs-personal": "Benotzerprofil",
     "enhancedrc-history": "Versiounen",
     "recentchanges": "Rezent Ännerungen",
     "recentchanges-legend": "Optioune vun de rezenten Ännerungen",
-    "recentchanges-summary": "Op dëser Säit kënnt Dir déi rezent Ännerungen op '''{{SITENAME}}''' gesinn.",
+    "recentchanges-summary": "Op dëser Säit kënnt Dir déi rezent Ännerungen op dëser Wiki gesinn.",
     "recentchanges-noresult": "Keng Ännerunge während der Period déi ugi gouf passen op de Critère.",
     "recentchanges-feed-description": "Verfollegt mat dësem Feed déi rezent Ännerungen op {{SITENAME}}.",
     "recentchanges-label-newpage": "Dës Ännerung huet eng nei Säit ugeluecht",
     "download": "eroflueden",
     "unwatchedpages": "Net iwwerwaacht Säiten",
     "listredirects": "Lëscht vun de Viruleedungen",
+    "listduplicatedfiles": "Lëscht vu Fichiere mat Doublonen",
     "listduplicatedfiles-entry": "[[:File:$1|$1]] huet [[$3|{{PLURAL:$2|een Doublon|$2 Doublonen}}]].",
     "unusedtemplates": "Net benotzt Schablounen",
     "unusedtemplatestext": "Op dëser Säit stinn all Säiten aus dem {{ns:template}} Nummraum, déi a kenger anerer Säit benotzt ginn. Vergiesst net nozekucken, ob et keng aner Linken op dës Schabloune gëtt, ier Dir eng Schabloun läscht.",
     "listgrouprights-removegroup-self": "Däerf {{PLURAL:$2|de Grupp|d'Gruppe}} vu sengem eegene Benotzerkont ewechhuelen: $1",
     "listgrouprights-addgroup-self-all": "däerf all Gruppe bei säin eegene Benotzerkont derbäisetzen",
     "listgrouprights-removegroup-self-all": "Däerf all Gruppe vu sengem eegene Benotzerkont ewechhuelen",
+    "listgrouprights-namespaceprotection-header": "Limitatioune vum Nummraum",
+    "listgrouprights-namespaceprotection-namespace": "Nummraum",
+    "listgrouprights-namespaceprotection-restrictedto": "Recht(er), déi dem Benotzer d'Änneren erlaben",
     "trackingcategories-name": "Numm vum Message",
+    "noindex-category-desc": "D'Säit gëtt net vu Botten indexéiert, well dat magescht Wuert <code><nowiki>__NOINDEX__</nowiki></code> dran ass a well se an engem Nummraum ass, an deem déi Markéierung erlaabt ass.",
+    "hidden-category-category-desc": "Dëst ass eng Kategorie an där <code><nowiki>__HIDDENCAT__</nowiki></code> drasteet, dat verhënnert datt se standardméisseg an der këscht mat de Kategorielinken op der Säit gewise gëtt.",
     "trackingcategories-nodesc": "Keng Beschreiwung disponibel.",
     "trackingcategories-disabled": "Kategorie ass desaktivéiert",
     "mailnologin": "Keng E-Mailadress",
     "unwatchthispage": "Net méi iwwerwaachen",
     "notanarticle": "Keng Säit",
     "notvisiblerev": "Versioun gouf geläscht",
-    "watchlist-details": "{{PLURAL:$1|1 Säit|$1 Säiten}} sinn op ärer Iwwerwaachungsklëscht (d'Diskussiounssäite net matgezielt).",
+    "watchlist-details": "{{PLURAL:$1|1 Säit|$1 Säiten}} sinn op ärer Iwwerwaachungsklëscht, d'Diskussiounssäiten net matgezielt.",
     "wlheader-enotif": "E-Mail-Notifikatioun ass ageschalt.",
     "wlheader-showupdated": "Säiten déi zanter Ärer leschter Visite geännert goufen, si '''fett''' geschriwwen",
     "watchmethod-recent": "Rezent Ännerunge ginn op iwwerwaacht Säiten iwwerpréift",
     "sp-contributions-newbies-sub": "Fir déi Nei",
     "sp-contributions-newbies-title": "Kontributioune vun neie Benotzer",
     "sp-contributions-blocklog": "Spärlescht",
+    "sp-contributions-suppresslog": "geläscht Benotzerkontributiounen",
     "sp-contributions-deleted": "geläscht Kontributiounen",
     "sp-contributions-uploads": "Eropgeluede Fichieren",
     "sp-contributions-logs": "Logbicher",
     "filedelete-archive-read-only": "Op den Archiv-Repertoire „$1“ ka vum Webserver aus näischt geschriwwe ginn.",
     "previousdiff": "← Méi al Ännerung",
     "nextdiff": "Méi nei Ännerung →",
-    "mediawarning": "'''Warnung:''' Dës Zort vu Fichier kann e béiswëllege Programmcode enthalen.\nDuerch d'Opmaache vum Fichier kann Äre System beschiedegt ginn.",
+    "mediawarning": "<strong>Warnung:</strong> Dës Zort vu Fichier kann e béiswëllege Programmcode enthalen.\nDuerch d'Opmaache vum Fichier kann Äre System beschiedegt ginn.",
     "imagemaxsize": "Maximal Gréisst fir Biller:<br />''(fir Billerbeschreiwungssäiten)''",
     "thumbsize": "Gréisst vun der Miniatur:",
     "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|Säit|Säiten}}",
     "file-info-png-repeat": "gouf $1 {{PLURAL:$1|mol|mol}} gespillt",
     "file-info-png-frames": "$1 {{PLURAL:$1|Frame|Framen}}",
     "file-no-thumb-animation": "''''Informatioun: Wéinst technesche Limitatioune sinn d'Miniatur-Biller vun dësem Fichier net animéiert.'''",
-    "file-no-thumb-animation-gif": "'''Hiweis: Aus technesche Grënn gi Miniature mat enger héijer Opléisung vu GIF Biller, sou wéi dëst, net animéiert.'''",
+    "file-no-thumb-animation-gif": "<strong>Hiweis: Aus technesche Grënn gi Miniature mat enger héijer Opléisung vu GIF Biller, sou wéi dëst, net animéiert.</strong>",
     "newimages": "Gallerie vun den neie Biller",
     "imagelisttext": "Hei ass eng Lëscht vu(n) '''$1''' {{PLURAL:$1|Fichier|Fichieren}}, zortéiert $2.",
     "newimages-summary": "Dës Spezialsäit weist eng Lëscht mat de Fichieren déi als lescht eropgeluede goufen.",
index c34fc7f..5755ddc 100644 (file)
@@ -26,7 +26,8 @@
             "Vilius2001",
             "Vpovilaitis",
             "Xabier Armendaritz",
-            "לערי ריינהארט"
+            "לערי ריינהארט",
+            "Vogone"
         ]
     },
     "tog-underline": "Pabraukti nuorodas:",
     "accountcreatedtext": "Naudotojo paskyra [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) buvo sukurta.",
     "createaccount-title": "{{SITENAME}} paskyros kūrimas",
     "createaccount-text": "Projekte {{SITENAME}} ($4) kažkas sukūrė paskyrą „$2“ su slaptažodžiu „$3“ panaudodamas jūsų el. pašto adresą.\nJūs turėtumėte prisijungti ir pasikeisti savo slaptažodį.\n\nJūs galite nekreipti dėmesio į laišką, jei ši paskyra buvo sukurta per klaidą.",
-    "usernamehasherror": "Naudotojo vardas negali turėti grotelių simbolio",
     "login-throttled": "Jūs pernelyg daug kartų bandėte prisijungti.\nPalaukite prieš bandant vėl.",
     "login-abort-generic": "Jūsų prisijungimas buvo nesėkmingas - Nutraukta",
     "loginlanguagelabel": "Kalba: $1",
     "prefs-skin": "Išvaizda",
     "skin-preview": "Peržiūra",
     "datedefault": "Jokio pasirinkimo",
-    "prefs-datetime": "Data ir laikas",
     "prefs-labs": "Bandomosios funkcijos",
     "prefs-user-pages": "Naudotojo puslapiai",
     "prefs-personal": "Naudotojo profilis",
     "upload-permitted": "Leidžiami failų tipai: $1.",
     "upload-preferred": "Pageidautini failų tipai: $1.",
     "upload-prohibited": "Uždrausti failų tipai: $1.",
-    "uploadlog": "įkėlimų sąrašas",
     "uploadlogpage": "Įkėlimų sąrašas",
     "uploadlogpagetext": "Žemiau pateikiamas paskutinių failų įkėlimų sąrašas.\nTaip pat galite peržvelgti [[Special:NewFiles|naujausių failų galeriją]].",
     "filename": "Failo vardas",
     "filereuploadsummary": "Failo pakeitimai:",
     "filestatus": "Autorystės teisės:",
     "filesource": "Šaltinis:",
-    "uploadedfiles": "Įkelti failai",
     "ignorewarning": "Ignoruoti įspėjimą ir išsaugoti failą vistiek.",
     "ignorewarnings": "Ignuoruoti bet kokius įspėjimus",
     "minlength1": "Failo pavadinimas turi būti bent viena raidė.",
     "overwroteimage": "įkėlė naują „[[$1]]“ versiją",
     "uploaddisabled": "Įkėlimai uždrausti",
     "copyuploaddisabled": "Įkėlimas pagal URL išjungtas.",
-    "uploadfromurl-queued": "Jūsų įkėlimas įtrauktas į eilę.",
     "uploaddisabledtext": "Failų įkėlimai yra uždrausti.",
     "php-uploaddisabledtext": "Failų įkėlimai uždrausti PHP nustatymuose.\nPatikrinkite ''file_uploads'' nustatą.",
     "uploadscripted": "Šis failas turi HTML arba programinį kodą, kuris gali būti klaidingai suprastas interneto naršyklės.",
     "upload-misc-error": "Nežinoma įkėlimo klaida",
     "upload-misc-error-text": "Įvyko nežinoma klaida vykstant įkėlimui. Prašome patikrinti, kad URL teisingas bei pasiekiamas ir pamėginkite vėl. Jei problema lieka, susisiekite su [[Special:ListUsers/sysop|administratoriumi]].",
     "upload-too-many-redirects": "URL yra per daug kartų peradresuotas",
-    "upload-unknown-size": "Nežinomas dydis",
     "upload-http-error": "Įvyko HTTP klaida: $1",
     "upload-copy-upload-invalid-domain": "Pakrovimų kopijos yra neleidžiamos iš šio domeno.",
     "backend-fail-stream": "Negali būti apdorotas failas $1.",
     "img-auth-streaming": "Siunčiamas „$1“.",
     "img-auth-public": "img_auth.php paskirtis yra pateikti failus iš privačių projektų.\nŠis projektas sukonfigūruotas kaip viešasis.\nDėl saugumo, img_auth.php yra išjungtas.",
     "img-auth-noread": "Naudotojas neturi teisės peržiūrėti „$1“.",
-    "img-auth-bad-query-string": "URL neteisingas užklausos eilutę.",
     "http-invalid-url": "Neleistinas URL: $1",
     "http-invalid-scheme": "URL su priedėliu „$1“ nepalaikomi.",
     "http-request-error": "HTTP užklausa nepavyko dėl nežinomos klaidos.",
     "filehist-dimensions": "Matmenys",
     "filehist-filesize": "Failo dydis",
     "filehist-comment": "Komentaras",
-    "filehist-missing": "Failo nėra",
     "imagelinks": "Failų panaudojimas",
     "linkstoimage": "{{PLURAL:$1|Šis puslapis|Šie puslapiai}} nurodo į šį failą:",
     "linkstoimage-more": "Daugiau nei $1 {{PLURAL:$1|puslapis|puslapiai|puslapių}} rodo į šį failą.\nŠis sąrašas rodo tik {{PLURAL:$1|puslapio|pirmų $1 puslapių}} nuorodas į šį failą.\nYra pasiekiamas ir [[Special:WhatLinksHere/$2|visas sąrašas]].",
     "emailuser-title-notarget": "El. pašto vartotojas",
     "emailpage": "Siųsti el. laišką naudotojui",
     "emailpagetext": "Jūs gali pasinaudoti šia forma norėdami nusiųsti el. laišką šiam naudotojui.\nEl. pašto adresas, kurį įvedėte [[Special:Preferences|savo naudotojo nustatymuose]], bus rodomas kaip el. pašto siuntėjo adresas, tam, kad gavėjas galėtų jums iškart atsakyti.",
-    "usermailererror": "Pašto objektas grąžino klaidą:",
     "defemailsubject": "{{SITENAME}} el. pašto iš vartotojo \" $1 \"",
     "usermaildisabled": "Naudotojo elektroninis paštas išjungtas",
     "usermaildisabledtext": "Jūs negalite siūlsti el. laiško kitiems šio wiki projekto naudotojams.",
     "noemailtitle": "Nėra el. pašto adreso",
     "noemailtext": "Šis naudotojas nėra nurodęs teisingo el. pašto adreso, arba yra pasirinkęs negauti el. pašto iš kitų naudotojų.",
-    "nowikiemailtitle": "El. laiškai neleidžiami",
     "nowikiemailtext": "Šis naudotojas yra pasirinkęs negauti elektroninių laiškų iš kitų naudotojų.",
     "emailnotarget": "Nesamas arba neteisingas vartotojo vardas gavėjui.",
     "emailtarget": "Įveskite vartotojo vardą gavėjo",
     "watching": "Įtraukiama į stebimųjų sąrašą...",
     "unwatching": "Šalinama iš stebimųjų sąrašo...",
     "watcherrortext": "Keičiant jūsų stebėjimo nustatymus puslapiui „$1“ įvyko klaida.",
-    "enotif_mailer": "{{SITENAME}} Pranešimų sistema",
     "enotif_reset": "Pažymėti visus puslapius kaip aplankytus",
     "enotif_impersonal_salutation": "{{SITENAME}} naudotojau",
     "enotif_subject_deleted": "{{GENDER:$2|Naudotojas}} ištrynė puslapį $1, priklausantį projektui {{SITENAME}}",
     "excontent": "buvęs turinys: „$1“",
     "excontentauthor": "buvęs turinys: „$1“ (redagavo tik „[[Special:Contributions/$2|$2]]“)",
     "exbeforeblank": "prieš ištrinant turinys buvo: „$1“",
-    "exblank": "puslapis buvo tuščias",
     "delete-confirm": "Ištrinti „$1“",
     "delete-legend": "Trynimas",
     "historywarning": "'''Dėmesio:''' Trinamas puslapis turi istoriją su maždaug $1 {{PLURAL:$1|versija|versijomis|versijų}}:",
     "importunknownsource": "Nežinomas importo šaltinio tipas",
     "importcantopen": "Nepavyksta atverti importo failo",
     "importbadinterwiki": "Bloga tarpprojektinė nuoroda",
-    "importnotext": "Tuščia arba jokio teksto",
     "importsuccess": "Importas užbaigtas!",
-    "importhistoryconflict": "Yra konfliktuojanti istorijos versija (galbūt šis puslapis buvo importuotas anksčiau)",
     "importnosources": "Nenustatyti transwiki importo šaltiniai, o tiesioginis praeities įkėlimas uždraustas.",
     "importnofile": "Nebuvo įkeltas joks importo failas.",
     "importuploaderrorsize": "Importavimo failo įkėlimas nepavyko. Failas didesnis nei leidžiamas dydis.",
     "tags": "Leistinos keitimų žymės",
     "tag-filter": "[[Special:Tags|Žymų]] filtras:",
     "tag-filter-submit": "Filtras",
+    "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Žyma|Žymos}}]]: $2)",
     "tags-title": "Žymos",
     "tags-intro": "Šiame puslapyje yra žymų, kuriomis programinė įranga gali pažymėti keitimus, sąrašas bei jų reikšmės.",
     "tags-tag": "Žymos pavadinimas",
index 30a0807..a55ee5c 100644 (file)
     "prefs-skin": "Apdare",
     "skin-preview": "Priekšskats",
     "datedefault": "Vienalga",
-    "prefs-datetime": "Datums un laiks",
     "prefs-labs": "Laboratorijas funkcijas",
     "prefs-user-pages": "Lietotāja lapas",
     "prefs-personal": "Lietotāja dati",
index 119314f..eeda04c 100644 (file)
     "prefs-skin": "面版",
     "skin-preview": "草覽",
     "datedefault": "原註",
-    "prefs-datetime": "日時",
     "prefs-personal": "概簿",
     "prefs-rc": "近易",
     "prefs-watchlist": "哨站",
index 6224762..36b85bc 100644 (file)
     "prefs-skin": "Руво",
     "skin-preview": "Преглед",
     "datedefault": "Небитно",
-    "prefs-datetime": "Датум и време",
     "prefs-labs": "Експериментални можности",
     "prefs-user-pages": "Кориснички страници",
     "prefs-personal": "Кориснички профил",
     "statistics-header-hooks": "Други статистики",
     "statistics-articles": "Статии",
     "statistics-pages": "Страници",
-    "statistics-pages-desc": "Сите страници на викито, вклучувајќи и страници за разговор, пренасочувања, и.т.н.",
+    "statistics-pages-desc": "Сите страници на викито, вклучувајќи страници за разговор, пренасочувања и тн.",
     "statistics-files": "Подигнати податотеки",
     "statistics-edits": "Број на уредувања од започнувањето на {{SITENAME}}",
     "statistics-edits-average": "Просечен број на уредувања по страница",
     "unwatchthispage": "Престани набљудување",
     "notanarticle": "Не е статија",
     "notvisiblerev": "Преработката била избришана",
-    "watchlist-details": "{{PLURAL:$1|$1 страница|$1 страници}} во вашиот список на набљудувања, не броејќи ги страниците за разговор.",
+    "watchlist-details": "{{PLURAL:$1|$1 страница|$1 страници}} во вашиот список на набљудувања, не броејќи ги посебно страниците за разговор.",
     "wlheader-enotif": "Известувањето по е-пошта е вклучено.",
     "wlheader-showupdated": "Страниците што се изменети од вашата последна посета се прикажани со '''задебелени''' букви",
     "watchmethod-recent": "Проверка на скорешните уредувања на набљудуваните страници",
     "contributions-title": "Придонеси на корисникот $1",
     "mycontris": "придонеси",
     "contribsub2": "За {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "Корисничката сметка „$1“ не е регистрирана.",
     "nocontribs": "Не се пронајдени промени што одговараат на овој критериум.",
     "uctop": "(тековно)",
     "month": "Од месец (и порано):",
index 86c4c12..501f2e9 100644 (file)
     "prefs-skin": "ദൃശ്യരൂപം",
     "skin-preview": "എങ്ങനെയുണ്ടെന്നു കാണുക",
     "datedefault": "ക്രമീകരണങ്ങൾ വേണ്ട",
-    "prefs-datetime": "ദിവസവും സമയവും",
     "prefs-labs": "പരീക്ഷണശാലയിൽ തയ്യാറാകുന്ന സൗകര്യങ്ങൾ",
     "prefs-user-pages": "ഉപയോക്തൃതാളുകൾ",
     "prefs-personal": "എന്നെപ്പറ്റി",
index 6e75084..80ecb78 100644 (file)
     "november-date": "Арван нэгдүгээр сарын $1",
     "december-date": "Арван хоёрдугаар сарын $1",
     "pagecategories": "{{PLURAL:$1|Анги|Ангилал}}",
-    "category_header": "\"$1\" Ð°Ð½Ð³Ð¸Ð»Ð°Ð» Ð´Ð°Ñ\85Ñ\8c Ñ\85Ñ\83Ñ\83даÑ\81нÑ\83Ñ\83д",
+    "category_header": "\"$1\" Ð°Ð½Ð³Ð¸Ð¹Ð½ Ð´Ð°Ð½ Ñ\85Ñ\83Ñ\83даÑ\81",
     "subcategories": "Ангийн бүлэг",
     "category-media-header": "\"$1\" ангийн файл",
     "category-empty": "''Одоогийн байдлаар энэ ангилалд хуудас, медиа файл байхгүй байна.''",
     "hidden-categories": "{{PLURAL:$1|Нуугдсан ангилал|Нуугдсан ангиллууд}}",
     "hidden-category-category": "Нуугдсан ангиллууд",
-    "category-subcat-count": "{{PLURAL:$2|ЭнÑ\8d Ð°Ð½Ð³Ð¸Ð»Ð°Ð»Ð´ Ð´Ð°Ñ\80ааÑ\85 Ð´Ñ\8dд Ð°Ð½Ð³Ð¸Ð»Ð°Ð» Ð» Ð±Ð°Ð¹Ð½Ð°.|ЭнÑ\8d Ð°Ð½Ð³Ð¸Ð»Ð°Ð»Ð´ Ð½Ð¸Ð¹Ñ\82 $2-Ñ\81 Ð´Ð°Ñ\80ааÑ\85 $1 Ð´Ñ\8dд Ð°Ð½Ð³Ð¸Ð»Ð°Ð» Ð±Ð°Ð¹на.}}",
+    "category-subcat-count": "{{PLURAL:$2|ТÑ\83Ñ\81 Ð°Ð½Ð³Ð¸Ð´ Ð´Ð°Ñ\80ааÑ\85 Ð°Ð½Ð³Ð¸Ð¹Ð½ Ñ\85Ñ\83Ñ\83дÑ\81Ñ\83Ñ\83д Ñ\85амааÑ\80на.|ТÑ\83Ñ\81 Ð°Ð½Ð³Ð¸Ð´ Ð´Ð°Ñ\80ааÑ\85 $2 Ð°Ð½Ð³Ð¸Ð¹Ð½ Ñ\85Ñ\83Ñ\83дÑ\81Ñ\83Ñ\83д Ñ\85амааÑ\80на.}}",
     "category-subcat-count-limited": "Энэ ангилалд {{PLURAL:$1| дэд ангилал|$1-н дэд ангилалууд}} байна.",
-    "category-article-count": "{{PLURAL:$2|Энд нэг хуудас байна.|Энэ ангид $2 хуудас байна.}}\n\n{{PLURAL:$2|Энэ ангилалд дараах хуудас л байна.|Энэ ангилалд нийт $2-с дараах $1 хуудас байна.}}",
+    "category-article-count": "{{PLURAL:$2|Энэ ангид дараах хуудас хамаарна.|Энэ ангид дараах $2 хуудас хамаарна.}}",
     "category-article-count-limited": "Энэ ангилалд дараах {{PLURAL:$1|хуудас|$1 хуудаснууд}} байна.",
     "category-file-count": "{{PLURAL:$2|Энэ ангилалд дараах файл л байна.|Энэ ангилалд нийт $2-с дараах $1 файл байна.}}",
     "category-file-count-limited": "Энэ ангилалд дараах {{PLURAL:$1|файл|$1 файлнууд}} байна.",
     "accountcreatedtext": "$1 хэрэглэгчийн бүртгэл үүсгэгдлээ.",
     "createaccount-title": "{{SITENAME}}-н бүртгэлийн үүсгэл",
     "createaccount-text": "Хэн нэгэн {{SITENAME}}-д ($4) \"$2\" гэсэн нэрээр, \"$3\" гэсэн нууц үгтэйгээр таны мэйл хаягийг ашиглан бүртгүүлжээ.\nТа одоо нэвтэрч өөрийн нууц үгээ солих хэрэгтэй.\n\nХэрэв буруугаар бүртгүүлсэн бол энэ мэдэгдлийг үл ойшоож болно.",
-    "usernamehasherror": "Хэрэглэгчийн нэрэнд хаш тэмдэгт орж болохгүй",
     "login-throttled": "Та хэт олон удаа нэвтрэх гэж оролдсон байна.\n$1 хүлээж байгаад дахин оролдоно уу.",
     "login-abort-generic": "Та нэвтэрч чадсангүй",
     "loginlanguagelabel": "Хэл: $1",
     "prefs-skin": "Арьс",
     "skin-preview": "Урьдчилж харах",
     "datedefault": "Анхны байдал",
-    "prefs-datetime": "Огноо ба цаг",
     "prefs-labs": "Labs -ын функцүүд",
     "prefs-user-pages": "Хэрэглэгчийн хуудсууд",
     "prefs-personal": "Хувийн тохируулга",
     "upload-permitted": "Оруулж болох файлын төрлүүд: $1.",
     "upload-preferred": "Хэрэглэхийг зөвлөж буй файлын төрлүүд: $1.",
     "upload-prohibited": "Оруулж болохгүй файлын төрлүүд: $1.",
-    "uploadlog": "файл оруулалтын лог",
     "uploadlogpage": "Файл оруулалтын лог",
     "uploadlogpagetext": "Доорх нь хамгийн сүүлд оруулсан файлуудын жагсаалт юм.\n[[Special:NewFiles|Шинэ файлуудын үзэсгэлэн]] дээр жагсаалтыг зурган байдлаар харуулсан байгаа.",
     "filename": "Файлын нэр",
     "filereuploadsummary": "Файлын өөрчлөлтүүд:",
     "filestatus": "Зохиогчийн эрхийн байдал:",
     "filesource": "Эх үүсвэр:",
-    "uploadedfiles": "Оруулагдсан файлууд",
     "ignorewarning": "Анхааруулгыг үл тоомсорлон файлыг хадгалах",
     "ignorewarnings": "Ямар ч анхааруулгыг үл тоомсорлох",
     "minlength1": "Файлын нэрүүд доод тал нь нэг үсгийн урттай байх ёстой.",
     "overwroteimage": "\"[[$1]]\"-н шинэ хувилбарыг орууллаа",
     "uploaddisabled": "Файл оруулах боломжгүй байна.",
     "copyuploaddisabled": "URL-аас оруулж болохгүй.",
-    "uploadfromurl-queued": "Таны оруулалсан файлыг оруулах дараалалд нэмэв.",
     "uploaddisabledtext": "Файл оруулалтуудыг идэвхижүүлээгүй байна.",
     "php-uploaddisabledtext": "PHP-д файл оруулахыг хориглоно.\nfile_uploads тохиргоогоо шалгана уу.",
     "uploadscripted": "Энэ файл нь вэб броузераас шалтгаалж алдаатай уншигдах магадлал бүхий HTML буюу скрипт код агуулсан байна.",
     "upload-misc-error": "Мэдэгдэхгүй файл оруулалтын алдаа",
     "upload-misc-error-text": "Файл оруулахад үл мэдэгдэх алдаа гарлаа.\nURL нь хүчинтэй, мөн түүн руу орж болж байгаа эсэхийг шалган, дахин оролдож үзнэ үү.\nЭнэ асуудал үргэлжилсээр байвал [[Special:ListUsers/sysop|администраторт]] хандана уу.",
     "upload-too-many-redirects": "URL-д хэт олон чиглүүлэгч байв",
-    "upload-unknown-size": "Үл мэдэгдэх хэмжээ",
     "upload-http-error": "HTTP алдаа гарав: $1",
     "upload-copy-upload-invalid-domain": "Энэ хаяг дээрээс хуулах боломжгүй байна.",
     "backend-fail-stream": "$1 файлыг дамжуулж чадсангүй.",
     "filehist-dimensions": "Хэмжээ",
     "filehist-filesize": "Файлын хэмжээ",
     "filehist-comment": "Тайлбар",
-    "filehist-missing": "Файл байхгүй байна",
     "imagelinks": "Файлын хэрэглээ",
     "linkstoimage": "Дараах {{PLURAL:$1|хуудас уг файлтай|$1 хуудас уг файлтай}} холбогдсон байна:",
     "linkstoimage-more": "$1-с их зураг энэ файлд холбогдсон байна.\nДараах жагсаалт нь энэ файлд холбогдсон эхний $1 хуудсыг л харуулна.\n[[Special:WhatLinksHere/$2|Бүтэн жагсаалт]] мөн байгаа.",
     "cachedspecial-refresh-now": "Саяханы хуудсыг харах",
     "categories": "Ангиллууд",
     "categoriespagetext": "Дараах {{PLURAL:$1|ангилалд|ангиллуудад}} хуудас эсвэл медиа файл агуулагдаж байна.\n[[Special:UnusedCategories|Хэрэглэгдэхгүй байгаа]] ангиллуудыг энд харуулсангүй.\n[[Special:WantedCategories|Хэрэгтэй ангиллууд]] гэдгийг харна уу.",
-    "categoriesfrom": "Эхний ангилал:",
+    "categoriesfrom": "Эхний анги:",
     "special-categories-sort-count": "тоогоор ялгах",
     "special-categories-sort-abc": "үсгийн дарааллаар ялгах",
     "deletedcontributions": "Устгагдсан хэрэглэгчийн хувь нэмэр",
     "emailuser-title-notarget": "И-мейл хэрэглэгч",
     "emailpage": "Хэрэглэгчид мэйл илгээх",
     "emailpagetext": "Энэ хэрэглэгч рүү мэйл илгээхэд доорхийг бөглөнө.\nТаны өөрийн [[Special:Preferences|хэрэглэгчийн тохиргоонд]] оруулсан мэйл хаяг нь \"Хэнээс\" гэсэн хэсэгт гарах тул хүлээн авагч хариугаа тань руу шууд илгээх боломжтой.",
-    "usermailererror": "Мэйл нь буцаж ирсэн шалтгаан:",
     "defemailsubject": "{{SITENAME}} дахь \"$1\" хэрэглэгчийн и-мэйл хаяг",
     "usermaildisabled": "Хэрэглэгчийн и-мэйлийг идэвхигүйжүүлэв",
     "usermaildisabledtext": "Та энэ викигийн бусад хэрэглэгч руу и-мэйл явуулах боломжгүй",
     "noemailtitle": "Мэйл хаяггүй байна",
     "noemailtext": "Энэ хэрэглэгч хүчинтэй и-мэйл хаяг тохируулаагүй байна.",
-    "nowikiemailtitle": "Мэйл зөвшөөрөгдөхгүй",
     "nowikiemailtext": "Энэ хэрэглэгч бусад хэрэглэгчдээс мэйл хүлээж авахгүй гэсэн байна.",
     "emailtarget": "Хүлээн авагчийн хэрэглэгчийн нэрийг оруулах",
     "emailusername": "Хэрэглэгчийн нэр:",
     "watchlist-options": "Хянаж буй хуудсуудын жагсаалтны сонголтууд",
     "watching": "Хянаж байна...",
     "unwatching": "Хянахаа больж байна...",
-    "enotif_mailer": "{{SITENAME}}-н мэйл сонордуулга",
     "enotif_reset": "Бүх хуудсыг үзсэн гэж тэмдэглэх",
     "enotif_impersonal_salutation": "{{SITENAME}}-н хэрэглэгч",
     "enotif_lastvisited": "$1-н хамгийн сүүлд зочилсноос хойших өөрчлөлтүүдийг харуул.",
     "excontent": "агуулга нь ийм байсан: '$1'",
     "excontentauthor": "агуулга нь ийм байсан: '$1' (цорын ганц хувь нэмэрлэгч нь '[[Special:Contributions/$2|$2]]')",
     "exbeforeblank": "хоосон болгохын өмнөх агуулга: '$1'",
-    "exblank": "хуудас нь хоосон байсан",
     "delete-confirm": "\"$1\"-г устгах",
     "delete-legend": "Устгах",
     "historywarning": "'''Анхаар''': Таны устгах гэж байгаа хуудас $1 орчим засвар бүхий түүхтэй байна:",
     "importunknownsource": "Мэдэгдээгүй төрлийн импортлох эх үүсвэр",
     "importcantopen": "Импортлосон файлыг нээж чадсангүй",
     "importbadinterwiki": "Интервикигийн хүчингүй холбоос",
-    "importnotext": "Хоосон эсвэл текст байхгүй",
     "importsuccess": "Амжилттай импортлолоо!",
-    "importhistoryconflict": "Өмнөх хувилбар нь оршин байгаа эсэх нь харшилдаж байна(магадгүй өмнө нь импотлосон хуудас байж болзошгүй)",
     "importnosources": "Транс-викигийн импортын эх үүсвэрүүд тодорхойлогдоогүй байгаа бөгөөд түүхийг шууд оруулах явдлыг хаасан байна.",
     "importnofile": "Имтортлосон файл хуулагдаагүй байна.",
     "importuploaderrorsize": "Импортлогдсон файлыг оруулж чадсангүй. Файлыг хэмжээ зөвшөөрөгдсөн хэмжээнээс том байна.",
index 5a7dc09..4aabc37 100644 (file)
     "prefs-skin": "Phôe",
     "skin-preview": "Chhì khoàⁿ",
     "datedefault": "Chhìn-chhái",
-    "prefs-datetime": "Ji̍t-kî kap sî-kan",
     "prefs-personal": "Iōng-chiá chu-liāu",
     "prefs-rc": "Chòe-kīn ê kái-piàn & stub ê hián-sī",
     "prefs-watchlist": "Kàm-sī-toaⁿ",
index 1c022f4..245600f 100644 (file)
     "pool-timeout": "Tidsavbudd mens man ventet på låsing",
     "pool-queuefull": "Prosesskøen er full",
     "pool-errorunknown": "Ukjent feil",
-    "pool-servererror": "Pool-teller tjenesten er ikke tilgjengelig ($1).",
+    "pool-servererror": "'Pool counter'-tjenesten er ikke tilgjengelig ($1).",
     "aboutsite": "Om {{SITENAME}}",
     "aboutpage": "Project:Om",
     "copyright": "Innholdet er tilgjengelig under $1 med mindre annet er spesifikt angitt.",
     "prefs-skin": "Utseende",
     "skin-preview": "Forhåndsvisning",
     "datedefault": "Ingen foretrukket",
-    "prefs-datetime": "Dato og tid",
     "prefs-labs": "Lab-funksjoner",
     "prefs-user-pages": "Brukersider",
     "prefs-personal": "Brukerdata",
     "trackingcategories-msg": "Sporingskategori",
     "trackingcategories-name": "Beskjednavn",
     "trackingcategories-desc": "Kategori-inklusjonskriterium",
-    "noindex-category-desc": "Denne siden er påført et <code><nowiki>__NOINDEX__</nowiki></code> magisk ord (og er i et navnerom hvor det flagget er tillatt), og blir derfor ikke indeksert av roboter.",
-    "index-category-desc": "Denne siden er påført et <code><nowiki>__INDEX__</nowiki></code> magisk ord (og er i et navnerom hvor det flagget er tillatt), og vil derfor bli indeksert av roboter mens det normalt ikke vil skje.",
-    "post-expand-template-inclusion-category-desc": "Etter ekspandering av alle malene, så er siden større enn <code>$wgMaxArticleSize</code>, så noen maler er ikke ekspandert.",
+    "noindex-category-desc": "Denne siden indekseres ikke av roboter fordi den er merket med det magiske ordet <code><nowiki>__NOINDEX__</nowiki></code> og er i navnerom der dette flagget tillates.",
+    "index-category-desc": "Denne siden er påført det magiske ordet <code><nowiki>__INDEX__</nowiki></code> (og er i et navnerom hvor flagget er tillatt), og vil derfor bli indeksert av roboter selv når det normalt ikke ville skjedd.",
+    "post-expand-template-inclusion-category-desc": "Etter ekspandering av alle malene ble siden større enn <code>$wgMaxArticleSize</code>, så noen maler kunne ikke ekspanderes.",
     "post-expand-template-argument-category-desc": "Etter ekspandering av et malargument (noe i trippel krøllparentes, slik som <code>{{{Foo}}})</code>, så er siden større en <code>$wgMaxArticleSize</code>.",
     "expensive-parserfunction-category-desc": "For mange kostbare parserfunksjoner (som <code>#ifexist</code>) er inkludert på en side. Se [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
     "broken-file-category-desc": "Kategorien blir lagt til hvis siden inneholder en brutt fil-lenke (en lenke for å bygge inn en fil når filen selv ikke eksisterer).",
-    "hidden-category-category-desc": "Dette er en kategori som er påført et <code><nowiki>__HIDDENCAT__</nowiki></code> magisk ord, som hindrer den fra å dukke opp i lenkeboksen for kategorier på siden, som standard.",
+    "hidden-category-category-desc": "Dette er en kategori merket med <code><nowiki>__HIDDENCAT__</nowiki></code>, som hindrer den fra å vises i siders kategorioversikt som standard.",
     "trackingcategories-nodesc": "Ingen beskrivelse er tilgjengelig",
     "trackingcategories-disabled": "Kategorien er deaktivert",
     "mailnologin": "Ingen avsenderadresse",
     "delete-edit-reasonlist": "Rediger begrunnelser for sletting",
     "delete-toobig": "Denne siden har en stor redigeringshistorikk, med over {{PLURAL:$1|$1&nbsp;revisjon|$1&nbsp;revisjoner}}. Muligheten til å slette slike sider er begrenset for å unngå utilsiktet forstyrring av {{SITENAME}}.",
     "delete-warning-toobig": "Denne siden har en stor redigeringshistorikk, med over {{PLURAL:$1|$1&nbsp;revisjon|$1&nbsp;revisjoner}}. Sletting av denne siden kan forstyrre databasen til {{SITENAME}}; vær varsom.",
-    "deleting-backlinks-warning": "'''Advarsel:''' [[Special:WhatLinksHere/{{FULLPAGENAME}|Andre sider]] linker til eller inkluderer siden du er i ferd med å slette.",
+    "deleting-backlinks-warning": "'''Advarsel:''' [[Special:WhatLinksHere/{{FULLPAGENAME}|Andre sider]] lenker til eller inkluderer siden du er i ferd med å slette.",
     "rollback": "Fjern redigeringer",
     "rollback_short": "Tilbakestill",
     "rollbacklink": "tilbakestill",
index ada401c..82d52f4 100644 (file)
     "permalink": "Vaste verwiezing",
     "print": "Aofdrokken",
     "view": "Lezen",
+    "view-foreign": "Bekieken op $1",
     "edit": "Bewarken",
     "create": "Anmaken",
     "editthispage": "Disse zied bewarken",
     "youhavenewmessages": "Je hebben $1 ($2).",
     "youhavenewmessagesfromusers": "Je hebben $1 van {{PLURAL:$3|n aandere gebruker|$3 gebrukers}} ($2).",
     "youhavenewmessagesmanyusers": "Je hebben $1 van n bulte gebrukers ($2).",
-    "newmessageslinkplural": "{{PLURAL:$1|n niej bericht|nieje berichten}}",
-    "newmessagesdifflinkplural": "leste {{PLURAL:$1|wieziging|wiezigingen}}",
+    "newmessageslinkplural": "{{PLURAL:$1|n niej bericht|999=nieje berichten}}",
+    "newmessagesdifflinkplural": "leste {{PLURAL:$1|wieziging|999=wiezigingen}}",
     "youhavenewmessagesmulti": "Je hebben nieje berichten op $1",
     "editsection": "bewark",
     "editold": "bewark",
     "passwordtooshort": "Wachtwoorden mutten uut tenminsten {{PLURAL:$1|$1 teken|$1 tekens}} bestaon.",
     "password-name-match": "Joew wachtwoord en gebrukersnaam maggen niet liek alleens ween.",
     "password-login-forbidden": "t Gebruuk van disse gebrukersnaam mit dit wachtwoord is niet toe-estaon.",
-    "mailmypassword": "Niej wachtwoord opsturen",
+    "mailmypassword": "Wachtwoord opniej instellen",
     "passwordremindertitle": "Niej tiedelik wachtwoord veur {{SITENAME}}",
     "passwordremindertext": "Der hef der ene evreugen, vanaof t IP-adres $1 (warschienlik jie zelf),\num n niej wachtwoord veur {{SITENAME}} ($4) op te sturen.\nDer is n tiedelik wachtwoord an-emaakt veur gebruker \"$2\":\n\"$3\". As dit niet de bedoeling was, meld dan effen an en kies n niej wachtwoord.\nJoew tiedelike wachtwoord zal verlopen over {{PLURAL:$5|één dag|$5 dagen}}.\n\nA'j dit verzeuk niet zelf edaon hebben of a'j t wachtwoord weer weten\nen t niet meer wiezigen willen, negeer dit bericht dan\nen blief joew bestaonde wachtwoord gebruken.",
     "noemail": "Gien netpostadres eregistreerd veur \"$1\".",
     "accountcreatedtext": "De gebrukersnaam veur [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) is an-emaakt.",
     "createaccount-title": "Gebrukers anmaken veur {{SITENAME}}",
     "createaccount-text": "Der hef der ene n gebruker an-emaakt op {{SITENAME}} ($4), mit de naam $2 en t wachtwoord \"$3\". \nMeld je eigen noen an en wiezig t wachtwoord.\n\nNegeer dit bericht as disse gebruker zonder joew toestemming an-emaakt is.",
-    "usernamehasherror": "In n gebrukersnaam ma'j gien hekjen gebruken.",
     "login-throttled": "Je hebben lestens te vake eprobeerd um an te melden mit n verkeerd wachtwoord.\nJe mutten effen $1 wachten veurda'j t opniej proberen.",
     "login-abort-generic": "Je bin niet an-emeld. De procedure is aofebreuken.",
     "loginlanguagelabel": "Taal: $1",
     "suspicious-userlogout": "Joew verzeuk um of te melden is aofewezen umdat t dernaor uutziet dat t verstuurd is deur n kepotte webkieker of tussenopslagbuffer",
     "createacct-another-realname-tip": "Joew echte naam opgeven is niet verplicht.\nA'j t invullen, dan zu'w t gebruken um erkenning te geven veur joew warkzaamhejen.",
+    "pt-login": "Anmelden",
+    "pt-login-button": "Anmelden",
+    "pt-createaccount": "Inschrieven",
+    "pt-userlogout": "Aofmelden",
     "php-mail-error-unknown": "Der was n onbekende fout mit de mail()-funksie van PHP",
     "user-mail-no-addy": "Eprobeerd n berichjen te versturen zonder n netpostadres",
     "user-mail-no-body": "Der is eprobeerd n netbreef zonder tekste of mit n biester korte tekste te versturen.",
     "changepassword": "Wachtwoord wiezigen",
-    "resetpass_announce": "Je bin an-emeld mit n veurlopige kode die mit de netpost toe-estuurd wörden. Um t anmelden te voltooien, mu'j n niej wachtwoord invoeren:",
+    "resetpass_announce": "Um t anmelden te voltooien, mu'j n niej wachtwoord invoeren.",
     "resetpass_text": "<!-- Tekste hier invoegen -->",
     "resetpass_header": "Wachtwoord wiezigen",
     "oldpassword": "Wachtwoord da'j noen hebben",
     "retypenew": "Niej wachtwoord (opniej)",
     "resetpass_submit": "Voer t wachtwoord in en meld je an",
     "changepassword-success": "Joew wachtwoord is ewiezigd!",
+    "changepassword-throttled": "Je hebben lestens te vake eprobeerd um an te melden mit n verkeerd wachtwoord.\nJe mutten effen $1 wachten veurda'j t opniej proberen.",
     "resetpass_forbidden": "Wachtwoorden kunnen niet ewiezigd wörden",
     "resetpass-no-info": "Je mutten an-emeld ween veurda'j disse zied gebruken kunnen.",
     "resetpass-submit-loggedin": "Wachtwoord wiezigen",
     "resetpass-abort-generic": "De wachtwoordwieziging is aofebreuken deur n uutbreiding.",
     "passwordreset": "Wachtwoord opniej instellen",
     "passwordreset-text-one": "Vul dit formulier in um joew wachtwoord opniej in te stellen.",
-    "passwordreset-text-many": "{{PLURAL:$1|Vul een van de gegevensvelden in um joew wachtwoord opniej in te stellen.}}",
+    "passwordreset-text-many": "{{PLURAL:$1|Vul een van de gegevensvelden in um per netpost n tiejelik wachtwoord te ontvangen.}}",
     "passwordreset-legend": "Wachtwoord opniej instellen",
     "passwordreset-disabled": "Je kunnen op disse wiki joew wachtwoord niet opniej instellen.",
     "passwordreset-emaildisabled": "Netpostmeugelikhejen bin uutezet op disse wiki.",
     "content-failed-to-parse": "Kon de inhoud van t MIME-type $2 veur t model $1 niet verwarken: $3.",
     "invalid-content-data": "Ongeldige inhoudsgegevens",
     "content-not-allowed-here": "De inhoud \"$1\" is niet toe-estaan op de zied [[$2]].",
-    "editwarning-warning": "A'j disse zied verlaoten dan bi'j de wieziging die'j emaakt hebben waorschienlik kwiet.\nA'j an-emeld bin, dan ku'j disse waorschuwing uutzetten in t tabblad \"Bewarkingsveld\" in joew veurkeuren.",
+    "editwarning-warning": "A'j disse zied verlaoten dan bi'j de wieziging die'j emaakt hebben waorschienlik kwiet.\nA'j an-emeld bin, dan ku'j disse waorschuwing uutzetten in t tabblad \"{{int:prefs-editing}}\" in joew veurkeuren.",
     "content-model-wikitext": "wikitekste",
     "content-model-text": "tekste zonder opmaak",
     "content-model-javascript": "JavaScript",
     "revdelete-hide-user": "Gebrukersnaam/IP-adres van disse gebruker",
     "revdelete-hide-restricted": "Gegevens veur beheerders en aander volk onderdrokken",
     "revdelete-radio-same": "(niet wiezigen)",
-    "revdelete-radio-set": "Zichtbaor",
-    "revdelete-radio-unset": "Verbörgen",
+    "revdelete-radio-set": "Verbörgen",
+    "revdelete-radio-unset": "Zichtbaor",
     "revdelete-suppress": "Gegevens veur beheerders en aander volk onderdrokken",
     "revdelete-unsuppress": "Beparkingen veur weerummezetten versies vortdoon",
     "revdelete-log": "Reden:",
     "shown-title": "Laot $1 {{PLURAL:$1|resultaot|resultaoten}} per zied zien",
     "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3)",
     "searchmenu-exists": "'''Der is n zied mit de naam \"[[:$1]]\" op disse wiki.'''",
-    "searchmenu-new": "'''De zied \"[[:$1]]\" op disse wiki anmaken!'''",
+    "searchmenu-new": "<strong>De zied \"[[:$1]]\" op disse wiki anmaken!</strong> \n{{PLURAL:$2|0=|Zie oek de zied mit joew zeukresultaoten.|Zie oek de lieste mit evunnen zeukresultaoten.}}",
     "searchprofile-articles": "Artikels",
     "searchprofile-project": "Hulp- en projektziejen",
     "searchprofile-images": "Multimedia",
     "search-section": "(onderwarp $1)",
     "search-suggest": "Bedoelden je: $1",
     "search-interwiki-caption": "Zusterprojekten",
-    "search-interwiki-default": "$1 resultaoten:",
+    "search-interwiki-default": "Resultaoten van $1:",
     "search-interwiki-more": "(meer)",
     "search-relatedarticle": "Verwaant",
     "searcheverything-enable": "In alle naamruumten zeuken",
     "prefs-skin": "{{SITENAME}}-uterlik",
     "skin-preview": "bekieken",
     "datedefault": "Gien veurkeur",
-    "prefs-datetime": "Daotum en tied",
     "prefs-labs": "Alphafunksies",
     "prefs-user-pages": "Gebrukersziejen",
     "prefs-personal": "Gebrukersgegevens",
     "recentchanges-label-unpatrolled": "Disse bewarking is nog niet nao-ekeken",
     "recentchanges-label-plusminus": "Disse ziedgrootte is mit dit antal bytes ewiezigd",
     "recentchanges-legend-newpage": "(zie oek de [[Special:NewPages|lieste mit nieje ziejen]])",
-    "rcnotefrom": "Dit bin de wiezigingen sinds <b>$2</b> (maximum van <b>$1</b> wiezigingen).",
+    "rcnotefrom": "Dit bin de wiezigingen sinds <strong>$2</strong> (maximum van <strong>$1</strong> wiezigingen).",
     "rclistfrom": "Bekiek wiezigingen vanaof $1",
     "rcshowhideminor": "$1 kleine wiezigingen",
     "rcshowhidebots": "$1 botgebrukers",
-    "rcshowhideliu": "$1 an-emelde gebrukers",
+    "rcshowhideliu": "$1 eregistreerden gebrukers",
     "rcshowhideanons": "$1 anonieme gebrukers",
     "rcshowhidepatr": "$1 nao-ekeken bewarkingen",
     "rcshowhidemine": "$1 mien bewarkingen",
     "upload-permitted": "Toe-estaone bestaandstypes: $1.",
     "upload-preferred": "An-ewezen bestaandstypes: $1.",
     "upload-prohibited": "Verbeujen bestaandstypes: $1.",
-    "uploadlog": "logboek mit nieje bestaanden",
     "uploadlogpage": "Logboek mit nieje bestaanden",
     "uploadlogpagetext": "Hieronder steet n lieste mit bestaanden die net niej bin.\nZie de [[Special:NewFiles|uutstalling mit media]] veur n overzichte.",
     "filename": "Bestaandsnaam",
     "filereuploadsummary": "Bestaandswiezigingen:",
     "filestatus": "Auteursrechtstaotus",
     "filesource": "Bron",
-    "uploadedfiles": "Nieje bestaanden",
     "ignorewarning": "Negeer alle waorschuwingen",
     "ignorewarnings": "Negeer waorschuwingen",
     "minlength1": "Bestaandsnamen mutten uut tenminsten één letter bestaon.",
     "overwroteimage": "Nieje versie van \"[[$1]]\" op-estuurd",
     "uploaddisabled": "t Opsturen van bestaanden is uutezet.",
     "copyuploaddisabled": "t Opsturen van bestaanden via n webadres is uutezet.",
-    "uploadfromurl-queued": "Joew bestaand is in de wachtrie ezet.",
     "uploaddisabledtext": "t Opsturen van bestaanden is uutezet.",
     "php-uploaddisabledtext": "t Opsturen van PHP-bestaanden is uutezet. Kiek de instellingen veur t opsturen van bestaanden effen nao.",
     "uploadscripted": "In dit bestaand steet HTML- of skriptkode die verkeerd elezen kan wörden deur de webkieker.",
     "upload-misc-error": "Onbekende fout bie t inlaojen van joew bestaand",
     "upload-misc-error-text": "Der is bie t inlaojen van t bestaand n onbekende fout op-etrejen. \nKiek effen nao of de verwiezing t wel döt en probeer t opniej. \nAs t probleem zo blif, neem dan kontakt op mit één van de [[Special:ListUsers/sysop|beheerders]].",
     "upload-too-many-redirects": "Der zatten te veule deurverwiezingen in de URL.",
-    "upload-unknown-size": "Onbekende grootte",
     "upload-http-error": "Der is n HTTP-fout op-etrejen: $1",
     "upload-copy-upload-invalid-domain": "Bestaanden per kopie opsturen is niet beschikbaor vanuut dit domein.",
     "backend-fail-stream": "t Was niet meugelik t bestaand $1 te streumen.",
     "img-auth-streaming": "Bezig mit t streumen van \"$1\".",
     "img-auth-public": "t Doel van img_auth.php is de uutvoer van bestaanden van n besleuten wiki.\nDisse wiki is in-esteld as publieke wiki.\nUm beveiligingsredens is img_auth.php uutezet.",
     "img-auth-noread": "De gebruker hef gien leestoegang tot \"$1\".",
-    "img-auth-bad-query-string": "In t webadres steet n ongeldige zeukopdrachte.",
     "http-invalid-url": "Ongeldig webadres: $1",
     "http-invalid-scheme": "Webadressen mit de opmaak \"$1\" wörden niet ondersteund.",
     "http-request-error": "Fout bie t verzenden van t verzeuk.",
     "filehist-dimensions": "Grootte",
     "filehist-filesize": "Bestaandsgrootte",
     "filehist-comment": "Opmarkingen",
-    "filehist-missing": "Bestaand ontbrik",
     "imagelinks": "Bestaandsgebruuk",
     "linkstoimage": "Dit bestaand wörden gebruukt op de volgende {{PLURAL:$1|zied|$1 ziejen}}:",
     "linkstoimage-more": "Der {{PLURAL:$2|is|bin}} meer as $1 {{PLURAL:$1|verwiezing|verwiezingen}} naor dit bestaand.\nDe volgende lieste gif allinnig de eerste {{PLURAL:$1|verwiezing|$1 verwiezingen}} naor dit bestaand weer.\nDe [[Special:WhatLinksHere/$2|hele lieste]] is oek beschikbaor.",
     "emailuser-title-notarget": "Gebruker n bericht sturen",
     "emailpage": "Gebruker n bericht sturen",
     "emailpagetext": "Deur middel van dit formulier ku'j n bericht sturen naor disse {{GENDER:$1|gebruker}}.\nt Adres da'j op-egeven hebben bie [[Special:Preferences|joew veurkeuren]] zal as aofzender gebruukt wörden.\nDe ontvanger kan dus drek beantwoorden.",
-    "usermailererror": "Foutmelding bie t versturen:",
     "defemailsubject": "Bericht van {{SITENAME}}-gebruker \"$1\"",
     "usermaildisabled": "n Persoonlik berichjen sturen geet niet.",
     "usermaildisabledtext": "Je kunnen gien berichjes sturen naor aandere gebrukers van disse wiki",
     "noemailtitle": "Gebruker hef gien netpostadres op-egeven",
     "noemailtext": "Disse gebruker hef gien geldig e-mailadres in-evoerd.",
-    "nowikiemailtitle": "Netpost is niet toe-estaon",
     "nowikiemailtext": "Disse gebruker wil gien netpost toe-estuurd kriegen van aandere gebrukers.",
     "emailnotarget": "Niet-bestaonde of ongeldige ontvanger.",
     "emailtarget": "Voer de gebrukersnaam of ontvanger in",
     "watching": "Volg...",
     "unwatching": "Niet volgen...",
     "watcherrortext": "Der is n fout op-etrejen tiejens t wiezigen van joew volgliesinstellingen veur \"$1\".",
-    "enotif_mailer": "{{SITENAME}}-berichgevingssysteem",
     "enotif_reset": "Markeer alle ziejen as bezöcht.",
     "enotif_impersonal_salutation": "{{SITENAME}}-gebruker",
     "enotif_subject_deleted": "{{SITENAME}}: zied $1 is vortedaon deur {{GENDER:$2|$2}}",
     "enotif_lastvisited": "Zie $1 veur alle wiezigingen sinds joew leste bezeuk.",
     "enotif_lastdiff": "Zie $1 um disse wieziging te bekieken.",
     "enotif_anon_editor": "anonieme gebruker $1",
-    "enotif_body": "Huj $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nSamenvatting van de wieziging: $PAGESUMMARY $PAGEMINOREDIT\n\nKontaktgevevens van de auteur:\nNetpost: $PAGEEDITOR_EMAIL\nWiki: $PAGEEDITOR_WIKI\n\nJe kriegen veerder gien berichten, behalven a'j disse zied bezeuken.\nOp joew volglieste ku'j veur alle ziejen die'j volgen de waorschuwingsinstellingen deraof haolen.\n\nGroeten van t {{SITENAME}}-waorschuwingssysteem.\n\n--\nJe kunnen joew netpostinstellingen wiezigen op:\n{{canonicalurl:{{#special:Preferences}}}}\n\nJe kunnen de volgliestinstellingen wiezigen op:\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nJe kunnen de zied van joew volglieste aofhaolen deur op de volgende verwiezing te klikken:\n$UNWATCHURL\n\nOpmarkingen en veerdere hulpe:\n{{canonicalurl:{{MediaWiki:Helppage}}}}",
+    "enotif_body": "Huj $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nSamenvatting van de wieziging: $PAGESUMMARY $PAGEMINOREDIT\n\nKontaktgevevens van de auteur:\nNetpost: $PAGEEDITOR_EMAIL\nWiki: $PAGEEDITOR_WIKI\n\nJe kriegen veerder gien berichten, behalven a'j disse zied bezeuken terwiel je an-emeld bin. Op joew volglieste ku'j veur alle ziejen die'j volgen de waorschuwingsinstellingen deraof haolen.\n\nGroeten van t {{SITENAME}}-waorschuwingssysteem.\n\n--\nJe kunnen joew netpostinstellingen wiezigen op:\n{{canonicalurl:{{#special:Preferences}}}}\n\nJe kunnen de volgliestinstellingen wiezigen op:\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nJe kunnen de zied van joew volglieste aofhaolen deur op de volgende verwiezing te klikken:\n$UNWATCHURL\n\nOpmarkingen en veerdere hulpe:\n{{canonicalurl:{{MediaWiki:Helppage}}}}",
     "created": "an-emaakt",
     "changed": "ewiezigd",
     "deletepage": "Vortdoon",
     "excontent": "De tekste was: '$1'",
     "excontentauthor": "De tekste was: '$1' (zied an-emaakt deur: [[Special:Contributions/$2|$2]])",
     "exbeforeblank": "veurdat disse zied leegemaakt wörden stung hier: '$1'",
-    "exblank": "Zied was leeg",
     "delete-confirm": "\"$1\" vortdoon",
     "delete-legend": "Vortdoon",
     "historywarning": "'''Waorschuwing''': de zied die'j vortdoon, hef $1 {{PLURAL:$1|versie|versies}}:",
     "protect-locked-blocked": "Je kunnen beveiligingsnivo's niet wiezigen terwiel je eblokkeerd bin. Hier bin de instellingen zo as ze noen bin veur de zied '''$1''':",
     "protect-locked-dblock": "Beveiligingsnivo's kunnen effen niet ewiezigd wörden umdat de databanke noen beveiligd is.\nHier staon de instellingen zo as ze noen bin veur de zied '''$1''':",
     "protect-locked-access": "Je hebben gien rechten um t beveilingsnivo van ziejen te wiezigen.\nHier staon de instellingen zo as ze noen bin veur de zied '''$1''':",
-    "protect-cascadeon": "Disse zied wörden beveiligd, umdat t op-eneumen is in de volgende {{PLURAL:$1|zied|ziejen}} die beveiligd {{PLURAL:$1|is|bin}} mit de kaskadeopsie. Je kunnen t beveiligingsnivo van disse zied anpassen, mer dat hef gien invleud op de kaskadebeveiliging.",
+    "protect-cascadeon": "Disse zied wörden beveiligd, umdat t op-eneumen is in de volgende {{PLURAL:$1|zied|ziejen}} die beveiligd {{PLURAL:$1|is|bin}} mit de kaskadeopsie. Wiezigingen in t beveiligingsnivo van disse zied hebben gien invleud op de kaskadebeveiliging.",
     "protect-default": "Veur alle gebrukers",
     "protect-fallback": "Allinnig gebrukers mit t recht \"$1\" toestaon",
     "protect-level-autoconfirmed": "Allinnig automaties bevestigden gebrukers toestaon",
     "range_block_disabled": "De meugelikheid veur beheerders um n groep adressen te blokkeren is uutezet.",
     "ipb_expiry_invalid": "De op-egeven verlooptied is ongeldig.",
     "ipb_expiry_temp": "Blokkeringen veur verbörgen gebrukers mutten permanent ween.",
-    "ipb_hide_invalid": "Kan disse gebruker niet verbargen; warschienlik hef e al te veule bewarkingen emaakt.",
+    "ipb_hide_invalid": "Kan disse gebruker niet verbargen; waorschienlik hef e al meer as {{PLURAL:$1|één bewarking|$1 bewarkingen}} edaon.",
     "ipb_already_blocked": "\"$1\" is al eblokkeerd",
     "ipb-needreblock": "$1 is al eblokkeerd.\nWi'j de instellingen wiezigen?",
     "ipb-otherblocks-header": "Aandere {{PLURAL:$1|blokkering|blokkeringen}}",
     "importunknownsource": "Onbekend invoerbrontype",
     "importcantopen": "Kon t invoerbestaand niet los doon",
     "importbadinterwiki": "Foute interwikiverwiezing",
-    "importnotext": "Leeg of gien tekste",
     "importsuccess": "Invoeren suksesvol!",
-    "importhistoryconflict": "Der bin konflikten in de geschiedenisse van de zied (is misschien eerder al in-evoerd)",
     "importnosources": "Gien transwiki-invoerbronnen vastesteld en t drek inlaojen van versies is eblokkeerd.",
     "importnofile": "Der is gien invoerbestaand op-estuurd.",
     "importuploaderrorsize": "t Opsturen van t invoerbestaand is mislokt.\nt Bestaand is groter as de in-estelde limiet.",
     "importuploaderrortemp": "t Opsturen van t invoerbestaand is mislokt.\nDe tiedelike map is niet anwezig.",
     "import-parse-failure": "Fout bie t verwarken van de XML-invoer",
     "import-noarticle": "Der bin gien ziejen um in te voeren!",
-    "import-nonewrevisions": "Alle versies bin al eerder in-evoerd.",
+    "import-nonewrevisions": "Gien eerdere versies in-evoerd (alles was der al, of is overesleugen vanwegen fouten).",
     "xml-error-string": "$1 op regel $2, kolom $3 (byte $4): $5",
     "import-upload": "XML-gegevens derbie doon",
     "import-token-mismatch": "De sessiegegevens bin verleuren egaon. Probeer t opniej.",
     "svg-long-desc": "SVG-bestaand, uutgangsgrootte $1 × $2 beeldpunten, bestaandsgrootte: $3",
     "svg-long-desc-animated": "Bewegend SVG-bestaand, uutgangsgrootte $1 × $2 beeldpunten, bestaandsgrootte: $3",
     "svg-long-error": "Ongeldig SVG-bestaand: $1",
-    "show-big-image": "Volle resolusie",
+    "show-big-image": "Oorspronkelik bestaand",
     "show-big-image-preview": "Grootte van disse weergave: $1.",
     "show-big-image-other": "Aandere {{PLURAL:$2|resolusie|resolusies}}: $1.",
     "show-big-image-size": "$1 × $2 beeldpunten",
     "version-hook-name": "Hooknaam",
     "version-hook-subscribedby": "In-eschreven deur",
     "version-version": "(Versie $1)",
-    "version-license": "Lisensie",
+    "version-license": "MediaWiki-lisensie",
     "version-poweredby-credits": "Disse wiki wörden an-estuurd deur '''[https://www.mediawiki.org/ MediaWiki]''', auteursrecht © 2001-$1 $2.",
     "version-poweredby-others": "aanderen",
     "version-poweredby-translators": "vertalers van translatewiki.net",
     "version-entrypoints": "Webadressen veur ingangen",
     "version-entrypoints-header-entrypoint": "Ingang",
     "version-entrypoints-header-url": "Webadres",
-    "redirect": "Deurverwiezen op bestaandsnaam, gebrukersnummer of versienummer",
+    "redirect": "Deurverwiezen op bestaandsnaam, gebrukersnummer, ziednummer of versienummer",
     "redirect-legend": "Deurverwiezen naor n bestaand of zied",
-    "redirect-summary": "Disse spesiale zied verwis deur naor n bestaand (as de bestaandsnaam op-egeven wörden), n zied (as n versienummer op-egeven wörden) of n gebrukerszied (as t gebrukersnummer op-egeven wörden). Gebruuk: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], of [[{{#Special:Redirect}}/user/101]].",
+    "redirect-summary": "Disse spesiale zied verwis deur naor n bestaand (as de bestaandsnaam op-egeven wörden), n zied (as n zied- of versienummer op-egeven wörden) of n gebrukerszied (as t gebrukersnummer op-egeven wörden). Gebruuk: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], of [[{{#Special:Redirect}}/user/101]].",
     "redirect-submit": "Zeuk",
     "redirect-lookup": "Opzeuken:",
     "redirect-value": "Weerde:",
     "fileduplicatesearch-result-n": "Der {{PLURAL:$2|is één bestaand|bin $2 bestaanden}} die liek alleens bin as \"$1\".",
     "fileduplicatesearch-noresults": "Der is gien bestaand mit de naam \"$1\" evunnen.",
     "specialpages": "Spesiale ziejen",
-    "specialpages-note": "* Normale spesiale ziejen.\n* <strong class=\"mw-specialpagerestricted\">Beparkt toegankelike spesiale ziejen.</strong>\n* <span class=\"mw-specialpagecached\">Spesiale ziejen mit allinnig gegevens uut t tussengeheugen (kunnen verouwerd ween).</span>",
+    "specialpages-note": "* Normale spesiale ziejen.\n* <span class=\"mw-specialpagerestricted\">Beparkt toegankelike spesiale ziejen.</span>",
     "specialpages-group-maintenance": "Onderhoudsliesten",
     "specialpages-group-other": "Aandere spesiale ziejen",
     "specialpages-group-login": "Anmelden / inschrieven",
index 730c6d6..66e60b0 100644 (file)
     "prefs-skin": "काँचुली",
     "skin-preview": "पूर्वावलोकन",
     "datedefault": "कुनै अभिरुचि छैन",
-    "prefs-datetime": "मिति र समय",
     "prefs-labs": "प्रयोगशाला गुणहरु",
     "prefs-user-pages": "प्रयोगकर्ता पृष्ठहरू",
     "prefs-personal": "प्रयोगकर्ताको विवरण",
index de3eccf..c6cf9b0 100644 (file)
     "prefs-skin": "Vormgeving",
     "skin-preview": "Voorvertoning",
     "datedefault": "Geen voorkeur",
-    "prefs-datetime": "Datum en tijd",
     "prefs-labs": "Alphafunctionaliteit",
     "prefs-user-pages": "Gebruikerspagina's",
     "prefs-personal": "Gebruikersprofiel",
     "defaultns": "Anders in de volgende naamruimten zoeken:",
     "default": "standaard",
     "prefs-files": "Bestanden",
-    "prefs-custom-css": "persoonlijke CSS",
-    "prefs-custom-js": "persoonlijke JS",
-    "prefs-common-css-js": "Gedeelde CSS/JS voor elke vormgeving:",
+    "prefs-custom-css": "aangepaste CSS",
+    "prefs-custom-js": "aangepaste JavaScript",
+    "prefs-common-css-js": "Gedeelde CSS/JavaScript voor elke vormgeving:",
     "prefs-reset-intro": "Gebruik deze functie om uw voorkeuren te herstellen naar de standaardinstellingen.\nDeze handeling kan niet ongedaan gemaakt worden.",
     "prefs-emailconfirm-label": "E-mailbevestiging:",
     "youremail": "Uw e-mailadres:",
     "right-editprotected": "Pagina's bewerken die beveiligd zijn als \"{{int:protect-level-sysop}}\"",
     "right-editsemiprotected": "Pagina's bewerken die beveiligd zijn als \"{{int:protect-level-autoconfirmed}}\"",
     "right-editinterface": "De gebruikersinterface bewerken",
-    "right-editusercssjs": "De CSS- en JS-bestanden van andere gebruikers bewerken",
+    "right-editusercssjs": "De CSS- en JavaScriptbestanden van andere gebruikers bewerken",
     "right-editusercss": "De CSS-bestanden van andere gebruikers bewerken",
     "right-edituserjs": "De JavaScriptbestanden van andere gebruikers bewerken",
     "right-editmyusercss": "Uw eigen CSS-pagina's bewerken",
     "unwatchthispage": "Niet meer volgen",
     "notanarticle": "Is geen pagina",
     "notvisiblerev": "De laatste versie van een andere gebruiker is verwijderd",
-    "watchlist-details": "Er {{PLURAL:$1|staat één pagina|staan $1 pagina's}} op uw volglijst, exclusief overlegpagina's.",
+    "watchlist-details": "Er {{PLURAL:$1|staat één pagina|staan $1 pagina's}} op uw volglijst. Overlegpagina's worden niet meegeteld.",
     "wlheader-enotif": "U wordt per e-mail gewaarschuwd.",
     "wlheader-showupdated": "Pagina's die zijn bewerkt sinds uw laatste bezoek worden '''vet''' weergegeven.",
     "watchmethod-recent": "controleer recente wijzigingen op pagina's op volglijst",
     "contributions-title": "Bijdragen van $1",
     "mycontris": "Bijdragen",
     "contribsub2": "Voor {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "De gebruiker \"$1\" is niet geregistreerd.",
     "nocontribs": "Geen wijzigingen gevonden die aan de gestelde criteria voldoen.",
     "uctop": "(laatste wijziging)",
     "month": "Van maand (en eerder):",
index 299f976..e9bdc0a 100644 (file)
     "prefs-skin": "Drakt",
     "skin-preview": "førehandsvis",
     "datedefault": "Standard",
-    "prefs-datetime": "Dato og klokkeslett",
     "prefs-labs": "Testfunksjonar",
     "prefs-user-pages": "Brukarsider",
     "prefs-personal": "Brukaropplysningar",
index bc5125b..2729d1c 100644 (file)
     "permalink": "Ligam istoric",
     "print": "Imprimir",
     "view": "Veire",
+    "view-foreign": "Veire sus $1",
     "edit": "Modificar",
+    "edit-local": "Modificar la descripcion locala",
     "create": "Crear",
+    "create-local": "apondre una descripcion locala",
     "editthispage": "Modificar aquesta pagina",
     "create-this-page": "Crear aquesta pagina",
     "delete": "Suprimir",
     "accountcreatedtext": "Lo compte d'utilizaire per [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|discussion]]) es estat creat.",
     "createaccount-title": "Creacion d'un compte per {{SITENAME}}",
     "createaccount-text": "Qualqu'un a creat un compte per vòstra adreça de corrièr electronic sus {{SITENAME}} ($4) intitolat « $2 », amb per senhal « $3 ». Deuriaz dobrir una sessilha e cambiar, tre ara, aqueste senhal.\n\nIgnoratz aqueste messatge se aqueste compte es estat creat per error.",
-    "usernamehasherror": "Lo nom d'utilizaire pòt pas conténer de caractèrs de hachage",
     "login-throttled": "Avètz ensajat un tròp grand nombre de connexions darrièrament.\nEsperatz $1 abans d’ensajar tornarmai.",
     "login-abort-generic": "Vòstra temptativa de connexion a fracassat",
     "loginlanguagelabel": "Lenga: $1",
     "prefs-skin": "Aparéncia",
     "skin-preview": "Previsualizar",
     "datedefault": "Pas cap de preferéncia",
-    "prefs-datetime": "Data e ora",
     "prefs-labs": "Foncionalitats « labs »",
     "prefs-user-pages": "Paginas d'utilizaire",
     "prefs-personal": "Entresenhas personalas",
     "upload-permitted": "Formats de fichièrs autorizats : $1.",
     "upload-preferred": "Formats de fichièrs preferits : $1.",
     "upload-prohibited": "Formats de fichièrs interdiches : $1.",
-    "uploadlog": "Istoric de las importacions",
     "uploadlogpage": "Istoric de las importacions de fichièrs multimèdia",
     "uploadlogpagetext": "Aquí la lista dels darrièrs fichièrs copiats sul servidor.\nVejatz la [[Special:NewFiles|galariá dels imatges novèls]] per una presentacion mai visuala.",
     "filename": "Nom del fichièr",
     "filereuploadsummary": "Modificacions del fichièr :",
     "filestatus": "Estatut dels dreches d'autor :",
     "filesource": "Font :",
-    "uploadedfiles": "Fichièrs importats",
     "ignorewarning": "Ignorar l’avertiment e salvar lo fichièr",
     "ignorewarnings": "Ignorar los avertiments al moment de l’impòrt",
     "minlength1": "Los noms de fichièrs devon comprendre almens una letra.",
     "overwroteimage": "a importat una version novèla de « [[$1]] »",
     "uploaddisabled": "O planhèm, lo mandadís de fichièr es desactivat.",
     "copyuploaddisabled": "Mandadís de fichièr per URL desactivat.",
-    "uploadfromurl-queued": "Vòstre mandadís es estat mes dins la fila d'espèra.",
     "uploaddisabledtext": "L'impòrt de fichièrs cap al servidor es desactivat.",
     "php-uploaddisabledtext": "Lo telecargament de fichièrs es estat desactivat dins PHP. Verificatz l'opcion de configuracion file_uploads.",
     "uploadscripted": "Aqueste fichièr conten de còde HTML o un escript que poiriá èsser interpretat d'un biais incorrècte per un navigador Internet.",
     "upload-misc-error": "Error d’impòrt desconeguda",
     "upload-misc-error-text": "Una error desconeguda s'es producha pendent l’impòrt.\nVerificatz que l’URL es valida e accessibla, puèi ensajatz tornamai.\nSe lo problèma persistís, contactatz un [[Special:ListUsers/sysop|administrator del sistèma]].",
     "upload-too-many-redirects": "L'URL conten tròp de redireccions",
-    "upload-unknown-size": "Talha desconeguda",
     "upload-http-error": "Una error HTTP es intervenguda : $1",
     "upload-copy-upload-invalid-domain": "La còpia dels telecargaments es pas disponibla dempuèi aqueste domeni.",
     "backend-fail-stream": "Impossible de legir lo fichièr $1.",
     "img-auth-streaming": "Lectura en continú de « $1 ».",
     "img-auth-public": "La foncion d'img_auth.php es d'afichar de fichièrs d'un wiki privat.\nAqueste wiki es configurat coma un wiki public.\nPer una seguretat optimala, img_auth.php es desactivat.",
     "img-auth-noread": "L'utilizaire a pas lo drech en lectura sus « $1 ».",
-    "img-auth-bad-query-string": "L'URL a una cadena de requèsta invalida.",
     "http-invalid-url": "URL incorrècta : $1",
     "http-invalid-scheme": "Las URLs amb l\"esquèma « $1 » son pas suportadas",
     "http-request-error": "Error desconeguda al moment del mandadís de la requèsta.",
     "filehist-dimensions": "Dimensions",
     "filehist-filesize": "Talha del fichièr",
     "filehist-comment": "Comentari",
-    "filehist-missing": "Fichièr mancant",
     "imagelinks": "Paginas que contenon lo fichièr",
     "linkstoimage": "{{PLURAL:$1|La pagina çaijós compòrta|Las paginas çaijós compòrtan}} aqueste imatge :",
     "linkstoimage-more": "Mai {{PLURAL:$1|d’un ligam de pagina|de $1 ligams de paginas}} cap a aqueste fichièr.\nLa lista seguenta aficha {{PLURAL:$1|lo primièr ligam de pagina|los $1 primièrs ligams de pagina}} unicament cap a aqueste fichièr.\nUna [[Special:WhatLinksHere/$2|lista completa]] es disponibla.",
     "listgrouprights-removegroup-self": "Se pòt levar {{PLURAL:$2|lo grop|los gropes}} de son compte pròpri : $1",
     "listgrouprights-addgroup-self-all": "Se pòt apondre totes los gropes a son compte pròpri",
     "listgrouprights-removegroup-self-all": "Se pòt levar totes los gropes de son compte pròpri",
+    "listgrouprights-namespaceprotection-header": "Restriccions d'espaci de noms",
+    "listgrouprights-namespaceprotection-namespace": "Espaci de noms",
+    "listgrouprights-namespaceprotection-restrictedto": "Drech(s) que permet(on) a l'utilizaire de modificar",
     "trackingcategories": "Categorias de seguiment",
     "trackingcategories-msg": "Categoria de seguiment",
     "trackingcategories-name": "Nom del messatge",
     "emailuser-title-notarget": "Mandar un corrièr electronic a l’utilizaire",
     "emailpage": "Mandar un corrièr electronic a l’utilizaire",
     "emailpagetext": "Podètz utilizar lo formulari çaijós per mandar un corrièr electronic a {{GENDER:$1|aqueste utilizaire|aquesta utilizaira}}.\nL'adreça electronica qu'avètz indicada dins [[Special:Preferences|vòstras preferéncias]] apareisserà dins lo camp « Expeditor » de vòstre messatge. E mai, lo destinatari vos poirà respondre dirèctament.",
-    "usermailererror": "Error dins lo subjècte del corrièr electronic :",
     "defemailsubject": "{{SITENAME}} Corrièl de l'utilizaire « $1 »",
     "usermaildisabled": "Lo mandadís de corrièrs electronics entre utilizairers es desactivat",
     "usermaildisabledtext": "Podètz pas mandar de corrièrs electronics a d'autres utilizaires sur aquel wiki",
     "noemailtitle": "Pas d'adreça electronica",
     "noemailtext": "Aqueste utilizaire a pas especificat d'adreça electronica valida.",
-    "nowikiemailtitle": "Pas de corrièr electronic autorizat",
     "nowikiemailtext": "Aqueste utilizaire a causit de recebre pas de corrièr electronic de la part d'autres utilizaires.",
     "emailnotarget": "Nom d'utilizaire del destinatari inexistent o invalid.",
     "emailtarget": "Entratz lo nom d'utilizaire del destinatari",
     "unwatchthispage": "Arrestar de seguir",
     "notanarticle": "Pas cap d'article",
     "notvisiblerev": "Version suprimida",
-    "watchlist-details": "I a {{PLURAL:$1|pagina|paginas}} dins vòstra lista de seguiment, sens comptar las paginas de discussion.",
+    "watchlist-details": "I a {{PLURAL:$1|$1 pagina|$1 paginas}} dins vòstra lista de seguiment, sens comptar las paginas de discussion.",
     "wlheader-enotif": "La notificacion per corrièr electronic es activada.",
     "wlheader-showupdated": "Las paginas que son estadas modificadas dempuèi vòstra darrièra visita son afichadas en '''gras'''.",
     "watchmethod-recent": "verificacion dels darrièrs cambiaments per i trobar de paginas seguidas",
     "watching": "Seguit...",
     "unwatching": "Fin del seguit...",
     "watcherrortext": "Una error s'es producha al moment de la modificacion dels paramètres de vòstra lista de seguiment per « $1 ».",
-    "enotif_mailer": "Sistèma d’expedicion de notificacion de {{SITENAME}}",
     "enotif_reset": "Marcar totas las paginas coma visitadas",
     "enotif_impersonal_salutation": "Utilizaire de {{SITENAME}}",
     "enotif_subject_deleted": "La pagina $1 sus {{SITENAME}} es estada suprimida per {{GENDER:$2|$2}}",
     "excontent": "contenent '$1'",
     "excontentauthor": "lo contengut èra : « $1 » (e l'unic contributor èra « [[Special:Contributions/$2|$2]] »)",
     "exbeforeblank": "lo contengut abans blanquiment èra :'$1'",
-    "exblank": "pagina voida",
     "delete-confirm": "Escafar «$1»",
     "delete-legend": "Escafar",
     "historywarning": "'''Atencion :''' La pagina que s�tz a mand de suprimir a un istoric que conten aproximadament $1 {{PLURAL:$1|revision|revisions}} :",
     "contributions-title": "Lista de las contribucions de l’utilizaire $1",
     "mycontris": "Contribucions",
     "contribsub2": "Per {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "Lo compte d'utilizaire « $1 » es pas enregistrat.",
     "nocontribs": "Cap de modificacion correspondenta a aquestes critèris es pas estada trobada.",
     "uctop": "(actual)",
     "month": "A partir del mes (e precedents) :",
     "importunknownsource": "Tipe de la font d’impòrt desconegut",
     "importcantopen": "Impossible de dobrir lo fichièr d'importar",
     "importbadinterwiki": "Ligam interwiki marrit",
-    "importnotext": "Void o sens tèxte",
     "importsuccess": "L'impòrt a capitat !",
-    "importhistoryconflict": "I a un conflicte dins l'istoric de las versions (aquesta pagina a pogut èsser importada de per abans).",
     "importnosources": "Cap de font interwiki es pas estada definida e la còpia dirècta d’istoric es desactivada.",
     "importnofile": "Cap de fichièr es pas estat importat.",
     "importuploaderrorsize": "Lo telecargament del fichièr d'importar a pas capitat. Sa talha es mai granda que la autorizada.",
index 4ace4aa..ed9604a 100644 (file)
     "createacct-benefit-heading": "{{grammar:B.lp|{{SITENAME}}}} tworzą ludzie tacy jak Ty.",
     "createacct-benefit-body1": "{{PLURAL:$1|edycja|edycje|edycji}}",
     "createacct-benefit-body2": "{{PLURAL:$1|strona|strony|stron}}",
-    "createacct-benefit-body3": "{{PLURAL:$1|użytkownik|użytkowników}} w ostatnim czasie",
+    "createacct-benefit-body3": "{{PLURAL:$1|aktywny użytkownik|aktywnych użytkowników}} w ostatnim miesiącu",
     "badretype": "Wprowadzone hasła różnią się między sobą.",
     "userexists": "Wybrana przez Ciebie nazwa użytkownika jest już zajęta.\nWybierz inną nazwę użytkownika.",
     "loginerror": "Błąd logowania",
     "prefs-skin": "Skórka",
     "skin-preview": "podgląd",
     "datedefault": "Domyślny",
-    "prefs-datetime": "Data i czas",
     "prefs-labs": "Funkcje doświadczalne",
     "prefs-user-pages": "Strony użytkowników",
     "prefs-personal": "Dane użytkownika",
     "restoreprefs": "Przywróć wszystkie domyślne preferencje (we wszystkich zakładkach)",
     "prefs-editing": "Edycja",
     "rows": "Wiersze:",
-    "columns": "Kolumny",
+    "columns": "Kolumny:",
     "searchresultshead": "Wyszukiwanie",
     "stub-threshold": "Maksymalny (w bajtach) rozmiar strony oznaczanej jako <a href=\"#\" class=\"stub\">zalążek (stub)</a>",
     "stub-threshold-disabled": "Wyłączone",
-    "recentchangesdays": "Liczba dni prezentowanych w ostatnich zmianach",
+    "recentchangesdays": "Liczba dni prezentowanych w ostatnich zmianach:",
     "recentchangesdays-max": "(maksymalnie $1 {{PLURAL:$1|dzień|dni}})",
-    "recentchangescount": "Domyślna liczba wyświetlanych edycji",
+    "recentchangescount": "Domyślna liczba wyświetlanych edycji:",
     "prefs-help-recentchangescount": "Uwzględnia ostatnie zmiany, historię stron i rejestry.",
     "prefs-help-watchlist-token2": "To jest tajny klucz umożliwiający dostęp do kanału internetowego zmian w obserwowanych przez ciebie stronach.\nKażdy, kto go zna, będzie mógł je zobaczyć, więc zachowaj go dla siebie.\n[[Special:ResetTokens|Kliknij tu, jeśli musisz go zresetować]].",
     "savedprefs": "Twoje preferencje zostały zapisane.",
     "unwatchthispage": "Nie obserwuj",
     "notanarticle": "To nie jest artykuł",
     "notvisiblerev": "Wersja została usunięta",
-    "watchlist-details": "Lista obserwowanych przez Ciebie stron zawiera {{PLURAL:$1|$1 pozycję|$1 pozycje|$1 pozycji}}, nie licząc stron dyskusji.",
+    "watchlist-details": "Lista obserwowanych przez Ciebie stron zawiera {{PLURAL:$1|$1 pozycję|$1 pozycje|$1 pozycji}}, nie licząc oddzielnie stron dyskusji.",
     "wlheader-enotif": "Wysyłanie powiadomień na adres e‐mail jest włączone.",
     "wlheader-showupdated": "'''Wytłuszczone''' zostały strony, które zostały zmodyfikowane od Twojej ostatniej wizyty na nich.",
     "watchmethod-recent": "poszukiwanie ostatnich zmian wśród obserwowanych stron",
     "contributions-title": "Wkład {{GENDER:$1|użytkownika|użytkowniczki}} $1",
     "mycontris": "Edycje",
     "contribsub2": "Dla {{GENDER:$3|użytkownika|użytkowniczki}} $1 ($2)",
+    "contributions-userdoesnotexist": "Konto użytkownika „$1” nie jest zarejestrowane.",
     "nocontribs": "Brak zmian odpowiadających tym kryteriom.",
     "uctop": "(ostatnia)",
     "month": "Do miesiąca (włącznie)",
     "previousdiff": "← poprzednia edycja",
     "nextdiff": "następna edycja →",
     "mediawarning": "'''Uwaga!''' Plik w tym formacie może zawierać złośliwy kod.\nJeśli go otworzysz, możesz zarazić swój system.",
-    "imagemaxsize": "Ograniczenie wielkości obrazków<br />''(na stronach opisu plików)''",
+    "imagemaxsize": "Ograniczenie wielkości obrazków:<br /><em>(na stronach opisu plików)</em>",
     "thumbsize": "Rozmiar miniaturki",
     "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|strona|strony|stron}}",
     "file-info": "rozmiar pliku: $1, typ MIME: $2",
index d3afed7..82a05b4 100644 (file)
     "permalink": "Anliura fissa",
     "print": "Stampé",
     "view": "Vardé",
+    "view-foreign": "Vëdde su $1",
     "edit": "Modifiché",
+    "edit-local": "Modifiché la descrission local",
     "create": "Creé",
+    "create-local": "Gionté na descrission local",
     "editthispage": "Modifiché costa pàgina",
     "create-this-page": "Creé sta pàgina",
     "delete": "Scancelé",
     "pool-timeout": "Ël temp a l'é finì antramentre ch'a së spetava la saradura",
     "pool-queuefull": "La coa ëd travaj a l'é pien-a",
     "pool-errorunknown": "Eror pa conossù",
+    "pool-servererror": "Ël servissi ëd conteur dl'arzerva a l'é nen disponìbil ($1).",
     "aboutsite": "A propòsit ëd {{SITENAME}}",
     "aboutpage": "Project:A propòsit",
     "copyright": "Ël contnù a resta disponìbil sota $1 gavà ch'a sia marcà an n'àutra manera.",
     "logdelete-selected": "{{PLURAL:$1|Event}} dël registr selessionà:",
     "revdelete-text-text": "Le revision ëscancelà a compariran ancora ant la stòria dla pàgina, ma na part ëd sò contnù a sarà inacessìbil al pùblich.",
     "revdelete-text-file": "Le version d'archivi scancelà a compariran ancora ant la stòria dj'archivi, ma na part ëd sò contnù a sarà inacessìbil al pùblich.",
+    "logdelete-text": "J'eveniment dl'argistr ëscancelà a compariran ancora ant j'argistr, ma na part ëd sò contnù a sarà inacessìbil al pùblich.",
+    "revdelete-text-others": "J'àutri aministrator ëd {{SITENAME}} a podran sempe acede al contù stërmà e a peulo ripristinelo torna con costa antërfassa, gavà ch'a sio definìe ëd restrission adissionaj.",
     "revdelete-confirm": "Për piasì, ch'a confema ch'a veul fé sòn, ch'as rend cont dle conseguense, e ch'a lo fa an acòrd con [[{{MediaWiki:Policy-url}}|le régole]].",
     "revdelete-suppress-text": "La scancelassion a dovrìa '''mach''' esse dovrà an costi cas:\n* Anformassion ch'a podrìo esse difamatòrie\n* Anformassion përsonaj inapropià\n*: ''adrësse ëd ca e nùmer ëd teléfon, còdes fiscaj, e via fòrt''",
     "revdelete-legend": "But-je coste limitassion-sì a le version scancelà:",
     "prefs-skin": "Facia",
     "skin-preview": "Preuva",
     "datedefault": "Franch l'istess",
-    "prefs-datetime": "Data e ora",
     "prefs-labs": "Caraterìstiche dël laboratòri",
     "prefs-user-pages": "Pàgine utent",
     "prefs-personal": "Profil dl'utent",
     "download": "dëscarié",
     "unwatchedpages": "Pàgine che gnun a ten sot-euj",
     "listredirects": "Lista dle ridiression",
+    "listduplicatedfiles": "Lista d'archivi con duplicà",
+    "listduplicatedfiles-summary": "Costa a l'é na lista d'archivi pr'ij quaj la version pi recenta dl'archivi a l'é un duplicà dla version pi recenta ëd chèich àutr archivi. Mach j'archivi local a son considerà.",
+    "listduplicatedfiles-entry": "[[:File:$1|$1]] a l'ha [[$3|{{PLURAL:$2|un dobion|$2 dobion}}]].",
     "unusedtemplates": "Stamp nen dovrà",
     "unusedtemplatestext": "Sta pàgina-sì a la smon tute lë pàgine ant lë spassi nominal {{ns:template}} che a son pa dovrà andrinta a d'àutre pàgine.\nCh'as visa ëd controlé che në stamp a-j serva nen a dj'àutri stamp anans che fé che ranchelo via.",
     "unusedtemplateswlh": "àutre anliure",
     "listgrouprights-removegroup-self": "Gavé {{PLURAL:$2|la partìa|le partìe}} da sò cont: $1",
     "listgrouprights-addgroup-self-all": "Gionté tute le partìe a sò cont",
     "listgrouprights-removegroup-self-all": "Gavé tute le partìe da sò cont",
+    "listgrouprights-namespaceprotection-header": "Restrission dë spassi nominal",
+    "listgrouprights-namespaceprotection-namespace": "Spassi nominal",
+    "listgrouprights-namespaceprotection-restrictedto": "Drit ch'a permëtto a l'utent ëd modifiché",
+    "trackingcategories": "Categorìe ëd trassament",
+    "trackingcategories-summary": "Costa pàgina a lista le categorìe ëd trassament ch'a son ampinìe an automàtich dal programa MediaWiki. Ij sò nòm a peulo esse cangià an modificand ij mëssagi ëd sistema rëspondent ant lë spassi nominal {{ns:8}}.",
+    "trackingcategories-msg": "Categorìa ëd trassament",
+    "trackingcategories-name": "Nòm dël mëssagi",
+    "trackingcategories-desc": "Criteri d'anclusion dla categorìa",
+    "noindex-category-desc": "La pàgina a l'é pa trassà dai robò përchè a conten la paròla màgica <code><nowiki>__NOINDEX__</nowiki></code> andrinta e a l'é an në spassi nominal anté che cost marcagi a l'é autorisà.",
+    "index-category-desc": "La pàgina a conten un <code><nowiki>__INDEX__</nowiki></code> (e a l'é an në spassi nominal anté che ëd marcagi a l'é autorisà); a l'é donca trassà dai robò antant che ëd sòlit a lo sarìa nen.",
+    "post-expand-template-inclusion-category-desc": "Apress avèj dësvlupà tuti jë stamp, la taja dla pàgina a sorpassa <code>$wgMaxArticleSize</code>, donca chèich ëstamp a son nen ëstàit dësvlupà.",
+    "post-expand-template-argument-category-desc": "Apress avèj dësvlupà l'argoment ëd në stamp (cheicòs antra tripl agraf, tanme <code>{{{Foo}}}</code>), la pàgina a l'é pi gròssa che <code>$wgMaxArticleSize</code>.",
+    "expensive-parserfunction-category-desc": "Tròpe fonsion care ëd l'analisator (parèj ëd <code>#ifexist</code>) contnùe an na pàgina. Ch'a vëdda [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
     "mailnologin": "A-i é pa l'adrëssa për mandé ël mëssagi",
     "mailnologintext": "A dev [[Special:UserLogin|rintré ant ël sistema]]\ne avèj registrà n'adrëssa ëd pòsta eletrònica vàlida ant ij [[Special:Preferences|sò gust]] për podèj mandé dij mëssagi ëd pòsta eletrònica a j'àutri Utent.",
     "emailuser": "Mandeje un mëssagi eletrònich a st'utent-sì",
index 349fa77..9c5b3bd 100644 (file)
     "permalink": "تلپاتې تړنه",
     "print": "چاپ",
     "view": "کتل",
+    "view-foreign": "په $1 باندې کتل",
     "edit": "سمول",
+    "edit-local": "سيمه ايزې څرگندونې سمول",
     "create": "جوړول",
+    "create-local": "سيمه ايزې څرگندونې ورگډول",
     "editthispage": "همدا مخ سمول",
     "create-this-page": "همدا مخ ليکل",
     "delete": "ړنگول",
     "prefs-skin": "پوښۍ",
     "skin-preview": "مخکتنه",
     "datedefault": "هېڅ نه ټاکل",
-    "prefs-datetime": "نېټه او وخت",
     "prefs-labs": "د آزمېښتون ځانگړنې",
     "prefs-user-pages": "کارن مخونه",
     "prefs-personal": "د کارن پېژنليک",
     "listgrouprights-removegroup-self": "خپل گڼون نه د {{PLURAL:$2|ډله|ډلې}} ليري کول: $1",
     "listgrouprights-addgroup-self-all": "خپل گڼون کې ټولې ډلې ورگډول",
     "listgrouprights-removegroup-self-all": "خپل گڼون نه ټولې ډلې ليري کول",
+    "listgrouprights-namespaceprotection-namespace": "نوم-تشيال",
+    "trackingcategories-name": "پيغام نوم",
     "mailnologin": "د لېږلو پته نشته",
     "emailuser": "کارن ته برېښليک لېږل",
     "emailuser-title-target": "دې {{GENDER:$1|کارن}} ته برېښليک لېږل",
     "unwatch": "نه کتل",
     "unwatchthispage": "څارنې په ټپه درول",
     "notanarticle": "يو منځپانګيز مخ نه دی",
-    "watchlist-details": "ستاسې کتنلړ کې {{PLURAL:$1|$1 مخ دی|$1 مخونه دي}}، د خبرو اترو مخونه مو پکې نه دي شمېرلي.",
+    "watchlist-details": "ستاسې کتنلړ کې {{PLURAL:$1|$1 مخ دی|$1 مخونه دي}}، د خبرو اترو مخونه مو بېل نه دي شمېرلي.",
     "wlheader-enotif": "برېښليک خبرونه چارنه شوې.",
     "wlheader-showupdated": "هغه مخونه چې ستاسې د کتلو نه وروسته بدلون موندلی په '''روڼ''' ليک په نښه شوي.",
     "watchlistcontains": "ستاسې کتنلړ $1 {{PLURAL:$1|مخ|مخونه}} لري.",
     "delete-edit-reasonlist": "د ړنگولو سببونه سمول",
     "rollback_short": "په شابېول",
     "rollbacklink": "په شابېول",
+    "rollbacklinkcount": "$1 {{PLURAL:$1|سمون|سمونونه}} پرشابېول",
     "protectlogpage": "د ژغورنې يادښت",
     "protectedarticle": "\"[[$1]]\" وژغورل شو",
     "modifiedarticleprotection": "د \"[[$1]]\" لپاره د ژغورنې کچه بدله شوه",
     "tooltip-watchlistedit-normal-submit": "سرليکونه غورځول",
     "tooltip-watchlistedit-raw-submit": "کتنلړ اوسمهالول",
     "tooltip-upload": "د پورته کولو پيل",
-    "tooltip-rollback": "Ù¾Ù\87 Ù\87Ù\85دÛ\90 Ù\85Ø® Ú©Û\90 \"Ù¾Ù\87 Ø´Ø§Ø¨Û\90Ù\88Ù\84\" Ø¯ Ù\88رÙ\88ستÙ\86Ù\8a Ù\88Ù\86Ú\89Ù\88اÙ\84 Ø³Ù\85Ù\88Ù\86 (سÙ\85Ù\88Ù\86Ù\88Ù\86Ù\87) Ù¾Ù\87 Ù\8aÙ\88Ù\87 Ú©Ù\84Û\90Ú© Ù¾Ù\87 Ú\85Ù¼ Ù\88رګرځوي.",
+    "tooltip-rollback": "Ù¾Ù\87 Ù\87Ù\85دÛ\90 Ù\85Ø® Ú©Û\90 \"Ù¾Ù\87 Ø´Ø§Ø¨Û\90Ù\88Ù\84\" Ø¯ Ù\88رÙ\88ستÙ\86Ù\8a Ù\88Ù\86Ú\89Ù\88اÙ\84 Ø³Ù\85Ù\88Ù\86 (سÙ\85Ù\88Ù\86Ù\88Ù\86Ù\87) Ù¾Ù\87 Ù\8aÙ\88Ù\87 Ú©Ù\84Û\90Ú© Ù¾Ù\87 Ú\85Ù¼ Ù\88رگرځوي.",
     "tooltip-undo": "\"ناکړ\" همدا سمون پر شا گرځوي او د سمون کړکۍ د مخکتنې په بڼه پرانيزي.\nدا کړنه د لنډيز په برخه کې د سمونونو د سببونو د ورگډولو آسانتيا برابروي.",
     "tooltip-preferences-save": "غوره توبونه خوندي کول",
     "tooltip-summary": "يو لنډ لنډيز کښل",
     "expand_templates_input": "ځايونکی متن:",
     "expand_templates_output": "پايله",
     "expand_templates_ok": "ښه",
+    "expand_templates_remove_nowiki": "په پايلو کې د <nowiki> نښلنونه ځپل",
+    "expand_templates_generate_rawhtml": "خام HTML ښکاره کول",
     "expand_templates_preview": "مخکتنه"
 }
index ed57c31..a9905f0 100644 (file)
     "accmailtitle": "Senha enviada.",
     "accmailtext": "Uma senha gerada aleatoriamente para [[User talk:$1|$1]] foi enviada para $2.\n\nEla pode ser alterada na página ''[[Special:ChangePassword|de troca de senha]]'', após o início de sessão.",
     "newarticle": "(Nova)",
-    "newarticletext": "Você seguiu um link para uma página que ainda não existe.\nPara criá-la, comece escrevendo na caixa abaixo (veja [$1 na página de ajuda] para mais informações).\nSe você chegou aqui por engano, clique no botão '''voltar''' do seu navegador.",
+    "newarticletext": "Você seguiu um link para uma página que ainda não existe.\nPara criá-la, comece escrevendo na caixa abaixo (veja [$1 a página de ajuda] para mais informações).\nSe você chegou aqui por engano, clique no botão '''voltar''' do seu navegador.",
     "anontalkpagetext": "---- ''Esta é a página de discussão para um usuário anônimo que ainda não criou uma conta ou que não a usa, de forma que temos de utilizar o endereço de IP para identificá-lo(a). Tal endereço de IP pode ser compartilhado por vários usuários. Se você é um usuário anônimo e acha que comentários irrelevantes foram direcionados a você, por gentileza, [[Special:UserLogin/signup|crie uma conta]] ou [[Special:UserLogin|autentique-se]], a fim de evitar futuras confusões com outros usuários anônimos.''",
     "noarticletext": "No momento, não há conteúdo nesta página.\nVocê pode [[Special:Search/{{PAGENAME}}|pesquisar pelo título desta página]] em outras páginas, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar por registros relacionados],\nou [{{fullurl:{{FULLPAGENAME}}|action=edit}} criar esta página]</span>.",
     "noarticletext-nopermission": "No momento, não há conteúdo nesta página\nVocê pode [[Special:Search/{{PAGENAME}}|pesquisar pelo título desta página]] em outras páginas,\nou <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar por registros relacionados] </span>. Note que, no entanto, você não tem permissão para criar esta página.",
     "prefs-skin": "Tema",
     "skin-preview": "Pré-visualização",
     "datedefault": "Sem preferência",
-    "prefs-datetime": "Data e hora",
     "prefs-labs": "Características de laboratório",
     "prefs-user-pages": "Páginas de usuário",
     "prefs-personal": "Dados do usuário",
index c7849f5..564ffe2 100644 (file)
     "prefs-skin": "Tema",
     "skin-preview": "Antever tema",
     "datedefault": "Sem preferência",
-    "prefs-datetime": "Data e hora",
     "prefs-labs": "Funcionalidades dos laboratórios",
     "prefs-user-pages": "Páginas de utilizador",
     "prefs-personal": "Dados do utilizador",
index 08f3e18..5f774d2 100644 (file)
     "noarticletext-nopermission": "See also {{msg-mw|Noarticletext}}.",
     "noarticletextanon": "{{notranslate}}\nDefault:\n* {{msg-mw|Noarticletext}}",
     "missing-revision": "Text displayed when the requested revision does not exist using a permalink.\n\nExample: [{{canonicalurl:Project:News|oldid=9999999}} Permalink with invalid revision#]\n\nParameters:\n* $1 - the ID of the missing revision",
-    "userpage-userdoesnotexist": "Error message displayed when trying to edit or create a page or a subpage that belongs to a user who is not registered on the wiki.\n\nParameters:\n* $1 - a possible username that has not been registered",
-    "userpage-userdoesnotexist-view": "Shown in user pages of non existing users. See for example [{{canonicalurl:User:Foo}} User:Foo].\n\nParameters:\n* $1 - a username",
+    "userpage-userdoesnotexist": "Error message displayed when trying to edit or create a page or a subpage that belongs to a user who is not registered on the wiki.\n\nParameters:\n* $1 - a username\n\n{{identical|userdoesnotexist}}",
+    "userpage-userdoesnotexist-view": "Shown in user pages of non-existing users. See for example [{{canonicalurl:User:Foo}} User:Foo].\n\nParameters:\n* $1 - a username\n\n{{identical|userdoesnotexist}}",
     "blocked-notice-logextract": "{{gender}}\nParameters:\n* $1 - (Optional) the name of the blocked user. Can be used for GENDER.",
     "clearyourcache": "Text at the top of .js/.css pages",
     "usercssyoucanpreview": "Text displayed on every CSS page.\n\nSee also:\n* {{msg-mw|Userjsyoucanpreview}}\n* {{msg-mw|Showpreview}}",
     "storedversion": "This is used in an edit conflict as the label for the top revision that has been stored, as opposed to your version {{msg-mw|yourtext}} that has not been stored which is shown at the bottom of the page.",
     "nonunicodebrowser": "Used as warning when editing page.",
     "editingold": "Used as warning when editing page.",
-    "yourdiff": "",
+    "yourdiff": "Used as h2 header for the diff of the current version of a page with the user's version in case there is an edit conflict or a spam filter hit.",
     "copyrightwarning": "Copyright warning displayed under the edit box in editor. Parameters:\n* $1 - link\n* $2 - license name",
     "copyrightwarning2": "Copyright warning displayed under the edit box in editor\n*$1 - license name",
     "editpage-head-copy-warn": "{{ignored}}Custom copyright warning in the header of an edit page.",
     "revdelete-no-file": "Used as error message in [[Special:RevisionDelete]].",
     "revdelete-show-file-confirm": "A confirmation message shown on [[Special:Revisiondelete]] when the request does not contain a valid token (e.g. when a user clicks a link received in mail).\n\nParameters:\n* $1 - a file name\n* $2 - a date\n* $3 - a time\n{{Identical|Are you sure you want to view the deleted revision of the file...}}",
     "revdelete-show-file-submit": "Reply to {{msg-mw|Revdelete-show-file-confirm}}.\n\n{{Identical|Yes}}",
-    "revdelete-selected-text": "{{Related|Revdelete-selected}}",
-    "revdelete-selected-file": "{{Related|Revdelete-selected}}",
-    "logdelete-selected": "{{RevisionDelete}}\nParameters:\n* $1 - number of log events\n* $2 - (Unused) localized name of Special:Log, maybe with type as subpage\n{{Related|Revdelete-selected}}",
+    "revdelete-selected-text": "Parameters:\n* $1 - number of revisions\n* $2 - page title\n{{Related|Revdelete-selected}}",
+    "revdelete-selected-file": "Parameters:\n* $1 - number of revisions\n* $2 - page title\n{{Related|Revdelete-selected}}",
+    "logdelete-selected": "{{RevisionDelete}}\nParameters:\n* $1 - number of log events\n* $2 - (Unused) localized name of [[Special:Log]], maybe with type as subpage\n{{Related|Revdelete-selected}}",
     "revdelete-text-text": "{{RevisionDelete}}\nThis is the introduction explaining the feature.\n\nSee also:\n* {{msg-mw|Revdelete-text-file}}\n* {{msg-mw|Logdelete-text}}\n* {{msg-mw|Revdelete-text-others}}",
     "revdelete-text-file": "{{RevisionDelete}}\nThis is the introduction explaining the feature.\n\nSee also:\n* {{msg-mw|Revdelete-text-text}}\n* {{msg-mw|Logdelete-text}}\n* {{msg-mw|Revdelete-text-others}}",
     "logdelete-text": "{{RevisionDelete}}\nThis is the introduction explaining the feature.\n\nSee also:\n* {{msg-mw|Revdelete-text-text}}\n* {{msg-mw|Revdelete-text-file}}\n* {{msg-mw|Revdelete-text-others}}",
     "defaultns": "Used in [[Special:Preferences]], tab \"Search\".",
     "default": "{{Identical|Default}}",
     "prefs-files": "Title of a tab in [[Special:Preferences]].\n{{Identical|File}}",
-    "prefs-custom-css": "visible on [[Special:Preferences]] -[Skins].",
-    "prefs-custom-js": "visible on [[Special:Preferences]] -[Skins].",
+    "prefs-custom-css": "visible on [[Special:Preferences]] -[Skins].\n{{Identical|Custom CSS}}",
+    "prefs-custom-js": "visible on [[Special:Preferences]] -[Skins].\n{{Identical|Custom JavaScript}}",
     "prefs-common-css-js": "Used as label in [[Special:Preferences#mw-prefsection-rendering|preferences]], tab \"Appearance\", section \"Skin\".",
     "prefs-reset-intro": "Used in [[Special:Preferences/reset]].",
     "prefs-emailconfirm-label": "Sub-heading in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}.",
     "listgrouprights-addgroup-self-all": "Used on [[Special:ListGroupRights]].\n{{Related|Listgrouprights}}",
     "listgrouprights-removegroup-self-all": "Used on [[Special:ListGroupRights]].\n{{Related|Listgrouprights}}",
     "listgrouprights-namespaceprotection-header": "Shown on [[Special:ListGroupRights]] as the header for the namespace restrictions table.",
-    "listgrouprights-namespaceprotection-namespace": "Shown on [[Special:ListGroupRights]] as the 'namespace' column header for the namespace restrictions table.",
-    "listgrouprights-namespaceprotection-restrictedto": "Shown on [[Special:ListGroupRights]] as the 'right(s) allowing user to edit' column header for the namespace restrictions table.",
+    "listgrouprights-namespaceprotection-namespace": "Shown on [[Special:ListGroupRights]] as the 'namespace' column header for the namespace restrictions table.\n{{Identical|Namespace}}",
+    "listgrouprights-namespaceprotection-restrictedto": "Shown on [[Special:ListGroupRights]] as the \"right(s) allowing user to edit\" column header for the namespace restrictions table.",
     "trackingcategories": "[[Special:TrackingCategories]] page implementing list of Tracking categories [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]].\n{{Identical|Tracking category}}",
     "trackingcategories-summary": "Description for [[Special:TrackingCategories]] page [[mw:Help:Tracking categories|tracking category]]",
     "trackingcategories-msg": "Header for the message column of the table on [[Special:TrackingCategories]]. This column lists the mediawiki message that controls the tracking category in question.\n{{Identical|Tracking category}}",
     "contributions-title": "{{Gender}}\nThe page title in your browser bar, but not the page title.\n\nParameters:\n* $1 - the username\nSee also:\n* {{msg-mw|Contributions}}",
     "mycontris": "In the personal urls page section - right upper corner.\n\nSee also:\n* {{msg-mw|Mycontris}}\n* {{msg-mw|Accesskey-pt-mycontris}}\n* {{msg-mw|Tooltip-pt-mycontris}}\n{{Identical|Contribution}}",
     "contribsub2": "Contributions for \"user\" (links). Parameters:\n* $1 is an IP address or a username, with a link which points to the user page (if registered user).\n* $2 is list of tool links. The list contains a link which has text {{msg-mw|Sp-contributions-talk}}.\n* $3 is a plain text username used for GENDER.\n{{Identical|For $1}}",
+    "contributions-userdoesnotexist": "This message is used in [[Special:Contributions]]. It is used to tell the user that the name he searched for doesn't exists.\n\nParameters:\n* $1 - a username\n\n{{identical|userdoesnotexist}}",
     "nocontribs": "Used in [[Special:Contributions]] and [[Special:DeletedContributions]].\n\nSee examples: [[Special:Contributions/x]] and [[Special:DeletedContributions/x]].\n\nParameters:\n* $1 - (Unused) the user name",
     "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|Top}}",
     "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}}.",
index ae06c72..e931dfb 100644 (file)
     "session_fail_preview_html": "''Stgisa! Tia modificaziun na pudeva betg vegnir memorisada perquei che las datas da la sesida èn idas a perder.'''\n\n''Perquai che {{SITENAME}} ha activà la pussaivlada d'utilisar HTML è la prevista betg visibla per impedir attaccas cun JavaScript.''\n\n'''Emprova per plaschair danovamain.'''\nSche quai na funcziuna anc adina betg, emprova da [[Special:UserLogout|partir]] ed anc ina giada t'annunziar.",
     "token_suffix_mismatch": "'''Tia modificaziun è vegnida refusada perquai che tes navigatur ha manizzà ils segns en il token da modifitgar.'''\nLa modificaziun è vegnida refusada per evitar ch'il cuntegn da la pagina vegnia destruì. \nQuai po capitar sche ti utiliseschas in survetsch da proxy anonim che na funcziuna betg correctamain.",
     "edit_form_incomplete": "'''Entginas parts dal formular da modifitgar n'èn betg arrivadas cumplattamain al server; controllescha p.pl. che tias midadas èn intactas ed emprova danovamain.'''",
-    "editing": "Modifitgar $1",
-    "creating": "Crear $1",
-    "editingsection": "Modifitgar $1 (secziun)",
-    "editingcomment": "Modifitgar $1 (nova secziun)",
+    "editing": "Modifitgar «$1»",
+    "creating": "Crear «$1»",
+    "editingsection": "Modifitgar «$1» (secziun)",
+    "editingcomment": "Modifitgar «$1» (nova secziun)",
     "editconflict": "Conflict da modifitgar: $1",
     "explainconflict": "Insatgi auter ha midà questa pagina dapi che ti has cumenzà a la modifitgar. \nIl champ d'endataziun sura cuntegna il text sco che la pagina vesa ora actualmain. \nTias midadas èn mussadas en il champ d'endataziun sut. \nTi stos integrar tias midadas en il text existent. \n'''Mo''' il text en il champ d'endataziun sura vegn memorià sche ti cliccas sin \"{{int:savearticle}}\".",
     "yourtext": "Tes text",
     "prefs-skin": "Skin",
     "skin-preview": "Prevista",
     "datedefault": "Nagina preferenza",
-    "prefs-datetime": "Data e temp",
     "prefs-labs": "Funcziuns experimentalas",
     "prefs-user-pages": "Paginas dad utilisader",
     "prefs-personal": "Profil da l'utilisader",
index 6ebacee..7dca401 100644 (file)
     "view": "Lectură",
     "view-foreign": "Vizualizare la $1",
     "edit": "Modificare",
-    "edit-local": "Modifică descrierea locală",
+    "edit-local": "Modificare descriere locală",
     "create": "Creare",
-    "create-local": "Adaugă descriere locală",
+    "create-local": "Adăugare descriere locală",
     "editthispage": "Modificați pagina",
     "create-this-page": "Creați această pagină",
     "delete": "Ștergere",
     "prefs-skin": "Aspect",
     "skin-preview": "Previzualizare",
     "datedefault": "Nici o preferință",
-    "prefs-datetime": "Data și ora",
     "prefs-labs": "Opțiuni „labs”",
     "prefs-user-pages": "Pagini de utilizator",
     "prefs-personal": "Informații personale",
     "unwatchthispage": "Nu mai urmări",
     "notanarticle": "Nu este un articol",
     "notvisiblerev": "Versiunea a fost ștearsă",
-    "watchlist-details": "{{PLURAL:$1|O pagină|$1 pagini urmărite|$1 de pagini urmărite}}, excluzând paginile de discuție.",
+    "watchlist-details": "{{PLURAL:$1|O pagină|$1 pagini urmărite|$1 de pagini urmărite}}, fără a include separat paginile de discuție.",
     "wlheader-enotif": "Notificarea prin e-mail este activată.",
     "wlheader-showupdated": "Paginile care au fost modificate după ultima dumneavoastră vizită sunt afișate '''îngroșat'''.",
     "watchmethod-recent": "căutarea schimbărilor recente pentru paginile urmărite",
index c43fc38..1dec640 100644 (file)
     "prefs-skin": "Тема оформления",
     "skin-preview": "Предпросмотр",
     "datedefault": "По умолчанию",
-    "prefs-datetime": "Дата и время",
     "prefs-labs": "Экспериментальные возможности",
     "prefs-user-pages": "Страницы участника",
     "prefs-personal": "Личные данные",
     "contributions-title": "Вклад {{GENDER:$1|участника|участницы}} $1",
     "mycontris": "Вклад",
     "contribsub2": "Вклад {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "Не зарегистрировано учётной записи «$1».",
     "nocontribs": "Изменений, соответствующих заданным условиям, найдено не было.",
     "uctop": "(текущая)",
     "month": "С месяца (и ранее):",
index 6ef319a..f853559 100644 (file)
     "history-feed-description": "अस्मिन् विकि-जालस्थाने तस्मै पृष्ठाय संस्करणेतिहासः",
     "history-feed-item-nocomment": "$1 द्वारा $3 दिनाङ्के $4 समये",
     "history-feed-empty": "एतत् पृष्ठं न विद्यते । \nएतस्य पृष्ठस्य नामपरिवर्तनम्, अपाकरणं च कृतं स्यात् । \n अनेन सम्बद्धानि पृष्ठानि [[Special:Search|विकि-जालस्थाने अन्विष्यताम्]] ।",
-    "rev-deleted-comment": "(समà¥\8dपादनसà¥\8dय à¤¸à¤¾à¤°à¤\83 à¤\85पाà¤\95à¥\83तमसà¥\8dति)",
+    "rev-deleted-comment": "(समà¥\8dपादनसà¥\8dय à¤¸à¤¾à¤°à¤\83 à¤\85पाà¤\95à¥\83तà¤\83)",
     "rev-deleted-user": "(प्रयोक्तृनाम अपाकृतमस्ति)",
-    "rev-deleted-event": "(à¤\85भिलà¥\87à¤\96न-à¤\95à¥\8dरिया à¤\85पाà¤\95à¥\83ताऽसà¥\8dति)",
-    "rev-deleted-user-contribs": "[पà¥\8dरयà¥\8bà¤\95à¥\8dतà¥\83नाम à¤\85थवा à¤\86à¤\87पà¥\80सà¤\82à¤\95à¥\87तà¤\83 à¤\85पाà¤\95à¥\83तà¤\83 - à¤¸à¤®à¥\8dपादनà¤\82 à¤¯à¥\8bà¤\97दानà¥\87भà¥\8dयà¤\83 à¤¨à¤¿à¤\97à¥\82ढमसà¥\8dति]",
-    "rev-deleted-text-permission": "à¤\85सà¥\8dय à¤ªà¥\81à¤\9fसà¥\8dय à¤ªà¥\81नरवतरणमà¥\8d à¤\85पमारà¥\8dà¤\9cितमà¥\8d à¥¤ à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dयतà¥\87  à¥¤ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
-    "rev-deleted-text-unhide": "à¤\85सà¥\8dय à¤ªà¥\81à¤\9fसà¥\8dय à¤ªà¥\81नरवतरणमà¥\8d à¤\85पमारà¥\8dà¤\9cितमà¥\8d à¥¤ à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dयतà¥\87 à¥¤ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].\nYou can still [$1 view this revision]",
-    "rev-suppressed-text-unhide": "à¤\85सà¥\8dय à¤ªà¥\81à¤\9fसà¥\8dय à¤ªà¥\81नरवतरणà¤\82 ''' à¤¨à¤¿à¤·à¤¿à¤¦à¥\8dधमà¥\8d ''' à¤¯à¤¦à¤¿ à¤\85नà¥\81वरà¥\8dतनमिà¤\9aà¥\8dà¤\9bति à¤¤à¤°à¥\8dहि à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dयतà¥\87 à¥¤ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].\nYou can still [$1 view this revision]",
-    "rev-deleted-text-view": "à¤\8fतसà¥\8dमातà¥\8d à¤\85नà¥\8dतरतà¤\83 à¤\95िà¤\9eà¥\8dà¤\9aिदवतरणà¤\82 à¤ªà¤°à¤¿à¤®à¤¾à¤°à¥\8dà¤\9cितमà¥\8d à¥¤ à¤\8fतदनà¥\8dतरà¤\82 à¤¦à¥\83षà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\81वनà¥\8dति à¥¤ à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} à¤¹à¤\9fानà¥\87 à¤\95à¥\80 à¤²à¥\89à¤\97]",
-    "rev-suppressed-text-view": "à¤\85सà¥\8dमिनà¥\8dननà¥\8dतरà¥\87 à¤\95िà¤\9eà¥\8dà¤\9aिदवतरणà¤\82 à¤¸à¤\99à¥\8dà¤\97à¥\81पतमà¥\8d à¥¤ à¤¤à¤¦à¤¨à¥\8dतरमà¥\8d à¤\85तà¥\8dर à¤¦à¥\83षà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\81वनà¥\8dति à¥¤ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].",
-    "rev-deleted-no-diff": "à¤\8fततà¥\8d à¤¦à¥\83षà¥\8dà¤\9fà¥\81à¤\82 à¤¨à¥\88व à¤¶à¤\95à¥\8dयतà¥\87 à¤¯à¤¤à¤\83 à¤ªà¥\81नरावरà¥\8dतनà¤\82 à¤ªà¤°à¤¿à¤®à¤¾à¤°à¥\8dà¤\9cितमà¥\8d à¥¤ à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dयतà¥\87 à¥¤ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
-    "rev-suppressed-no-diff": "à¤\8fतदनà¥\8dतरà¤\82 à¤¦à¥\83षà¥\8dà¤\9fà¥\81à¤\82 à¤¨à¥\88व à¤¶à¤\95à¥\8dयतà¥\87 à¤¯à¤¤à¤\83 à¤\85तà¥\8dर à¤\95िà¤\9eà¥\8dà¤\9aिदवतरणà¤\82 à¤ªà¤°à¤¿à¤®à¤¾à¤°à¥\8dà¤\9cितमà¥\8d ।",
-    "rev-deleted-unhide-diff": "à¤\85सà¥\8dय à¤ªà¥\81à¤\9fसà¥\8dय à¤ªà¥\81नरवतरणमà¥\8d à¤\85पमारà¥\8dà¤\9cितमà¥\8d à¥¤ à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dयतà¥\87 à¥¤ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].\nYou can still [$1 view this revision]",
-    "rev-suppressed-unhide-diff": "à¤\85सà¥\8dय à¤ªà¥\81à¤\9fसà¥\8dय à¤ªà¥\81नरवतरणà¤\82 ''' à¤¨à¤¿à¤·à¤¿à¤¦à¥\8dधमà¥\8d ''' à¤¯à¤¦à¤¿ à¤\85नà¥\81वरà¥\8dतनमिà¤\9aà¥\8dà¤\9bति à¤¤à¤°à¥\8dहि à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dयतà¥\87 à¥¤ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].\nYou can still [$1 view this revision]",
-    "rev-deleted-diff-view": "à¤\8fतसà¥\8dमातà¥\8d à¤\85नà¥\8dतरतà¤\83 à¤\95िà¤\9eà¥\8dà¤\9aिदवतरणà¤\82 à¤ªà¤°à¤¿à¤®à¤¾à¤°à¥\8dà¤\9cितमà¥\8d à¥¤ à¤\8fतदनà¥\8dतरà¤\82 à¤¦à¥\83षà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\81वनà¥\8dति à¥¤ à¤µà¤¿à¤µà¤°à¤£à¤®à¥\8d [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} à¤¹à¤\9fानà¥\87 à¤\95à¥\80 à¤²à¥\89à¤\97]",
-    "rev-suppressed-diff-view": "à¤\85सà¥\8dमिनà¥\8dननà¥\8dतरà¥\87 à¤\95िà¤\9eà¥\8dà¤\9aिदवतरणà¤\82 à¤¸à¤\99à¥\8dà¤\97à¥\81पतमà¥\8d à¥¤ à¤¤à¤¦à¤¨à¥\8dतरमà¥\8d à¤\85तà¥\8dर à¤¦à¥\83षà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\81वनà¥\8dति à¥¤ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].",
+    "rev-deleted-event": "(सà¤\82रà¤\95à¥\8dषिताऽऽवलà¥\8dयà¤\83(log) à¤\85पाà¤\95à¥\83ताà¤\83)",
+    "rev-deleted-user-contribs": "[पà¥\8dरयà¥\8bà¤\95à¥\8dतà¥\83नाम à¤\85नà¥\8dतरà¥\8dà¤\9cालसà¤\82विदà¥\8d à¤µà¤¾ à¤\85पाà¤\95à¥\83तमà¥\8d - à¤¯à¥\8bà¤\97दानाऽऽवलà¥\8dयामà¥\8d à¤\8fतानि à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनानि à¤¨à¤¿à¤\97à¥\82ढितानि à¤¸à¤¨à¥\8dति à¥¤]",
+    "rev-deleted-text-permission": "à¤\8fतसà¥\8dय à¤ªà¥\83षà¥\8dठसà¥\8dय à¤¸à¤\82सà¥\8dà¤\95रणमà¥\8d <strong>à¤\85पाà¤\95à¥\83तमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+    "rev-deleted-text-unhide": "à¤\8fतसà¥\8dय à¤ªà¥\83षà¥\8dठसà¥\8dय à¤¸à¤\82सà¥\8dà¤\95रणमà¥\8d <strong>à¤\85पाà¤\95à¥\83तमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]. \n\nयदि à¤\87à¤\9aà¥\8dà¤\9bति, à¤¤à¤°à¥\8dहि à¤\85तà¥\8dरापि [$1 view this revision] à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति à¥¤",
+    "rev-suppressed-text-unhide": "à¤\8fतसà¥\8dय à¤ªà¥\83षà¥\8dठसà¥\8dय à¤¸à¤\82सà¥\8dà¤\95रणमà¥\8d <strong>निषिदà¥\8dधमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]. \n\nयदि à¤\87à¤\9aà¥\8dà¤\9bति, à¤¤à¤°à¥\8dहि à¤\85तà¥\8dरापि [$1 view this revision] à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति à¥¤",
+    "rev-deleted-text-view": "à¤\8fतसà¥\8dय à¤ªà¥\83षà¥\8dठसà¥\8dय à¤¸à¤\82सà¥\8dà¤\95रणमà¥\8d <strong>à¤\85पाà¤\95à¥\83तमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+    "rev-suppressed-text-view": "à¤\8fतसà¥\8dय à¤ªà¥\83षà¥\8dठसà¥\8dय à¤¸à¤\82सà¥\8dà¤\95रणमà¥\8d <strong>निषिदà¥\8dधमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+    "rev-deleted-no-diff": "भवानà¥\8d/भवतà¥\80 à¤¸à¤\82सà¥\8dà¤\95रणसà¥\8dय à¤­à¥\87दà¤\82 à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¨ à¤¶à¤\95à¥\8dनà¥\8bति à¥¤ à¤\95ारणमà¥\8d à¤\8fतसà¥\8dय à¤\95िमपि à¤¸à¤\82सà¥\8dà¤\95रणà¤\82 <strong>à¤\85पाà¤\95à¥\83तमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+    "rev-suppressed-no-diff": "भवानà¥\8d/भवतà¥\80 à¤¸à¤\82सà¥\8dà¤\95रणसà¥\8dय à¤­à¥\87दà¤\82 à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¨ à¤¶à¤\95à¥\8dनà¥\8bति à¥¤ à¤\95ारणमà¥\8d à¤\8fतसà¥\8dय à¤\95िमपि à¤¸à¤\82सà¥\8dà¤\95रणà¤\82 <strong>à¤\85पाà¤\95à¥\83तमसà¥\8dति</strong> ।",
+    "rev-deleted-unhide-diff": "भवानà¥\8d/भवतà¥\80 à¤¸à¤\82सà¥\8dà¤\95रणसà¥\8dय à¤­à¥\87दà¤\82 à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¨ à¤¶à¤\95à¥\8dनà¥\8bति à¥¤ à¤\95ारणमà¥\8d à¤\8fतसà¥\8dय à¤\95िमपि à¤¸à¤\82सà¥\8dà¤\95रणà¤\82 <strong>à¤\85पाà¤\95à¥\83तमसà¥\8dति</strong> à¥¤\n\nयदि à¤\87à¤\9aà¥\8dà¤\9bति, à¤¤à¤°à¥\8dहि à¤\85तà¥\8dरापि [$1 view this revision] à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति à¥¤",
+    "rev-suppressed-unhide-diff": "भवानà¥\8d/भवतà¥\80 à¤¸à¤\82सà¥\8dà¤\95रणसà¥\8dय à¤­à¥\87दà¤\82 à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¨ à¤¶à¤\95à¥\8dनà¥\8bति à¥¤ à¤\95ारणमà¥\8d à¤\8fतसà¥\8dय à¤\95िमपि à¤¸à¤\82सà¥\8dà¤\95रणà¤\82 <strong>निषिदà¥\8dधमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]. \n\nयदि à¤\87à¤\9aà¥\8dà¤\9bति, à¤¤à¤°à¥\8dहि à¤\85तà¥\8dरापि [$1 view this revision] à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति à¥¤",
+    "rev-deleted-diff-view": "भवानà¥\8d/भवतà¥\80 à¤¸à¤\82सà¥\8dà¤\95रणसà¥\8dय à¤­à¥\87दà¤\82 à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¨ à¤¶à¤\95à¥\8dनà¥\8bति à¥¤ à¤\95ारणमà¥\8d à¤\8fतसà¥\8dय à¤\95िमपि à¤¸à¤\82सà¥\8dà¤\95रणà¤\82 <strong>निषिदà¥\8dधमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+    "rev-suppressed-diff-view": "भवानà¥\8d/भवतà¥\80 à¤¸à¤\82सà¥\8dà¤\95रणसà¥\8dय à¤­à¥\87दà¤\82 à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81à¤\82 à¤¨ à¤¶à¤\95à¥\8dनà¥\8bति à¥¤ à¤\95ारणमà¥\8d à¤\8fतसà¥\8dय à¤\95िमपि à¤¸à¤\82सà¥\8dà¤\95रणà¤\82 <strong>निषिदà¥\8dधमसà¥\8dति</strong> à¥¤\nविसà¥\8dतà¥\83तà¤\82 à¤\9cà¥\8dà¤\9eानमà¥\8d à¤\85तà¥\8dर à¤ªà¥\8dरापà¥\8dतà¥\81à¤\82 à¤¶à¤\95à¥\8dनà¥\8bति... [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
     "rev-delundel": "दृश्यताम्/गोप्यताम्",
     "rev-showdeleted": "दर्श्यताम्",
-    "revisiondelete": "à¤\85वतरणà¤\82 à¤ªà¤°à¤¿à¤®à¤¾à¤°à¥\8dà¤\9cयतà¥\81/पà¥\81नस्थापयतु",
-    "revdelete-nooldid-title": "लà¤\95à¥\8dषà¥\8dयरà¥\82पा à¤\86वà¥\83तà¥\8dतिà¤\83 à¤\85मानà¥\8dयाऽसà¥\8dति।",
-    "revdelete-nooldid-text": "एतत्कार्यं कर्तुं भवतः अवतरणं न दत्तम् । अथवा भवता दत्तावतरणस्य अस्तित्वं नास्ति । अथवा सद्यः अवतरणस्य सङ्गोपनं कुर्वन् अस्ति ।",
+    "revisiondelete": "सà¤\82सà¥\8dà¤\95रणानि à¤¨à¤¿à¤·à¥\8dà¤\95ासयतà¥\81/पà¥\81नसà¥\8dस्थापयतु",
+    "revdelete-nooldid-title": "à¤\85यà¥\8bà¤\97à¥\8dयलà¤\95à¥\8dषà¥\8dयसà¥\8dय à¤¸à¤\82शà¥\8bधनमà¥\8d",
+    "revdelete-nooldid-text": "एतत् कार्यं कर्तुं भवता/भवत्या लक्ष्य न निर्धारितम् एतत् संस्करणं न भवेत् वा । भवान्/भवती एतत् संस्करणं निगूढितुम् प्रयतति इत्यपि शक्यम् ।",
     "revdelete-no-file": "निर्दिष्टा सञ्चिका न विद्यते ।",
-    "revdelete-show-file-confirm": "$2 à¤¤à¤\83 $3 à¤®à¤§à¥\8dयà¥\87 \"<nowiki>$1</nowiki>\" à¤\87ति à¤¸à¤\9eà¥\8dà¤\9aिà¤\95ायाà¤\83 à¤¨à¤¿à¤°à¤¸à¥\8dतà¤\82 à¤ªà¤°à¤¿à¤·à¥\8dà¤\95रणà¤\82 à¤­à¤µà¤¾à¤¨à¥\8d à¤¨à¥\82नà¤\82 à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81मà¥\8d à¤\87à¤\9aà¥\8dà¤\9bति ?",
+    "revdelete-show-file-confirm": "$2 à¤¦à¤¿à¤¨à¤¾à¤\99à¥\8dà¤\95सà¥\8dय  $3 à¤¸à¤®à¤¯à¤ªà¤°à¥\8dयनà¥\8dतसà¥\8dय  \"<nowiki>$1</nowiki>\" à¤\87तà¥\8dयसà¥\8dयाà¤\83 à¤\85पाà¤\95à¥\83तसà¤\9eà¥\8dà¤\9aिà¤\95ायाà¤\83 à¤¸à¤\82सà¥\8dà¤\95रणाऽऽवलिà¤\82 à¤­à¤µà¤¾à¤¨à¥\8d/भवतà¥\80 à¤¨à¤¿à¤¶à¥\8dà¤\9aयà¥\87न à¤¦à¥\8dरषà¥\8dà¤\9fà¥\81मà¥\8d à¤\88पà¥\8dसति ?",
     "revdelete-show-file-submit": "आम्",
-    "logdelete-selected": "{{PLURAL:$1|Selected log event|Selected log events}}:",
-    "revdelete-confirm": "भवान् एतत् कार्यं करोति इति दढयतु । भवान् अस्य परिणामं जानाति । [[{{MediaWiki:Policy-url}}|the policy]] भवान् एतदनुसारं करोति ।",
-    "revdelete-suppress-text": "अधोनिदेशितपरिस्थितिषु केवलं निग्रहः कार्यः । \n* अवमाननीयाः विषयाः ।\n* अप्रधानाः वैयक्तिकविषयाः\n* गृहसङ्केतः, दूरवाणीसङ्ख्या, सामाजिकसुरक्षासङ्ख्या, इत्यादयः ।",
-    "revdelete-legend": "दृश्यप्रतिबन्धं निश्चिनोतु ।",
-    "revdelete-hide-text": "अवतरणस्य पाठं गोपयतु ।",
-    "revdelete-hide-image": "सञ्चिकाधेयं गोपयतु ।",
-    "revdelete-hide-name": "प्रक्रियां लक्ष्यं च गोपयतु ।",
-    "revdelete-hide-comment": "सम्पादनसारं गोपयतु ।",
-    "revdelete-hide-user": "सम्पादकस्य योजकनाम/आइपिसंकेतः गोप्यताम्।",
-    "revdelete-hide-restricted": "प्रबन्धकेभ्यः अन्येभ्यश्च समंकं गोपयतु।",
-    "revdelete-radio-same": "मा परिवर्तयतु।",
-    "revdelete-radio-set": "आम्",
-    "revdelete-radio-unset": "न हि",
-    "revdelete-suppress": "प्रबन्धकेभ्यः अन्येभ्यश्च समंकं गोपयतु।",
-    "revdelete-unsuppress": "प्रत्यानीताऽऽवृत्तिभ्यः  वर्जनाः अपाकरोतु।",
+    "revdelete-selected-text": "[[:$2]] इत्यस्य {{PLURAL:$1|चित-परिवर्तनं|चित-परिवर्तनानि}} :",
+    "revdelete-selected-file": "[[:$2]] इत्यस्य {{PLURAL:$1|चित-सञ्चिका|चित-सञ्चिकाः}} :",
+    "logdelete-selected": "[[:$2]] इत्यस्य {{PLURAL:$1|चित-संरक्षिताऽऽवलेः घटना|संरक्षिताऽऽवलेः घटनाः}} :",
+    "revdelete-text-text": "पृष्ठस्य इतिहासे अधुनापि अपाकृतानि संस्करणानि द्रष्टुं शक्यन्ते । परन्तु सामान्ययोजकेभ्यः तत्र परिवर्तनम् अशक्यम् ।",
+    "revdelete-text-file": "सञ्चिकायाः इतिहासे अधुनापि अपाकृतानां सञ्चिकानां संस्करणानि द्रष्टुं शक्यन्ते । परन्तु सामान्ययोजकेभ्यः तत्र परिवर्तनम् अशक्यम् ।",
+    "logdelete-text": "संरक्षिताऽऽवलीनां(log) संस्करणानि संरक्षिताऽऽवल्यां द्रष्टुं शक्यन्ते । परन्तु सामान्ययोजकेभ्यः तत्र परिवर्तनम् अशक्यम् ।",
+    "revdelete-confirm": "एतस्याः [[{{MediaWiki:Policy-url}}|नीतेः]] अन्तर्गतं भवता/भवत्या एतत् कार्यं गभीरतया क्रियमाणम् अस्ति इत्यस्य पुष्टतां करोतु ।",
+    "revdelete-suppress-text": "<strong>केवलं</strong> निम्नकारणेभ्यः निषेधः योग्यः....\n१ भयोत्पादकमाहिती स्यात्\n२ वैयक्तिकमाहिती स्यात्\n३ <em>गृहसङ्केतः, दूरभाषसङ्केतः, राष्ट्रियपरिचयपत्रस्य अङ्कः इत्यादीनि माहितयः स्युः ।</em>",
+    "revdelete-legend": "दृश्यप्रतिबन्धं निश्चितं करोतु",
+    "revdelete-hide-text": "संस्करणस्थं लेखनं (text)",
+    "revdelete-hide-image": "सञ्चिकाधेयं गोप्यताम्",
+    "revdelete-hide-name": "प्रक्रियां, लक्ष्यं च गोप्यताम्",
+    "revdelete-hide-comment": "सम्पादनसारं गोप्यताम्",
+    "revdelete-hide-user": "योजकस्य प्रयोकतृनाम/अन्तर्जालसंविद् (IP)",
+    "revdelete-hide-restricted": "प्रबन्धकेभ्यः, अन्येभ्यश्च माहिती गोप्यताम्",
+    "revdelete-radio-same": "(मा परिवर्त्यताम्)",
+    "revdelete-radio-set": "निगूढितम्",
+    "revdelete-radio-unset": "प्रत्यक्षम्",
+    "revdelete-suppress": "प्रबन्धकेभ्यः, अन्येभ्यश्च माहिती गोप्यताम्",
+    "revdelete-unsuppress": "पुनस्स्थापितसंस्करणानां प्रतिबन्धः अपाक्रियताम्",
     "revdelete-log": "कारणम् :",
-    "revdelete-submit": "{{PLURAL:$1|चितायां आवृत्त्यां|चितासु आवृत्तिषु}} अनुप्रयोजयतु।",
-    "revdelete-success": "अवतरणदृश्यता साफल्येन उन्नतीकृता ।",
-    "revdelete-failure": "अवतरणदृश्यता उन्नतीकरणं न शक्यते ।$1",
-    "logdelete-success": "नामाङ्कनदृश्यता साफल्येन योजिता ।",
-    "logdelete-failure": "नामाभिलेखदृश्यता सपला नाभवत् । $1",
+    "revdelete-submit": "{{PLURAL:$1|चित-संस्करणे|चित-संस्करणेषु}} प्रयोगं क्रियताम्",
+    "revdelete-success": "<strong>संस्करणस्य दृश्यता साफल्येन अद्यतनकृता </strong>",
+    "revdelete-failure": "<strong>संस्करणस्य दृश्यता अद्यतना नाभवत् </strong> $1",
+    "logdelete-success": "<strong>संरक्षिताऽऽवल्याः दृश्यता योग्यतया परिवर्तिता ।</strong>",
+    "logdelete-failure": "<strong>संरक्षिताऽऽवल्याः दृश्यता न परिवर्तिता ।</strong> $1",
     "revdel-restore": "दृश्यता परिवर्त्यताम्",
     "pagehist": "पृष्ठस्य इतिहासः",
-    "deletedhist": "परिमारà¥\8dà¤\9cितà¥\87तिहासà¤\83 à¥¤",
-    "revdelete-hide-current": "$2 $1 दिनाङ्कितस्य गोपने दोषः । एतत् प्रकृतावतरणम्, एतत् न गोपनीयम् ।",
-    "revdelete-show-no-access": "$2, $1: दिनाङ्कितस्य दर्शने दोषः । एतत् पञ्जीकृतमिति अङ्कितम् । एतत् प्राप्तुं नैव शक्नोति ।",
-    "revdelete-modify-no-access": " $2, $1 दिनाङ्कितं परिवर्तने दोषः । एतत् निर्बन्धितमिति अङ्कितम् । एतत् प्राप्तुं नैव शक्नोति ।",
-    "revdelete-modify-missing": "$1 दिनाङ्कितं परिवर्तने दोषः । मूलपाठात् विहीनम् एतत् ।",
-    "revdelete-no-change": "'''पूर्वसूचना ''' $2, $1 दिनाङ्किताः पूर्वमेव दृश्यतासंयोजनम् आभ्यर्थिताः ।",
-    "revdelete-concurrent-change": "$2, $1: दिनाङ्कितदेषपरिमार्जनानि । अस्य स्तरः केनचित् परिवर्तितं यत् भवता परिवर्तितुं प्रयत्नः कृतः । प्रवेशं परिशीलयतु ।",
-    "revdelete-only-restricted": "$2, $1: दिनाङ्कितस्य गोपने दोषाः। अन्यदृश्यविकल्पानां चयनेन विना एतत् निग्रहितुं नैव शक्नोति ।",
-    "revdelete-reason-dropdown": "*परित्यागाय समानकारणाः\n** प्रतिलिपिअधिकारअतिक्रम\n** अयोग्यवैयक्तिकविज्ञप्ति",
-    "revdelete-otherreason": "à¤\85नà¥\8dयतà¥\8d/सà¤\99à¥\8dà¤\95लितं कारणम् :",
+    "deletedhist": "à¤\85पाà¤\95à¥\83तà¤\83 à¤\87तिहासà¤\83",
+    "revdelete-hide-current": "$2 दिनाङ्कस्य $1 समये कस्यापि वस्तोः निगूढनं कार्यं न सफलीभीतम् । एतत् सद्यःकालीन संस्करणमस्ति । एतत् निगूढितुं शक्यते ।",
+    "revdelete-show-no-access": "$2 दिनाङ्कस्य $1 समयस्य वस्तुनि दोषः दृष्टः । तत् वस्तुः निषिद्धावल्याम् अस्ति । भवान्/भवती तस्य परिवर्तनं कर्तुं न शक्नोति ।",
+    "revdelete-modify-no-access": "$2 दिनाङ्कस्य $1 समयस्य परिवर्तितवस्तुनि दोषः दृष्टः । तत् वस्तुः निषिद्धावल्याम् अस्ति । भवान्/भवती तस्य परिवर्तनं कर्तुं न शक्नोति ।",
+    "revdelete-modify-missing": " ID $1 इत्यस्य परिवर्तने दोषः : एतत् दत्तांशे न प्राप्तम् !",
+    "revdelete-no-change": "'''पूर्वसूचना :''' $2, $1 इत्यस्मिन् याचितवस्तूनि पूर्वस्मादेव विद्यन्ते ।",
+    "revdelete-concurrent-change": "$2, $1:",
+    "revdelete-only-restricted": "$2, $1: दिनाङ्कितस्य गोपने दोषाः। अन्यदृश्यविकल्पानां चयनेन विना एतत् निग्रहितुं नैव शक्नोति",
+    "revdelete-reason-dropdown": "* अपाकरणस्य सामान्यकारणानि\n** प्रतिकृत्यधिकारस्य उल्लङ्घनम्\n** अयोग्या टिप्पणी वैयक्तिकमाहिती वा\n** अयोग्यं सभ्यनाम\n** हानिकारकमाहिती",
+    "revdelete-otherreason": "à¤\85परà¤\82/à¤\85तिरिà¤\95à¥\8dतं कारणम् :",
     "revdelete-reasonotherlist": "अन्यानि कारणानि",
     "revdelete-edit-reasonlist": "सम्पादनस्य अपाकरणाय कारणानि",
-    "revdelete-offender": "à¤\85वतरणà¤\95रà¥\8dता à¥¤",
+    "revdelete-offender": "सà¤\82सà¥\8dà¤\95रणà¤\95रà¥\8dता",
     "suppressionlog": "निग्रहनामाभिलेखः ।",
     "suppressionlogtext": "अधोनिदेशितप्रशासकैः सङ्गुप्तस्य विभागस्य निष्कासितपुटानां सूची ।\nनिषिद्धपिहितपुटानि  [[Special:BlockList|block list]] पश्यतु ।",
     "mergehistory": "संलीनपुटेतिहासाः ।",
     "prefs-skin": "त्वक्",
     "skin-preview": "प्राग्दृश्यम्",
     "datedefault": "वरीयांसि नास्ति",
-    "prefs-datetime": "दिनाङ्कः, समयः च",
     "prefs-labs": "प्रयोगशालालक्षणानि ।",
     "prefs-user-pages": "योजकपुटानि ।",
-    "prefs-personal": "यà¥\8bà¤\9cà¤\95à¤\83 à¤µà¥\8dयà¤\95à¥\8dतिरेखा",
-    "prefs-rc": "सद्योजातानि परिवर्तनानि",
-    "prefs-watchlist": "दà¥\83षà¥\8dà¤\9fि सूची",
+    "prefs-personal": "यà¥\8bà¤\9cà¤\95सà¥\8dय à¤°à¥\82परेखा",
+    "prefs-rc": "सद्यो जातानि परिवर्तनानि",
+    "prefs-watchlist": "निरà¥\80à¤\95à¥\8dषासूची",
     "prefs-watchlist-days": "दृष्टि सूची दर्शनार्थे  दिवसानि",
     "prefs-watchlist-days-max": "अधिकतमानि $1 {{PLURAL:$1|दिनानि}}",
     "prefs-watchlist-edits": "विस्तृतावलोकनावल्यां प्रदर्शयितुम् अत्यधिकपरिवर्तनानि ।",
     "prefs-changeemail": "विद्युन्मानपत्रसङ्केतं परिवर्तयतु ।",
     "prefs-setemail": "विद्युन्मानपत्रसङ्केतं योजयतु ।",
     "prefs-email": "इमेल वैकल्पिकाः",
-    "prefs-rendering": "सà¥\8dवरà¥\81पà¤\83",
+    "prefs-rendering": "सà¥\8dवरà¥\82पमà¥\8d",
     "saveprefs": "संरक्ष्यताम्",
     "restoreprefs": "समग्राः व्यवस्थादय व्यवस्थानुसारं पुनः संरक्ष्यताम्",
     "prefs-editing": "सम्पादनम्",
     "prefs-help-email": "ई-पत्रसङ्केतः अनिवार्यः नास्ति । किन्तु कूटशब्दः विस्मर्यते चेत् तस्य परिवर्तनाय आवश्यकः भवति ।",
     "prefs-help-email-others": "योजकपृष्ठ-सम्भाषणपृष्ठयोः माध्यमेन,  ई-पत्रमाध्यमेन वा अन्ये योजकाः भवतः/भवत्याः सम्पर्कं कर्तुं शक्नुयुः ।\nसम्पर्केऽस्मिन् भवतः/भवत्याः ई-पत्रसङ्केतम् अन्ययोजकाः ज्ञातुं न प्रभवतन्ति ।",
     "prefs-help-email-required": "विद्युन्मानपत्रसङ्केतः आवश्यकः ।",
-    "prefs-info": "मूलसूचनाः ।",
+    "prefs-info": "मूलसूचनाः",
     "prefs-i18n": "अन्ताराष्ट्रिकरणम् ।",
     "prefs-signature": "हस्ताक्षर",
     "prefs-dateformat": "दिनाङ्कस्य प्रारूपः",
     "recentchanges-label-minor": "इदं लघु सम्पादनम्",
     "recentchanges-label-bot": "बोट्-द्वारा कृतं सम्पादनमेतत्",
     "recentchanges-label-unpatrolled": "एतावता अस्य सम्पादनस्य परिशीलिनं नाभूत् ।",
+    "recentchanges-legend-heading": "'''विकल्पविषयकम्'''",
     "rcnotefrom": "<strong>$2</strong> तः आरभ्य (<strong>$1</strong> पर्यन्तं) जातानि परिवर्तनानि अधः प्रदर्शितानि ।",
     "rclistfrom": "$1 पश्चात् जातानि नूतनानि परिवर्तनानि दृश्यन्ताम्",
     "rcshowhideminor": "$1 लघुसम्पादनानि",
+    "rcshowhideminor-show": "दर्श्यताम्",
+    "rcshowhideminor-hide": "गोप्यताम्",
     "rcshowhidebots": "$1 बोट् इत्येतानि",
     "rcshowhideliu": "$1 पञ्जीकृताः योजकाः",
     "rcshowhideanons": "अनामकाः योजकाः $1",
     "simpleantispam-label": "अनिष्टसन्देशविरोधपरीक्षणम् ।\nअस्मिन् '''नहि''' पूर्यताम् !",
     "pageinfo-title": "\"$1\" कृते सूचनाः ।",
     "pageinfo-not-current": "क्षम्यताम्, पुरातनाभ्यः आवृत्तिभ्यः एषा सूचना दातुं न शक्यते।",
-    "pageinfo-header-basic": "मूलसूचनाः ।",
+    "pageinfo-header-basic": "मूलसूचनाः",
     "pageinfo-header-edits": "इतिहासः सम्पाद्यताम्",
     "pageinfo-header-restrictions": "पृष्ठसंरक्षणम्",
     "pageinfo-header-properties": "पृष्ठस्य गुणधर्मः",
index a79d3e3..352d10b 100644 (file)
     "permalink": "Куруук баар ыйынньык",
     "print": "Бэчээттээ",
     "view": "Көрүү",
+    "view-foreign": "Манна көрүү: $1",
     "edit": "Уларыт",
+    "edit-local": "Олохтоох ойуулааһынын уларытыы",
     "create": "Саҥаны айыы",
+    "create-local": "Бу туһунан суруйуу",
     "editthispage": "Бу сирэйи уларыт",
     "create-this-page": "Бу сирэйи ай",
     "delete": "Соттор",
     "pool-timeout": "Хааччахтааһыны кэтэһии болдьоҕо ааста",
     "pool-queuefull": "Көрдөбүллэри хомуйуу туолбут",
     "pool-errorunknown": "Биллибэт алҕас",
+    "pool-servererror": "Пул ааҕааччытын сулууспата үлэлээбэт($1).",
     "aboutsite": "{{SITENAME}} туһунан",
     "aboutpage": "Project:туһунан",
     "copyright": "Маны туһанары $1 лиссиэнсийэ көҥүллүүр (атын ыйыллыбытах буоллаҕына).",
     "youhavenewmessages": "$1 ($2) кэллэ",
     "youhavenewmessagesfromusers": "Маны $1 {{PLURAL:$3|соҕотох кыттааччыттан|$3 кыттааччыттан}} туппуккун ($2).",
     "youhavenewmessagesmanyusers": "Маны $1 элбэх кыттааччыттан туппуккун ($2).",
-    "newmessageslinkplural": "{{PLURAL:$1|саҥа этии|саҥа этии}}",
-    "newmessagesdifflinkplural": "тиһэх {{PLURAL:$1|уларытыы|уларытыылар}}",
+    "newmessageslinkplural": "{{PLURAL:$1|саҥа этии|999=саҥа этии}}",
+    "newmessagesdifflinkplural": "тиһэх {{PLURAL:$1|уларытыы|999=уларытыылар}}",
     "youhavenewmessagesmulti": "$1, саҥа суруктар кэллилэр",
     "editsection": "уларыт",
     "editold": "уларыт",
     "invalidtitle-knownnamespace": "«$2» аат далыгар маннык тиэкистээх «$3» сатаммат аат",
     "invalidtitle-unknownnamespace": "Биллибэт аат дала $1 нүөмэрдээх, \"$2\" тиэкистээх сатаммат аат",
     "exception-nologin": "Ааккын билиһиннэрбэтэххин",
-    "exception-nologin-text": "Маны көрөргө эбэтэр оҥорорго ааккын билиһиннэриэхтээххин.",
+    "exception-nologin-text": "Маны көрөргө эбэтэр оҥорорго [[Special:Userlogin|ааккын билиһиннэриэхтээххин]].",
+    "exception-nologin-text-manual": "Көрөргө эбэтэр оҥорорго маны гыныахтааххын: $1.",
     "virus-badscanner": "Сатаммата. Вирус сканера биллибэтэ: ''$1''",
     "virus-scanfailed": "скан сыыһата (куода $1)",
     "virus-unknownscanner": "биллибэт антивирус:",
     "gotaccount": "Бэлиэтэммитиҥ дуо? '''$1'''.",
     "gotaccountlink": "Аатыҥ",
     "userlogin-resetlink": "Киирэр тылгын умнубуккун дуо?",
-    "userlogin-resetpassword-link": "Киирии тылы уларытыы",
+    "userlogin-resetpassword-link": "Киирии тылгын санаттараҕын дуо?",
+    "userlogin-helplink2": "Киирэргэ көмө",
     "userlogin-loggedin": "Маннык аатынан киирбиккин {{GENDER:$1|$1}}.\nАтын аатынан киирэргэ аллара көстөр форманы туһан.",
     "userlogin-createanother": "Атын аатынан бэлиэтэн",
     "createacct-join": "Аллара суруй.",
     "passwordtooshort": "Киирии тылыҥ наһаа кылгас.\nКырата {{PLURAL:$1|1 бэлиэлээх|$1 бэлиэлээх}} буолуохтаах.",
     "password-name-match": "Киирии тыл ааккыттан атын буолуохтаах.",
     "password-login-forbidden": "Маннык ааты уонна киирии тылы туһаныы бобуллар.",
-    "mailmypassword": "Саҥа ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлла Ñ\8bÑ\8bÑ\82Ñ\82аÑ\80",
+    "mailmypassword": "Ð\9aииÑ\80ии Ñ\82Ñ\8bлÑ\8b Ñ\81аҥаÑ\80дÑ\8bÑ\8b",
     "passwordremindertitle": "{{SITENAME}} киирии тылын санатыы",
     "passwordremindertext": "Ким эрэ (бадаҕа эн бу IP-аадырыстан: $1), {{SITENAME}} ($4) киирии тылын саҥаттан ыытыҥ диэбит.\n\"$2\" кыттааччы быстах киирии тыла билигин маннык: \"$3\".\nӨскө маны эн чахчы көрдөөбүт буоллаххына, систиэмэҕэ саҥаттан киирэҥҥин киирии тылгын уларытыаххын сөп.\nБыстах киири тыл {{PLURAL:$5|биир хонук|$5 хонук устата}} үлэлиир.\n\nӨскөтүн киирии тылы саҥаттан көрдөөбөтөх буоллаххына,\nэбэтэр урукку киирии тылгын өйдөөн кэлбит буоллаххына,\nбу сурукка ааххайыма уонна урукку киирии тылгын салгыы туһан.",
     "noemail": "\"$1\" ааттаах киһиэхэ эл. почтата ыйыллыбатах.",
     "throttled-mailpassword": "Киирии тылы өйдөтөр тэрил бүтэһик {{PLURAL:$1|чаас|$1 чаас}} иһигэр туттулла сылдьыбыт.\nКөмүскэнэр соруктан сылтаан киирии тылы {{PLURAL:$1|чааска|$1 чааска}} биирдэ эрэ ыйытыахха сөп.",
     "mailerror": "Сурук ыытарга алҕас таҕыста: $1",
     "acct_creation_throttle_hit": "Эн IP-гыттан бүгүн {{PLURAL:$1|1 аат оҥоһуллубут|$1 аат бэлиэтэммит}} буолан бүгүҥҥү күннээҕи нуорма туолбут.\nБу IP-тан киирэр дьон саҥа ааты билигин бэлиэтиир кыахтара суох.",
-    "emailauthenticated": "Эн Ð¿Ð¾Ñ\87Ñ\82аҥ Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bһа Ð±Ð°Ñ\87Ñ\87аÒ\95а Ð±Ð¸Ð³Ñ\8dÑ\80гÑ\8dÑ\82иллибиÑ\82: $2, $3.",
-    "emailnotauthenticated": "Эл. почтаҥ аадырыһа бигэргэтиллэ илик.\nОнон вики-движок эн почтаҕын кытта үлэлиир кыаҕа суох.",
+    "emailauthenticated": "Эн Ð¿Ð¾Ñ\87Ñ\82аҥ Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bһа Ð±Ð¸Ð³Ñ\8dÑ\80гÑ\8dÑ\82иллибиÑ\82 ÐºÑ\8dмÑ\8d: $2, $3.",
+    "emailnotauthenticated": "Эл. почтаҥ аадырыһа бигэргэтиллэ илик эбит.\nОнон сурук манна ааттаммыт түгэннэргэ ыытыллыа суоҕа.",
     "noemailprefs": "Эл. почтаҥ ыйыллыбатах, онон вики-движок аадырыскын туһанар кыаҕа суох.",
     "emailconfirmlink": "Эл. аадырыскын бигэргэтэргэ",
     "invalidemailaddress": "Киллэрбит аадырыһыҥ эл. почта аадырыһыгар майгыннаабат.\nСөпкө суруй эбэтэр кураанах хааллар.",
     "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|ыр.]]) бэлиэ аат оҥоһулунна.",
     "createaccount-title": "{{SITENAME}} бырайыакка саҥа аат оҥоруу",
     "createaccount-text": "Ким эрэ {{SITENAME}} бырайыакка ($4) саҥа $2 ааты бэлиэтээбит. \"$2\" киирии тыла \"$3\". Билигин киирэн киирии тылгын уларытыаххын наада.\n\nСаҥа аат сыыһа оҥоһуллубут буоллаҕына тугу да гыныа суоххун сөп.",
-    "usernamehasherror": "Аакка эрэһиэккэ бэлиэтин туттар сатаммат",
     "login-throttled": "Ааккын аһара элбэхтик билиһиннэрэ сатаатыҥ.\nБука диэн $1 буолан баран өссө киирэн көрөөр.",
     "login-abort-generic": "Бу аатынан сатаан киирбэтиҥ - быстан хаалла",
     "loginlanguagelabel": "Омугун тыла: $1",
     "suspicious-userlogout": "Сеансы түмүктүүр ыйытыгыҥ ылыныллыбата, тоҕо диэтэххэ браузер эбэтэр кээштыыр прокси алҕас ыыппыт ыйытыктарыгар майгынныыр.",
     "createacct-another-realname-tip": "Дьиҥнээх аатыҥ булгуччута суох.\nЫйдаххына уларыппыт сирэйиҥ устуоруйатыгар көстөр буолуоҕа.",
+    "pt-login": "Киир",
+    "pt-login-button": "Киир",
+    "pt-createaccount": "Бэлиэтэнии",
+    "pt-userlogout": "Тахсыы",
     "php-mail-error-unknown": "mail() PHP-функциятыгар туох эрэ алҕас тахсыбыт",
     "user-mail-no-addy": "Сурук аадырыһа суох ыыттылла сатаабыт",
     "user-mail-no-body": "Кураанах эбэтэр суолтата суох кылгас тиэкистээх суругу ыыта сатаабыт.",
     "changepassword": "Киирии тылы уларытарга",
-    "resetpass_announce": "Ð\91Ñ\83 Ð±Ñ\8bÑ\81Ñ\82аÑ\85 ÐºÑ\8dмҥÑ\8d Ñ\82Ñ\83Ñ\82Ñ\82Ñ\83ллаÑ\80 ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлÑ\8bнан ÐºÐ¸Ð¸Ñ\80диҥ. Ð¢Ò¯Ð¼Ò¯ÐºÐºÑ\8d Ñ\81аҥа ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлла Ñ\81Ñ\83Ñ\80Ñ\83й:",
+    "resetpass_announce": "ТүмүкÑ\82Ò¯Ò¯Ñ\80гÑ\8d Ñ\81аҥа ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлла Ñ\81Ñ\83Ñ\80Ñ\83й.",
     "resetpass_text": "<!-- Тиэкиһи манна эбэн суруйуҥ -->",
     "resetpass_header": "Аат киирии тылын уларытыы",
     "oldpassword": "Эргэ киирии тыл:",
     "retypenew": "Саҥа киирии тылы хатылаа:",
     "resetpass_submit": "Киирии тылы уларыт уонна киир",
     "changepassword-success": "Киирии тылыҥ этэҥҥэ уларыйда!",
+    "changepassword-throttled": "Ааккын аһара элбэхтик билиһиннэрэ сатаатыҥ.\nБука диэн $1 буолан баран өссө киирэн көрөөр.",
     "resetpass_forbidden": "Киирии тылы уларытар сатаммат",
     "resetpass-no-info": "Ааккын билиһиннэрдэххинэ эрэ бу сирэйгэ быһа тиийиэххин сөп.",
     "resetpass-submit-loggedin": "Киирии тылы уларытыы",
     "resetpass-submit-cancel": "Салҕаама",
     "resetpass-wrong-oldpass": "Киирии тыл сөп түбэспэтэ.\nБаҕар уларыппытыҥ буолуо эбэтэр быстах кэмҥэ туттуллар киирии тылы оҥотторбутуҥ буолуо.",
+    "resetpass-recycled": "Бука диэн, билиҥҥи киирии тылтан атыны суруй.",
+    "resetpass-temp-emailed": "Быстах кэмҥэ туттуллар киирии тылынан киирдиҥ.\nТүмүктүүргэ саҥа киирии тылы суруйуохтааххын:",
     "resetpass-temp-password": "Быстах кэмҥэ туттуллар киирии тыл:",
     "resetpass-abort-generic": "Киирии тылы уларытыыны кэҥэтии тохтотто.",
+    "resetpass-expired": "Киирии тылыҥ болдьоҕо ааспыт эбит. Бука диэн, саҥа киирии тылла туруорун.",
     "passwordreset": "Киирии тылы саҥаттан",
     "passwordreset-text-one": "Урукку киирии тылы уларытарга бу форманы толор.",
     "passwordreset-text-many": "{{PLURAL:$1|Киирии тылы уларытарга түннүктэртэн биирдэстэрин толор.}}",
     "prefs-skin": "Тас көстүү",
     "skin-preview": "Хайдах буолара",
     "datedefault": "Көннөрү көстүүтэ",
-    "prefs-datetime": "Күнэ-дьыла уонна кэмэ",
     "prefs-labs": "Тургутуллар туруоруулар",
     "prefs-user-pages": "Кыттааччы сирэйдэрэ",
     "prefs-personal": "Кыттааччы туруоруулара",
     "upload-permitted": "Көҥүллэммит билэ көрүҥнэрэ: $1.",
     "upload-preferred": "Маннык билэ көрүҥнэрин туһанар ордук: $1.",
     "upload-prohibited": "Маннык билэ көрүҥнэрэ бобуллубуттар: $1.",
-    "uploadlog": "уларытыы устуоруйата",
     "uploadlogpage": "Уларытыы устуоруйата",
     "uploadlogpagetext": "Манна бүтэһик уларытыылар тиһиктэрэ көстөр.\nӨссө [[Special:NewFiles|саҥа билэлэр]] тиһиктэрин көрүөххүн сөп.",
     "filename": "Билэ аата",
     "filereuploadsummary": "Билэ уларыйыылара:",
     "filestatus": "Туһаныы (Copyright):",
     "filesource": "Хантан ылыллыбыта:",
-    "uploadedfiles": "Киллэриллибит билэлэр",
     "ignorewarning": "Сэрэтиилэри истибэккэ билэни киллэр",
     "ignorewarnings": "Сэрэтиини истимэ",
     "minlength1": "Билэ аата биир суругунан буолуохтаах.",
     "overwroteimage": "\"[[$1]]\" киллэриллибит саҥа торума",
     "uploaddisabled": "Суруттарыы бобуллубут",
     "copyuploaddisabled": "URL көмөтүнэн хачайдыыр кыах араарыллыбыт.",
-    "uploadfromurl-queued": "Эн хачайдааһыныҥ уочаркка туруорулунна.",
     "uploaddisabledtext": "Билэлэри суруттарар көҥүллэммэт.",
     "php-uploaddisabledtext": "PHP туруорууларыгар билэни киллэрии араарыллыбыт. Бука диэн, file_uploads туруоруутун көр.",
     "uploadscripted": "Бу билэ HTML эбэтэр скрипт куодтаах эбит. Интэриниэт көрдөрөр бырагыраамма ону сыыһа ааҕыан сөп.",
     "upload-misc-error": "Сурутуу биллибэт моһоллонно",
     "upload-misc-error-text": "Сурутуу биллибэт моһоллонно.\nАадырыһы сөпкө суруйбуккун көр уонна өссө биирдэ боруобалаа.\nБу хатыланнаҕына [[Special:ListUsers/sysop|администраатары]] кытта сибээстэс.",
     "upload-too-many-redirects": "URL наһаа элбэх утаарыылаах",
-    "upload-unknown-size": "Биллибэт кээмэй",
     "upload-http-error": "HTTP алҕаһа таҕыста: $1",
     "upload-copy-upload-invalid-domain": "Бу домеҥҥа хачайдааһыны хатылыыр табыллыбат.",
     "backend-fail-stream": "$1 билэни ыытар табыллыбата.",
     "img-auth-streaming": "Ботуогунан биэрии «$1».",
     "img-auth-public": "img_auth.php аналынан билэлэри сабыылаах биикиттэн таһаарыы буолар.\nБу биики аһаҕас.\nОнон img_auth.php араарыллыбыт.",
     "img-auth-noread": "Кыттааччы «$1» ааҕарга көҥүлэ суох.",
-    "img-auth-bad-query-string": "URL алҕастаах",
     "http-invalid-url": "Алҕастаах URL: $1",
     "http-invalid-scheme": "Маннык схемалаах аадырыстар өйөммөттөр \"$1\"",
     "http-request-error": "HTTP-көрдөбүл биллибэт алҕастаан сылтаан ылыныллыбата.",
     "filehist-dimensions": "Кээмэйдэрэ",
     "filehist-filesize": "Билэ кээмэйэ",
     "filehist-comment": "Хос быһаарыы",
-    "filehist-missing": "Билэ суох",
     "imagelinks": "Билэни туттуу",
     "linkstoimage": "Бу билэҕэ маннык атын {{PLURAL:$1|сирэй сигэнэр|$1 сирэйдэр сигэнэллэр}}:",
     "linkstoimage-more": "$1 {{PLURAL:$1|сирэйтэн|сирэйтэн}} элбэх сирэй бу билэҕэ сигэнэр.\nОнтон бу тиһиккэ {{PLURAL:$1|$1 эрэ сигэ көһүннэ|$1 сигэ эрэ көһүннэ}}.\nӨссө [[Special:WhatLinksHere/$2|толору тиһиги]] көрүөххүн сөп.",
     "emailuser-title-notarget": "Кыттааччыга e-mail сурук ыытыы",
     "emailpage": "Кыттааччыга E-mail ыыт",
     "emailpagetext": "Бу фуорма көмөтүнэн {{GENDER:$1|кыттааччыга}} сурук ыытыаххын сөп.\n\"Кимтэн\" диэҥҥэ эн [[Special:Preferences|туруорууларгар]] баар аадырыһыҥ киириэҕэ,\nонон суругу туппут киһи ол аадырыскар чопчу хардарар кыахтаныа.",
-    "usermailererror": "Сурук кыайан барбата:",
     "defemailsubject": "{{SITENAME}} — $1 диэн киһиттэн сурук кэлбит",
     "usermaildisabled": "Кыттааччы эл почтата арахса сылдьар",
     "usermaildisabledtext": "Эн атын кыттааччыларга эл. почтанан сурук ыытар кыаҕыҥ суох эбит",
     "noemailtitle": "E-mail суох",
     "noemailtext": "Бу кыттааччы e-mail аадырыһын эппэтэх.",
-    "nowikiemailtitle": "Сурук ыытар кыах суох",
     "nowikiemailtext": "Бу кыттааччы сурук тутуон баҕарбат.",
     "emailnotarget": "Суруйбут кыттааччыҥ суох эбэтэр аата алҕастаах.",
     "emailtarget": "Суруйар киһиҥ аатын киллэр",
     "watching": "Кэтээ...",
     "unwatching": "Кэтээмэ...",
     "watcherrortext": "Кэтээн көрүү тиһигин уларытыы кэмигэр алҕас таҕыста (\"$1\" сирэйгэ сыһыаннаах).",
-    "enotif_mailer": "{{SITENAME}} Биллэрэр Сулууспата",
     "enotif_reset": "Бары сирэйдэри көрбүтүм курдук бэлиэтээ",
     "enotif_impersonal_salutation": "{{SITENAME}} кыттааччыта",
     "enotif_subject_deleted": "«{{SITENAME}}» бырайыак «$1» ааттаах сирэйин бу {{gender:$2|кыттааччы|кыттааччы}} соппут - $2",
     "excontent": "иһинээҕитэ: '$1'",
     "excontentauthor": "иһинээҕитэ: «$1» (соҕотох ааптар [[Special:Contributions/$2|$2]])",
     "exbeforeblank": "иһинээҕитэ сотуллуон иннинэ: '$1'",
-    "exblank": "сирэй кураанах этэ",
     "delete-confirm": "Маны \"$1\" соторго",
     "delete-legend": "Сотуу",
     "historywarning": "'''Сэрэтии''': Сотоору турар сирэйиҥ көрүллүбүт $1 {{PLURAL:$1|соҕотох барыллаах|барыллаах}} устуоруйалаах:",
     "importunknownsource": "Импортанар сирэй биллибэт көрүҥнээх",
     "importcantopen": "Импортанар билэ кыайан арыллыбат",
     "importbadinterwiki": "Интервики ыйынньык сыыһа",
-    "importnotext": "Тиэкис суох",
     "importsuccess": "Импортааһын түмүктэннэ!",
-    "importhistoryconflict": "Баар торумнар сөпсөспөтүлэр (баҕар сирэй номнуо импортаммыт буолуон сөп)",
     "importnosources": "Биики ыккрадынааҕы импортанар билэ талыллыбатах, уларытыы историятын көһөрүү арахса сылдьар.",
     "importnofile": "Импортанар билэ сатаан киллэриллибэтэ.",
     "importuploaderrorsize": "Файл ыйааhына наhаа улахан буолан хачайдааhын тохтотулунна.",
index 606ab5e..8554226 100644 (file)
     "prefs-skin": "Huil",
     "skin-preview": "First Leuk",
     "datedefault": "Nae preference",
-    "prefs-datetime": "Date n time",
     "prefs-labs": "Labs featurs",
     "prefs-user-pages": "Uiser pages",
     "prefs-personal": "Uiser data",
index 99ad4fc..4bddc6a 100644 (file)
@@ -5,7 +5,8 @@
             "Cornelia",
             "Felis",
             "Jun Misugi",
-            "Kaganer"
+            "Kaganer",
+            "Midnight Gambler"
         ]
     },
     "tog-underline": "Sotturìnia li cullegamenti:",
     "tog-extendwatchlist": "Musthra tutti li mudìfigghi a li abbaidaddi ippiziari, nò soru l'ulthimi.",
     "tog-usenewrc": "Utirizza l'ulthimi mudìfigghi abanzaddi (dumanda JavaScript)",
     "tog-numberheadings": "Numarazioni otomàtigga di li tìturi di sezzioni",
-    "tog-showtoolbar": "Musthra barra di l'isthrumenti di mudìfigga (dumanda JavaScript)",
-    "tog-editondblclick": "Mudìfigga di li pàgini attrabessu dóppiu clic (dumanda JavaScript)",
-    "tog-editsectiononrightclick": "Mudìfigga di li sezzioni attrabessu lu clic dresthu i' lu tìturu (nezzessàriu JavaScript)",
-    "tog-rememberpassword": "Ammenta la paràura d'órdhini (nezzessàriu azzittà li cookie) (for a maximum of $1 {{PLURAL:$1|dì|dì}})",
+    "tog-showtoolbar": "Musthra barra di l'isthrumenti di mudìfigga",
+    "tog-editondblclick": "Mudìfigga di li pàgini attrabessu dóppiu clic",
+    "tog-editsectiononrightclick": "Mudìfigga di li sezzioni attrabessu lu clic dresthu i' lu tìturu",
+    "tog-rememberpassword": "Ammenta la paràura d'órdhini (for a maximum of $1 {{PLURAL:$1|dì|dì}})",
     "tog-watchcreations": "Aggiungi li pàgini criaddi a l'abbaidaddi ippiziari",
     "tog-watchdefault": "Aggiungi li pàgini mudìfiggaddi a l'abbaidaddi ippiziari",
     "tog-watchmoves": "Aggiungi li pàgini ippusthaddi a l'abbaidaddi ippiziari",
     "newwindow": "(s'abbri in d'unu nobu balchoni)",
     "cancel": "Annullà",
     "moredotdotdot": "Althru...",
-    "mypage": "La mea pàgina",
+    "mypage": "Pàgina",
     "mytalk": "Li me' dischussioni",
     "anontalk": "Dischussioni pa chisthu IP",
     "navigation": "Nabiggazioni",
     "createaccount-title": "Criazioni di un'intradda a {{SITENAME}}",
     "createaccount-text": "Calchunu à criaddu una registhrazioni a {{SITENAME}} ($4) pa contu di \"$2\", cun la paràura d'órdhini \"$3\".\nÈ opporthunu eseguì un'intradda cantu primma e ciamballa immediatamenti.\n\nSi la registhrazioni è isthadda criadda pa un'errori, pói ignorà chisth'imbasciadda.",
     "loginlanguagelabel": "Linga: $1",
+    "pt-login": "Intra",
+    "pt-login-button": "Intra",
+    "pt-userlogout": "Iscidda",
     "changepassword": "Ciamba paràura d'órdhini",
     "resetpass_announce": "L'intradda è isthadda effettuadda cun un còdizi timpuràniu, inviaddu via postha erettrònica.\n\nPa cumprità la registhrazioni è nezzessàriu impusthà una noba paràura d'órdhini inogghi:",
     "resetpass_text": "<!-- Aggiungi lu testhu inogghi -->",
     "resetpass_submit": "Impustha la paràura d'órdhini e intra",
     "changepassword-success": "La paràura d'órdhini tóia è isthadda mudìfiggadda. Abà sei intrendi...",
     "resetpass_forbidden": "No è pussìbiri mudifiggà li paràuri d'órdhini in {{SITENAME}}.",
+    "passwordreset-username": "Innòmu utenti:",
+    "resettokens-tokens": "Token:",
     "bold_sample": "Grassetu",
     "bold_tip": "Grassetu",
     "italic_sample": "Cursibu",
     "prefs-skin": "Aipettu gràficu",
     "skin-preview": "antiprimma",
     "datedefault": "Nisciuna prifirènzia",
-    "prefs-datetime": "Data e ora",
     "prefs-personal": "Profiru utenti",
     "prefs-rc": "Ulthimi mudìfigghi",
     "prefs-watchlist": "Abbaidaddi ippiziari",
     "upload-permitted": "Fuimmaddi di file autorizaddi: $1.",
     "upload-preferred": "Fuimmaddi di file prifiriddi: $1.",
     "upload-prohibited": "Fuimmaddi di file pruibbiddi: $1.",
-    "uploadlog": "File carriggaddi",
     "uploadlogpage": "Rigisthru di li file carriggaddi",
     "uploadlogpagetext": "Inogghi v'è l'erencu di l'ulthimi file cariggaddi.",
     "filename": "Innòmu di lu file",
     "fileuploadsummary": "Dettàgli di lu file:",
     "filestatus": "Infuimmazioni i' lu copyright:",
     "filesource": "Orìgini:",
-    "uploadedfiles": "Erencu di li file carriggaddi",
     "ignorewarning": "Ignora l'avvirthimentu e saivva cumenti si sia lu file",
     "ignorewarnings": "Ignora li imbasciaddi di avvirthimentu di lu sisthema",
     "minlength1": "Lu nommu di lu file débi assé cumposthu arumandu d'un caràtteri.",
     "emailuser": "Ischribì a l'utenti",
     "emailpage": "Invia un'imbasciadda di postha erettrònica a l'utenti",
     "emailpagetext": "Si l'utenti à registhraddu un'indirizzu di postha erettrònica vàriddu i' li propri prifirenzi, lu mòdulu in giossu cunsenti d'ischribelli una sora imbasciadda. L'indirizzu indicaddu i' li prifirenzi di lu mandanti apparirà i' lu campu \"Da:\" di l'imbasciadda pa cunsintì a  lu disthinatàriu l'eventuari rippostha.",
-    "usermailererror": "L'oggettu di l'imbasciadda à turraddu l'errori:",
     "defemailsubject": "Imbasciadda da {{SITENAME}}",
     "noemailtitle": "Nisciun indirizzu di postha erettrònica",
     "noemailtext": "Chistu utenti nò à indicaddu un'indirizzu postha erettrònica vàriddu, oppuru à sciubaraddu di nò rizzibì imbasciaddi di postha erettrònica da l'althri utenti.",
     "watchlist-options": "Opzioni abbaidaddi ippiziari",
     "watching": "Aggiunta a l'abbaidaddi ippiziari...",
     "unwatching": "Eliminazioni da l'abbaidaddi ippiziari...",
-    "enotif_mailer": "Sisthema di nutìfica via postha erettrònica di {{SITENAME}}",
     "enotif_reset": "Signa tutti li pàgini cumenti già visitaddi",
     "enotif_impersonal_salutation": "Utenti di {{SITENAME}}",
     "enotif_lastvisited": "Cunsultha $1 pa vidé tutti li mudìfigghi da l'ulthima visita tóia.",
     "excontent": "lu cuntinuddu era : '$1'",
     "excontentauthor": "lu cuntinuddu era: '$1' (e lu soru cuntributori era '[[Special:Contributions/$2|$2]]')",
     "exbeforeblank": "Lu cuntinuddu primma di l'ibbiuddamentu era: '$1'",
-    "exblank": "la pàgina era biodda",
     "delete-confirm": "Canzella \"$1\"",
     "delete-legend": "Canzella",
     "historywarning": "Attinzioni: La pàgina chi sei canzellendi à una cronologia:",
     "importunknownsource": "Tipu d'orìgini ischunisciddu pa l'impurthazioni",
     "importcantopen": "Impussìbiri abbrì lu file d'impurthazioni",
     "importbadinterwiki": "Cullegamentu interwiki ibbagliaddu",
-    "importnotext": "Testhu bioddu o mancanti",
     "importsuccess": "Impurthazioni finidda!",
-    "importhistoryconflict": "La cronologia cunteni di li versioni in cuntrasthu (chistha pàgina pudia assé già isthadda impurthadda)",
     "importnosources": "Nò è isthadda difinidda un'origini pa l'impurthazioni transwiki; l'impurthazioni diretta di la cronologia nò è attiba.",
     "importnofile": "Nò è isthaddu cariggaddu nisciun file pa l'impurthazioni.",
     "importuploaderrorsize": "Carriggamentu di file pa l'impurthazioni nò ridisciddu. Lu file supara li misuri massimi cunsintiddi pa lu carriggamentu.",
index 117080e..81a5330 100644 (file)
     "prefs-skin": "Izgled (skin)",
     "skin-preview": "Pretpregled",
     "datedefault": "Bez preferenci",
-    "prefs-datetime": "Datum i vrijeme",
     "prefs-labs": "Eksperimentalne mogućnosti",
     "prefs-user-pages": "Korisničke stranice",
     "prefs-personal": "Korisnički profil",
index a5b45ba..d12f3a5 100644 (file)
     "permalink": "Trvalý odkaz",
     "print": "Tlač",
     "view": "Zobraziť",
+    "view-foreign": "Prehliadnuť na {{GRAMMAR:lokál|$1}}",
     "edit": "upraviť",
+    "edit-local": "Upraviť miestny popis",
     "create": "Vytvoriť",
+    "create-local": "Pridať miestny popis",
     "editthispage": "Upraviť túto stránku",
     "create-this-page": "Vytvoriť túto stránku",
     "delete": "Vymazať",
     "pool-timeout": "Bol prekročený vyhradený čas čakania na zámok",
     "pool-queuefull": "Front je plný",
     "pool-errorunknown": "Neznáma chyba",
+    "pool-servererror": "Služba riadiaca prístup k serverom nieje dostupná ($1).",
     "aboutsite": "O {{GRAMMAR:lokál|{{SITENAME}}}}",
     "aboutpage": "Project:Úvod",
     "copyright": "Obsah je dostupný pod $1, pokiaľ nie je uvedené inak.",
     "invalidtitle-unknownnamespace": "Neplatný názov s neznámym číslom menného priestoru „$1“ a textom „$2“",
     "exception-nologin": "Nie ste prihlásený",
     "exception-nologin-text": "Táto stránka alebo operácia vyžaduje, aby ste [[Special:Userlogin|boli prihlásený]].",
+    "exception-nologin-text-manual": "Pre prístup na túto stránku alebo k tejto akcii sa musíte $1.",
     "virus-badscanner": "Chybná konfigurácia: neznámy antivírus: ''$1''",
     "virus-scanfailed": "kontrola zlyhala (kód $1)",
     "virus-unknownscanner": "neznámy antivírus:",
     "gotaccountlink": "Prihlásiť",
     "userlogin-resetlink": "Zabudli ste svoje prihlasovacie údaje?",
     "userlogin-resetpassword-link": "Zabudli ste heslo?",
+    "userlogin-helplink2": "Pomoc s prihlásením",
     "userlogin-loggedin": "Ste už {{GENDER:$1|prihĺasený|prihlásená}} ako $1.\nPomocou formulára nižšie sa môžete prihlásiť ako iný redaktor.",
     "userlogin-createanother": "Vytvoriť ďalší účet",
     "createacct-join": "Vyplňte svoje údaje.",
     "resetpass-submit-cancel": "Zrušiť",
     "resetpass-wrong-oldpass": "Neplatné dočasné alebo aktuálne heslo.\nJe možné, že sa vám už podarilo úspešne zmeniť svoje heslo alebo ste si vyžiadali nové dočasné heslo.",
     "resetpass-recycled": "Ako nové heslo si prosím nastavte niečo iné než súčasné heslo.",
+    "resetpass-temp-emailed": "Prihlasujete sa dočasným heslom, zaslaným e-mailom. Aby ste dokončili prihlásenie, nastavte si tu nové heslo:",
     "resetpass-temp-password": "Dočasné heslo:",
     "resetpass-abort-generic": "Zmena hesla bola zablokovaná rozšírením.",
+    "resetpass-expired": "Platnosť vášho hesla vypršala. Pre prihlásenie si nastavte nové heslo.",
     "passwordreset": "Reset hesla",
     "passwordreset-text-one": "Pre získanie nového hesla vyplňte tento formulár.",
     "passwordreset-text-many": "{{PLURAL:$1|Pre získanie nového hesla zadajte jeden z údajov.}}",
     "prefs-skin": "Vzhľad",
     "skin-preview": "Náhľad",
     "datedefault": "štandardný",
-    "prefs-datetime": "Dátum a čas",
     "prefs-labs": "Laboratórne funkcie",
     "prefs-user-pages": "Stránky používateľa",
     "prefs-personal": "Profil",
     "listgrouprights-removegroup-self": "Z vlastného účtu je možné odstrániť {{PLURAL:$2|skupinu|skupiny}}: $1",
     "listgrouprights-addgroup-self-all": "Do vlastného účtu je možné pridať všetky skupiny",
     "listgrouprights-removegroup-self-all": "Z vlastného účtu je možné odstrániť všetky skupiny",
+    "trackingcategories-msg": "Sledovacia kategória",
+    "trackingcategories-name": "Názov správy",
+    "trackingcategories-desc": "Kritériá pre zaradenie do kategórie",
+    "trackingcategories-nodesc": "Popis nie je k dispozícii.",
+    "trackingcategories-disabled": "Kategória je vypnutá",
     "mailnologin": "Žiadna adresa na zaslanie",
     "mailnologintext": "Musíte byť [[Special:UserLogin|prihlásený]] a mať platnú e-mailovú adresu vo vašich [[Special:Preferences|nastaveniach]], aby ste mohli iným používateľom posielať e-maily.",
     "emailuser": "E-mail tomuto používateľovi",
index a3334fe..1bcb3a9 100644 (file)
     "prefs-skin": "Koža",
     "skin-preview": "Predogled",
     "datedefault": "Kakor koli",
-    "prefs-datetime": "Datum in čas",
     "prefs-labs": "Funkcije laboratorija",
     "prefs-user-pages": "Uporabniške strani",
     "prefs-personal": "Podatki o uporabniku",
     "unwatchthispage": "Prenehaj opazovati stran",
     "notanarticle": "Ni članek",
     "notvisiblerev": "Redakcija je bila izbrisana",
-    "watchlist-details": "Spremljate $1 {{PLURAL:$1|stran|strani|strani|strani|strani}} (pogovorne strani niso vštete).",
+    "watchlist-details": "Na vašem spisku nadzorov je $1 {{PLURAL:$1|stran|strani|strani}}; pogovorne strani niso štete posebej.",
     "wlheader-enotif": "Obveščanje po elektronski pošti je omogočeno.",
     "wlheader-showupdated": "Strani, spremenjene od vašega zadnjega ogleda, so prikazane '''krepko'''.",
     "watchmethod-recent": "med nedavnimi urejanji iščem spremljane strani",
     "contributions-title": "Prispevki uporabnika $1",
     "mycontris": "Prispevki",
     "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
+    "contributions-userdoesnotexist": "Uporabniški račun »$1« ni registriran.",
     "nocontribs": "Ne najdem nobene merilom ustrezajoče spremembe.",
     "uctop": "(trenutno)",
     "month": "Od meseca (in prej):",
index 4a3c676..38662bc 100644 (file)
     "powersearch-togglenone": "ништа",
     "search-external": "Спољна претрага",
     "searchdisabled": "Претрага је онемогућена.\nУ међувремену можете тражити преко Гугла.\nУпамтите да његови пописи овог викија могу бити застарели.",
+    "search-error": "Дошло је до грешке приликом претраге: $1",
     "preferences": "Подешавања",
     "mypreferences": "Подешавања",
     "prefs-edits": "Број измена:",
     "prefs-skin": "Тема",
     "skin-preview": "Прегледај",
     "datedefault": "Свеједно",
-    "prefs-datetime": "Датум и време",
     "prefs-labs": "Пробне могућности",
     "prefs-user-pages": "Корисничке странице",
     "prefs-personal": "Профил",
     "prefs-watchlist-days-max": "Највише $1 {{PLURAL:$1|дан|дана|дана}}",
     "prefs-watchlist-edits": "Највећи број измена у проширеном списку надгледања:",
     "prefs-watchlist-edits-max": "Највећа вредност је хиљаду",
-    "prefs-watchlist-token": "Ð\96еÑ\82он списка надгледања:",
+    "prefs-watchlist-token": "Токен списка надгледања:",
     "prefs-misc": "Друга подешавања",
     "prefs-resetpass": "Промени лозинку",
     "prefs-changeemail": "Промени е-адресу",
     "recentchangesdays-max": "(највише $1 {{PLURAL:$1|дан|дана|дана}})",
     "recentchangescount": "Број измена за приказ:",
     "prefs-help-recentchangescount": "Подразумева скорашње измене, историје страница и дневнике.",
+    "prefs-help-watchlist-token2": "Ово је тајни кључ за RSS довод вашег списка надгледања.\nСвако ко зна овај кључ биће у могућности да види ваша надгледања стога немојте га одавати никоме.\nАко је потребно можете га [[Special:ResetTokens|ресетовати]].",
     "savedprefs": "Ваша подешавања су сачувана.",
     "timezonelegend": "Временска зона:",
     "localtime": "Локално време:",
     "right-deleterevision": "брисање и враћање одређених измена страница",
     "right-deletedhistory": "прегледање обрисаних ставки историје без повезаног текста",
     "right-deletedtext": "прегледање обрисаног текста и измена између обрисаних измена",
-    "right-browsearchive": "тражење обрисаних страница",
+    "right-browsearchive": "претрага обрисаних страница",
     "right-undelete": "враћање обрисаних страница",
     "right-suppressrevision": "прегледање и враћање измена које су сакривене од стране администратора",
     "right-suppressionlog": "гледање приватних дневника",
     "right-block": "блокирање даљих измена других корисника",
     "right-blockemail": "онемогућавање корисницима да шаљу е-поруке",
     "right-hideuser": "блокирање корисничког имена и његово сакривање од јавности",
-    "right-ipblock-exempt": "заобилажење блокирања IP адресе, самоблокирања и блокирања опсега",
+    "right-ipblock-exempt": "заобилажење блокирања IP адресе, аутоматска блокирања и блокирања опсега",
     "right-proxyunbannable": "заобилажење самоблокирања посредника",
     "right-unblockself": "одблокирај самог себе",
     "right-protect": "промени нивое заштите и уреди странице са преносивом заштитом",
-    "right-editprotected": "уреди странице под заштитом „{{int:protect-level-sysop}}“",
-    "right-editsemiprotected": "уреди странице под заштитом „{{int:protect-level-autoconfirmed}}“",
+    "right-editprotected": "уређивање страница под заштитом „{{int:protect-level-sysop}}“",
+    "right-editsemiprotected": "уређивање страница под заштитом „{{int:protect-level-autoconfirmed}}“",
     "right-editinterface": "уређивање корисничког окружења",
     "right-editusercssjs": "уређивање туђих CSS и јаваскрипт датотека",
     "right-editusercss": "уређивање туђих CSS датотека",
-    "right-edituserjs": "уређивање туђих јаваскрипт датотека",
+    "right-edituserjs": "уређивање туђих JavaScript датотека",
+    "right-editmyusercss": "уређивање сопствених CSS датотека",
+    "right-editmyuserjs": "уређивање сопствених JavaScript датотека",
     "right-viewmyprivateinfo": "видите своје личне податке (нпр. адресу е-поште, право име)",
-    "right-editmyprivateinfo": "уреди своје личне податке (нпр. адресу е-поште, право име)",
+    "right-editmyprivateinfo": "уређивање сопствених личних података (нпр. адресу е-поште, право име)",
     "right-editmyoptions": "уредите своја подешавања",
     "right-rollback": "брзо враћање измена последњег корисника који је мењао одређену страницу",
     "right-markbotedits": "означавање враћених измена као измене бота",
     "right-noratelimit": "отпорност на ограничења",
     "right-import": "увожење страница из других викија",
     "right-importupload": "увожење страница из отпремљене датотеке",
-    "right-patrol": "ознаÑ\87аваÑ\9aе Ñ\82Ñ\83Ñ\92иÑ\85 Ð¸Ð·Ð¼ÐµÐ½Ð° ÐºÐ°Ð¾ Ð¿Ñ\80егледаниÑ\85",
-    "right-autopatrol": "самоозначавање измена као прегледане",
+    "right-patrol": "ознаÑ\87аваÑ\9aе Ñ\82Ñ\83Ñ\92иÑ\85 Ð¸Ð·Ð¼ÐµÐ½Ð° Ð¿Ð°Ñ\82Ñ\80олиÑ\80аним",
+    "right-autopatrol": "аутоматско означавање измена као прегледаним",
     "right-patrolmarks": "прегледање ознака за патролирање унутар скорашњих измена",
     "right-unwatchedpages": "прегледање списка ненадгледаних страница",
     "right-mergehistory": "спајање историја страница",
     "download": "преузми",
     "unwatchedpages": "Ненадгледане странице",
     "listredirects": "Списак преусмерења",
+    "listduplicatedfiles": "Списак дупликата датотека",
+    "listduplicatedfiles-summary": "Ово је списак датотека које су дупликат неких других датотека. Само локалне датотеке су приказане.",
     "unusedtemplates": "Некоришћени шаблони",
     "unusedtemplatestext": "Ова страница наводи све странице у именском простору {{ns:template}} које нису укључене ни на једној другој страници.\nПре брисања проверите да ли друге странице воде до тих шаблона.",
     "unusedtemplateswlh": "остале везе",
index dc9c254..68f120d 100644 (file)
     "prefs-skin": "Tema",
     "skin-preview": "Pregledaj",
     "datedefault": "Svejedno",
-    "prefs-datetime": "Datum i vreme",
     "prefs-labs": "Probne mogućnosti",
     "prefs-user-pages": "Korisničke stranice",
     "prefs-personal": "Profil",
     "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-token": "Žeton spiska nadgledanja:",
+    "prefs-watchlist-token": "Token spiska nadgledanja:",
     "prefs-misc": "Druga podešavanja",
     "prefs-resetpass": "Promeni lozinku",
     "prefs-changeemail": "Promeni e-adresu",
     "right-deleterevision": "brisanje i vraćanje određenih izmena stranica",
     "right-deletedhistory": "pregledanje obrisanih stavki istorije bez povezanog teksta",
     "right-deletedtext": "pregledanje obrisanog teksta i izmena između obrisanih izmena",
-    "right-browsearchive": "traženje obrisanih stranica",
+    "right-browsearchive": "pretraga obrisanih stranica",
     "right-undelete": "vraćanje obrisanih stranica",
     "right-suppressrevision": "pregledanje i vraćanje izmena koje su sakrivene od strane administratora",
     "right-suppressionlog": "gledanje privatnih dnevnika",
     "right-block": "blokiranje daljih izmena drugih korisnika",
     "right-blockemail": "onemogućavanje korisnicima da šalju e-poruke",
     "right-hideuser": "blokiranje korisničkog imena i njegovo sakrivanje od javnosti",
-    "right-ipblock-exempt": "zaobilaženje blokiranja IP adrese, samoblokiranja i blokiranja opsega",
+    "right-ipblock-exempt": "zaobilaženje blokiranja IP adrese, automatska blokiranja i blokiranja opsega",
     "right-proxyunbannable": "zaobilaženje samoblokiranja posrednika",
     "right-unblockself": "odblokiraj samog sebe",
     "right-protect": "promeni nivoe zaštite i uredi stranice sa prenosivom zaštitom",
-    "right-editprotected": "uredi stranice pod zaštitom „{{int:protect-level-sysop}}“",
-    "right-editsemiprotected": "uredi stranice pod zaštitom „{{int:protect-level-autoconfirmed}}“",
+    "right-editprotected": "uređivanje stranice pod zaštitom „{{int:protect-level-sysop}}“",
+    "right-editsemiprotected": "uređivanje stranica pod zaštitom „{{int:protect-level-autoconfirmed}}“",
     "right-editinterface": "uređivanje korisničkog sučelja",
     "right-editusercssjs": "uređivanje tuđih CSS i javaskript datoteka",
     "right-editusercss": "uređivanje tuđih CSS datoteka",
-    "right-edituserjs": "uređivanje tuđih javaskript datoteka",
+    "right-edituserjs": "uređivanje tuđih JavaScript datoteka",
+    "right-editmyuserjs": "uređivanje sopstvenih JavaScript datoteka",
     "right-viewmyprivateinfo": "vidite svoje lične podatke (npr. adresu e-pošte, pravo ime)",
-    "right-editmyprivateinfo": "uredi svoje lične podatke (npr. adresu e-pošte, pravo ime)",
+    "right-editmyprivateinfo": "uređivanje sopstvenih ličnih podataka (npr. adresu e-pošte, pravo ime)",
     "right-editmyoptions": "uredite svoja 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-noratelimit": "otpornost na ograničenja",
     "right-import": "uvoženje stranica iz drugih vikija",
     "right-importupload": "uvoženje stranica iz otpremljene datoteke",
-    "right-patrol": "označavanje tuđih izmena kao pregledanih",
-    "right-autopatrol": "samooznačavanje izmena kao pregledane",
+    "right-patrol": "označavanje tuđih izmena patroliranim",
+    "right-autopatrol": "automatsko označavanje izmena kao pregledanim",
     "right-patrolmarks": "pregledanje oznaka za patroliranje unutar skorašnjih izmena",
     "right-unwatchedpages": "pregledanje spiska nenadgledanih stranica",
     "right-mergehistory": "spajanje istorija stranica",
index ce1f8dd..561418b 100644 (file)
     "prefs-skin": "Utseende",
     "skin-preview": "Förhandsvisning",
     "datedefault": "Ovidkommande",
-    "prefs-datetime": "Datum och tid",
     "prefs-labs": "Testfunktioner",
     "prefs-user-pages": "Användarsidor",
     "prefs-personal": "Mitt konto",
     "unwatchthispage": "Sluta bevaka",
     "notanarticle": "Inte en artikel",
     "notvisiblerev": "Sidversionen har raderats",
-    "watchlist-details": "Du har $1 {{PLURAL:$1|sida|sidor}} på din bevakningslista (diskussionssidor är inte medräknade).",
+    "watchlist-details": "Du har {{PLURAL:$1|en sida|$1 sidor}} på din bevakningslista (diskussionssidor är inte separat medräknade).",
     "wlheader-enotif": "E-postmeddelanden är aktiverade.",
     "wlheader-showupdated": "Sidor som har ändrats sedan ditt senaste besök visas i '''fetstil.'''",
     "watchmethod-recent": "letar efter bevakade sidor bland senaste ändringar",
index 8bc961e..b37df48 100644 (file)
@@ -31,7 +31,8 @@
             "கௌசிக் பிரபு",
             "செல்வா",
             "மதனாஹரன்",
-            "බිඟුවා"
+            "බිඟුවා",
+            "Thamiziniyan"
         ]
     },
     "tog-underline": "இணைப்புகளுக்கு அடிக்கோடிடு",
     "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) என்ற பெயரில் பயனர் கணக்கு உருவாக்கப்பட்டது.",
     "createaccount-title": "{{SITENAME}} தளத்துக்கான கணக்கு தொடக்கம்",
     "createaccount-text": "யாரோ ஒருவர் உங்கள் மின்னஞ்சல் முவரிக்காக {{SITENAME}} ($4) தளத்தில் கணக்கொண்றை தொடங்கியுள்ளார். கணக்கின் பெயர் \"$2\", கடவுச்சொல் \"$3\". நீங்கள் இப்போது புகுபதிகைச் செய்து கடவுச்சொல்லை மாற்ற வேண்டும்.\n\nஇக்கணக்கு தவறுதலாக தொடங்கப்பட்டிருந்தால், இத்தகவலைப் புறக்கணிக்கலாம்.",
-    "usernamehasherror": "பயனர் பெயரில் '#' எழுத்தைப் பயன்படுத்த முடியாது",
     "login-throttled": "தாங்கள் மிக அண்மையில் பலமுறை புகுபதிகை செய்ய முயற்சி செய்துள்ளீர்கள்.\n\nமீண்டும் முயற்சிக்கும் முன் $1 காத்திருக்கவும்.",
     "login-abort-generic": "உங்கள் உள்நுழைவு தோல்வியுற்றது - Aborted",
     "loginlanguagelabel": "மொழி: $1",
     "updated": "(இற்றைப்படுத்தப்பட்டது)",
     "note": "'''குறிப்பு:'''",
     "previewnote": "'''இது ஒரு முன்தோற்றம் மட்டுமே''', உங்கள் மாற்றங்கள் இன்னும் சேமிக்கப்படவில்லை!",
-    "continue-editing": "தொகுக்கும் பகுதிக்கு செல்லவும்",
+    "continue-editing": "தொகுக்கும் பகுதிக்குச் செல்லவும்",
     "previewconflict": "இந்த முன்தோற்றம் உரை தொகுப்புப் பகுதியின் மேற்பகுதியிலுள்ள உரையைப் பிரதிபலிக்கின்றது. நீங்கள் இப்பொழுது சேமித்தால் மேற்படி தோற்றமே கிடைக்கும்.",
     "session_fail_preview": "'''உங்கள் அமர்வுத் தரவுகள் அழிந்துப்போனமையால் உங்கள் தொகுப்பை செயற்படுத்த முடியவில்லை. அருள் கூர்ந்து மீண்டும் முயலவும். அதுவும் பலனளிக்காவிட்டால் விடுபதிகைச் செய்து மீண்டும் புகுபதிகைச் செய்யவும்'''",
     "session_fail_preview_html": "'''மன்னிக்கவும்! தங்கள் அமர்வுத் தரவுகள் அழிந்துப்போனமையால் தொகுப்பைச் செயற்படுத்த முடியவில்லை.'''\n\n''கரணியம்:{{SITENAME}} தளத்தில் பக்குவப்படாத எச்.டி.எம்.எல். முடுக்கிவிடப்பட்டுள்ளமையால் ஜாவா நிரல் தாக்குதல்களைத் தவிர்க்கும் பொருட்டு முன்தோற்றம் முடக்கப்பட்டுள்ளது.''\n\n'''இது ஒரு முறையான தொகுப்பாயின், அருள் கூர்ந்து மீண்டும் முயலவும். அதுவும் பலனளிக்காவிடின் [[Special:UserLogout|விடுபதிகை]] செய்து மீண்டும் புகுபதிகை செய்யவும்'''",
     "prefs-skin": "முகப்புறை",
     "skin-preview": "முன்தோற்றம்",
     "datedefault": "விருப்பத்தேர்வுகள் இல்லை",
-    "prefs-datetime": "நாள் நேரம்",
     "prefs-labs": "ஆய்வகச் சிறப்புக்கூறுகள்",
     "prefs-user-pages": "பயனர் பக்கங்கள்",
     "prefs-personal": "பயனர் தரவு",
     "upload-permitted": "அனுமதிக்கப்பட்ட கோப்பு வகைகள்: $1.",
     "upload-preferred": "விரும்பத்தக்க கோப்பு வகைகள்: $1.",
     "upload-prohibited": "தடைச் செய்யப்பட்ட கோப்பு வகைகள்: $1.",
-    "uploadlog": "பதிவேற்றப் பதிகை",
     "uploadlogpage": "பதிவேற்றப் பதிகை",
     "uploadlogpagetext": "கீழேயுள்ளது மிக அண்மையில் பதிவேற்றம் செய்யப்பட்ட கோப்புகளின் பட்டியலாகும்.\nமேலும் விவரங்கள் அறிய, [[Special:NewFiles|புதிய கோப்புகள் பக்கத்தைப்]] பார்க்கவும்.",
     "filename": "கோப்புப் பெயர்",
     "filereuploadsummary": "கோப்பில் செய்யப்பட்ட மாற்றங்கள்:",
     "filestatus": "பதிப்புரிமை நிலை:",
     "filesource": "மூலம்:",
-    "uploadedfiles": "பதிவேற்றப்பட்டக் கோப்புகள்",
     "ignorewarning": "எச்சரிக்கையை சட்டை செய்யாமல் கோப்பை சேமி",
     "ignorewarnings": "எச்சரிக்கைகளைப் புறக்கணி",
     "minlength1": "கோப்பின் பெயர் ஆகக் குறைந்தது ஒரு எழுத்தையாவது கொண்டிருக்க வேண்டும்.",
     "overwroteimage": "\"[[$1]]\" கோப்பின் புதிய பதிப்பை பதிவேற்று",
     "uploaddisabled": "பதிவேற்றம் செயலிழக்கச் செய்யப்பட்டுள்ளது",
     "copyuploaddisabled": "URL வழியாக தகவலேற்றல் முடக்கப்பட்டுள்ளது.",
-    "uploadfromurl-queued": "தங்களுடைய பதிவேற்றம் வரிசையில் உள்ளது.",
     "uploaddisabledtext": "கோப்பு பதிவேற்றங்கள் செயலிழக்கச் செய்யப்பட்டுள்ளன.",
     "php-uploaddisabledtext": "கோப்பு தரவேற்றம் PHP இல் முடக்கப்பட்டுள்ளது.தயவுகூர்ந்து file_uploads அமைப்பை சரிபார்க்கவும்.",
     "uploadscripted": "இந்தக் கோப்பு உலாவியால் பிழையாக விளங்கிக் கொள்ளக்கூடிய எச்.டி.எம்.எல். அல்லது வேறு நிரல்களைக் கொண்டுள்ளது.",
     "upload-misc-error": "இனந்தெரியாத பதிவேற்றல் தவறு",
     "upload-misc-error-text": "தகவலேற்றும்போது அறியப்படாத பிழை ஏற்பட்டுள்ளது.\nதயவுசெய்து இந்த URL செல்லதக்கதா மற்றும் உபயோகிக்ககூடியதா என சரிபார்த்து மீண்டும் முயற்சிக்கவும்.\nஇச்சிக்கல் தொடர்ந்தால் ஒரு  நிர்வாகியை [[Special:ListUsers/sysop|administrator]]  தொடர்பு கொள்ளவும்.",
     "upload-too-many-redirects": "இந்த URL மிக அதிகமான திருப்பங்களை (redirects) கொண்டுள்ளது.",
-    "upload-unknown-size": "தெரியாத அளவு",
     "upload-http-error": "ஒரு HTTP பிழை ஏற்பட்டுள்ளது:$1",
     "upload-copy-upload-invalid-domain": "இந்தக் களத்தில் இருந்து படியெடுத்துப் பதிவேற்றம் செய்யும் வசதி கிடையாது.",
     "backend-fail-stream": " $1 கோப்பை stream செய்ய இயலவில்லை  .",
     "img-auth-streaming": "தொடரோடி \"$1\".",
     "img-auth-public": "Img_auth.php யின் செயல்பாடு, தனியார் விக்கி கோப்புகளை வெளியிட்டு உள்ளது.\nஇந்த விக்கி  பொது விக்கி போல உள்ளமைக்கப்பட்டுள்ளது.\nவிவேகமிக்க பாதுகாப்புக்காக , img_auth.php செயலிழக்கம் செய்யப்பட்டுள்ளது.",
     "img-auth-noread": "பயனர் \"$1\" ஐ படிக்க அனுமதி கொண்டிருக்கவில்லை .",
-    "img-auth-bad-query-string": "செல்லாத கேள்வி எழுத்துகளை URL கொண்டுள்ளது.",
     "http-invalid-url": "செல்லாத உரலி: $1",
     "http-invalid-scheme": " \"$1\" திட்டத்துடன் உள்ள URLகள் ஆதரிக்கப்படாது.",
     "http-request-error": "அறியப்படாத பிழை காரணமாக HTTP கோரிக்கை தோல்வியடைந்தது.",
     "filehist-dimensions": "அளவுகள்",
     "filehist-filesize": "கோப்பின் அளவு",
     "filehist-comment": "கருத்து",
-    "filehist-missing": "கோப்பைக் காணவில்லை",
     "imagelinks": "கோப்பு பயன்பாடு",
     "linkstoimage": "பின்வரும் {{PLURAL:$1|பக்க இணைப்புகள்|$1 பக்கங்கள் இணைப்பு}}\nஇப் படிமத்துக்கு இணைக்கபட்டுள்ளது(ளன):",
     "linkstoimage-more": " $1  க்கும் மேற்பட்ட {{PLURAL:$1| பக்கம் இணைப்புகள்|பக்கத்தின்  இணைப்பு}}  இந்த கோப்பிற்கு உள்ளது.\nகீழ்கண்ட பட்டியல் காட்டுவது,  {{PLURAL:$1| முதல் பக்க இணைப்பு|முதல்  $1 பக்க  இணைப்புகளை பக்கம்}}, இந்த கோப்பிற்கு மட்டும்.\nஒரு [[Special:WhatLinksHere/$2|முழு பட்டியல்]] உள்ளது.",
     "emailuser-title-notarget": "பயனருக்கு மின்னஞ்சல் செய்",
     "emailpage": "மின்னஞ்சல் பயனர்",
     "emailpagetext": "நீங்கள் கீழ்வரும் படிவத்தை உபயோகித்து இந்த பயனருக்கு மின்னஞ்சல் செய்யலாம்.\n\n[[Special:Preferences|என் விருப்பத்தேர்வுகளில்]] நீங்கள் கொடுத்துள்ள மின்னஞ்சல் முகவரி மின்னஞ்சலின் \"From\" முகவரியாகக் காட்சி தரும், இதனால் பெறுநர் உங்களுக்கு நேரடியாக பதில் எழுத முடியும்.",
-    "usermailererror": "மின்னஞ்சல் விளைவாக்கிய தவறு:",
     "defemailsubject": "{{SITENAME}} மின்னஞ்சல் பயனர்  \"$1\"-இடமிருந்து.",
     "usermaildisabled": "பயனரின் மின்னஞ்சல் செயலிழக்கச் செய்யப்பட்டுள்ளது",
     "usermaildisabledtext": "நீங்கள் மற்ற பயனர்களுக்கு இந்த விக்கியில் மின்னஞ்சல் அனுப்ப முடியாது.",
     "noemailtitle": "மின்னஞ்சல் முகவரி இல்லை",
     "noemailtext": "இப் பயனர் ஒரு செல்லுபடியாகக்கூடிய மின்னஞ்சல் முகவரியைக் குறிப்பிடவில்லை.",
-    "nowikiemailtitle": "மின்னஞ்சலுக்கு  அனுமதி இல்லை.",
     "nowikiemailtext": "இந்த பயனர் மற்ற பயனர்களிடமிருந்து மின்னஞ்சல் பெற வேண்டாம் என தேர்வு செய்துள்ளார் .",
     "emailnotarget": "பெறுநர் இல்லாத அல்லது செல்லாத பயனர்பெயர்.",
     "emailtarget": "பெறுநரின் பயனர் பெயரை உள்ளிடவும்",
     "watching": "கவனிக்கப்படுகிறது...",
     "unwatching": "கவனிப்பு விடப்படுகிறது...",
     "watcherrortext": "\"$1\". உக்கான கவனிப்புப் பட்டியல் அமைப்பை மாற்றும்பொழுது பிழை நேர்ந்தது",
-    "enotif_mailer": "{{SITENAME}} தளத்தின் அறிவித்தல் அஞ்சல்காரர்",
     "enotif_reset": "எல்லாப் பக்கங்களையும் பார்வையிட்டதாக குறித்துக்கொள்",
     "enotif_impersonal_salutation": "{{SITENAME}} பயனர்",
     "enotif_lastvisited": "உங்கள் கடைசி வருகைக்குப் பின்னர் நடைபெற்றுள்ள மாற்றங்களைக் காண $1 பக்கத்தைப் பார்க்கவும்.",
     "excontent": "இருந்த உள்ளடக்கம்: '$1'",
     "excontentauthor": "இருந்த உள்ளடக்கம்: '$1' (தவிர, '[[Special:Contributions/$2|$2]]' மட்டுமே பங்களித்திருந்தார்)",
     "exbeforeblank": "வெறுமைப்படுத்த முன்னிருந்த உள்ளடக்கம்: '$1'",
-    "exblank": "பக்கம் வெறுமையாய் இருந்தது",
     "delete-confirm": "\"$1\" பக்கத்தை நீக்கு",
     "delete-legend": "நீக்கவும்",
     "historywarning": "'''எச்சரிக்கை:''' தாங்கள் நீக்கவுள்ள பக்கத்திற்கு சுமார் $1 {{PLURAL:$1|திருத்தம்|திருத்தங்களின்}} வரலாறு உண்டு:",
     "importunknownsource": "அறியப்படாத இறக்குமதிக் கோப்பு வகை",
     "importcantopen": "இறக்குமதிக் கோப்பை திறக்க முடியவில்லை",
     "importbadinterwiki": "பழுதுள்ள விக்கியிடை இணைப்பு",
-    "importnotext": "வெற்று அல்லது உரையெதுவுமில்லை",
     "importsuccess": "இறக்குமதி முற்றியது!",
-    "importhistoryconflict": "முரண்பாடான திருத்த வரலாறுகள் காணப்படுகின்றன (நீர் ஏற்கனவே இப்பக்கத்தை இறக்கியிருக்கலாம்)",
     "importnosources": "விக்கியிடை இறகுமதி மூலம் வரையறுக்கப்படவில்லை மேலும் நேரடி வரலாறு பதிவேற்றங்கள் முடக்கப்பட்டுள்ளன.",
     "importnofile": "இறக்குமதிக் கோப்பொன்றும் பதிவேற்றப்படவில்லை.",
     "importuploaderrorsize": "இறக்குமதி கோப்பின் பதிவேற்றம் தோல்வி. அனுமதிக்கப்பட்ட உச்ச அளவைவிட கோப்பு பெரியது.",
index 1ba88a4..567ad5c 100644 (file)
     "permalink": "శాశ్వత లంకె",
     "print": "ముద్రించు",
     "view": "చూచుట",
+    "view-foreign": "$1 లో చూడండి",
     "edit": "సవరించు",
     "create": "సృష్టించు",
     "editthispage": "ఈ పేజీని సవరించండి",
     "prefs-skin": "రూపు",
     "skin-preview": "మునుజూడు",
     "datedefault": "ఏదైనా పరవాలేదు",
-    "prefs-datetime": "తేదీ, సమయం",
     "prefs-labs": "ప్రయోగాత్మక సౌలభ్యాలు",
     "prefs-user-pages": "వాడుకరి పేజీలు",
     "prefs-personal": "వాడుకరి ప్రవర",
     "listgrouprights-removegroup-self": "{{PLURAL:$2|సమూహాన్ని|సమూహాలని}} తన స్వంత ఖాతా నుండి తొలగించుకోవడం: $1",
     "listgrouprights-addgroup-self-all": "అన్ని సమూహాలని స్వంత ఖాతాకు చేర్చుకోలగడటం",
     "listgrouprights-removegroup-self-all": "స్వంత ఖాతా నుండి అన్ని సమూహాలనూ తొలగించుకోగలగడం",
+    "listgrouprights-namespaceprotection-header": "పేరుబరి నిబంధనలు",
+    "listgrouprights-namespaceprotection-namespace": "పేరుబరి",
     "trackingcategories-name": "సందేశం పేరు",
     "trackingcategories-nodesc": "వివరణ లేదు.",
     "trackingcategories-disabled": "వర్గం అచేతనమై ఉంది",
index 970d6b6..2c98775 100644 (file)
     "prefs-skin": "หน้าตา",
     "skin-preview": "แสดงตัวอย่าง",
     "datedefault": "ค่าตั้งต้น",
-    "prefs-datetime": "วันที่และเวลา",
     "prefs-labs": "คุณสมบัติทดลอง",
     "prefs-user-pages": "หน้าผู้ใช้",
     "prefs-personal": "โพรไฟล์ผู้ใช้",
index 1522484..eecd5ff 100644 (file)
     "permalink": "Постійне посилання",
     "print": "Друк",
     "view": "Перегляд",
+    "view-foreign": "Переглянути на $1",
     "edit": "Редагувати",
+    "edit-local": "Редагувати локальний опис",
     "create": "Створити",
+    "create-local": "Додати локальний опис",
     "editthispage": "Редагувати цю сторінку",
     "create-this-page": "Створити цю сторінку",
     "delete": "Вилучити",
     "pool-timeout": "Час очікування блокування вичерпано",
     "pool-queuefull": "Сервер запитів заповнений",
     "pool-errorunknown": "Невідома помилка",
+    "pool-servererror": "Служба лічильника пулу недоступна ($1).",
     "aboutsite": "Про {{grammar:accusative|{{SITENAME}}}}",
     "aboutpage": "Project:Про",
     "copyright": "Вміст доступний на умовах $1, якщо не вказано інше.",
     "accountcreatedtext": "Обліковий запис користувача для [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|обговорення]]) був створений.",
     "createaccount-title": "Створення облікового запису для {{SITENAME}}",
     "createaccount-text": "Хтось створив обліковий запис «$2» на сервері проекту {{SITENAME}} ($4) з паролем «$3», зазначивши вашу адресу електронної пошти. Вам слід зайти і змінити пароль.\n\nПроігноруйте дане повідомлення, якщо обліковий запис було створено помилково.",
-    "usernamehasherror": "Ім'я користувача не може містити символу «решітка»",
     "login-throttled": "Ви зробили надто багато спроб ввійти до системи.\nБудь ласка, зачекайте $1 перед повторною спробою.",
     "login-abort-generic": "Не вдалося ввійти до системи",
     "loginlanguagelabel": "Мова: $1",
     "prefs-skin": "Оформлення",
     "skin-preview": "Попередній перегляд",
     "datedefault": "Стандартний",
-    "prefs-datetime": "Дата й час",
     "prefs-labs": "Експериментальні функції",
     "prefs-user-pages": "Сторінки користувача",
     "prefs-personal": "Особисті дані",
     "upload-permitted": "Дозволені типи файлів: $1.",
     "upload-preferred": "Бажані типи файлів: $1.",
     "upload-prohibited": "Заборонені типи файлів: $1.",
-    "uploadlog": "журнал завантажень",
     "uploadlogpage": "Журнал завантажень",
     "uploadlogpagetext": "Нижче наведено список останніх завантажених файлів.\nГляньте [[Special:NewFiles|галерею нових зображень]] для більш візуального огляду.",
     "filename": "Назва файлу",
     "filereuploadsummary": "Зміни у файлі:",
     "filestatus": "Умови поширення:",
     "filesource": "Джерело:",
-    "uploadedfiles": "Завантажені файли",
     "ignorewarning": "Ігнорувати попередження і зберегти файл",
     "ignorewarnings": "Ігнорувати всі попередження",
     "minlength1": "Назва файлу повинна містити щонайменше одну літеру.",
     "overwroteimage": "завантажив нову версію «[[$1]]»",
     "uploaddisabled": "Завантаження заборонене",
     "copyuploaddisabled": "Завантаження через URL вимкнене.",
-    "uploadfromurl-queued": "Ваше завантаження поставлене в чергу.",
     "uploaddisabledtext": "Можливість завантаження файлів відключена.",
     "php-uploaddisabledtext": "Завантаження файлів вимкнене у налаштуваннях PHP. Будь ласка, перевірте значення file_uploads.",
     "uploadscripted": "Файл містить HTML-код або скрипт, який може неправильно обробитися браузером.",
     "upload-misc-error": "Невідома помилка завантаження",
     "upload-misc-error-text": "Невідома помилка завантаження. Будь-ласка, перевірте, що вказана адреса вірна й спробуйте ще. Якщо проблема виникає знову, зверніться до [[Special:ListUsers/sysop|адміністратора]].",
     "upload-too-many-redirects": "URL містить надто багато перенаправлень",
-    "upload-unknown-size": "Невідомий розмір",
     "upload-http-error": "Відбулася помилка HTTP: $1",
     "upload-copy-upload-invalid-domain": "З цього домену завантаження неможливе.",
     "backend-fail-stream": "Не вдалося транслювати файл $1.",
     "img-auth-streaming": "Потокова передача «$1».",
     "img-auth-public": "Призначенням img_auth.php є добування файлів із закритих вікі.\nЦя вікі налаштована як загальнодоступна.\nДля оптимальної безпеки img_auth.php відключено.",
     "img-auth-noread": "Користувач не має доступу до перегляду \"$1\".",
-    "img-auth-bad-query-string": "URL-адреса містить неправильний рядок запиту.",
     "http-invalid-url": "Неправильний URL: $1",
     "http-invalid-scheme": "URL-адреси схеми \"$1\" не підтримуються",
     "http-request-error": "HTTP-запит не вдався через невідому помилку.",
     "filehist-dimensions": "Розмір об'єкта",
     "filehist-filesize": "Розмір файлу",
     "filehist-comment": "Коментар",
-    "filehist-missing": "Файл відсутній",
     "imagelinks": "Використання файлу",
     "linkstoimage": "{{PLURAL:$1|1=Наступна сторінка посилається|Наступні сторінки посилаються}} на цей файл:",
     "linkstoimage-more": "Більше $1 {{PLURAL:$1|1=сторінки|сторінок}} посилаються на цей файл.\nУ цьому списку {{PLURAL:$1|показане тільки $1 посилання|показані тільки $1 посилання|показані тільки $1 посилань}} на цей файл.\nТакож доступний [[Special:WhatLinksHere/$2|повний список]].",
     "deadendpagestext": "Наступні сторінки не містять посилань на інші сторінки цієї вікі.",
     "protectedpages": "Захищені сторінки",
     "protectedpages-indef": "Тільки безстроково захищені",
-    "protectedpages-summary": "На цій сторінці перераховані сторінки, які на цей момент захищені. Список назв, які захищені від створення див. [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+    "protectedpages-summary": "На цій сторінці перераховані сторінки, які на цей момент захищені. Список назв, які захищені від створення див.  [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
     "protectedpages-cascade": "Тільки каскадний захист",
     "protectedpages-noredirect": "Сховати перенаправлення",
     "protectedpagesempty": "Зараз нема захищених сторінок із зазначеними параметрами",
     "protectedpages-unknown-timestamp": "Невідомо",
     "protectedpages-unknown-performer": "Невідомий користувач",
     "protectedtitles": "Заборонені назви",
-    "protectedtitles-summary": "На цій сторінці перераховані назви, які захищені від створення. Для перегляду списку сторінок, які на цей момент захищені, див. [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
+    "protectedtitles-summary": "На цій сторінці перераховані назви, які захищені від створення. Для перегляду списку сторінок, які на цей момент захищені, див.  [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
     "protectedtitlesempty": "Зараз нема захищених назв із зазначеними параметрами.",
     "listusers": "Список користувачів",
     "listusers-editsonly": "Показати лише користувачів, які зробили принаймні одне редагування",
     "listgrouprights-removegroup-self": "може вилучати {{PLURAL:$2|1=групу|групи}} зі свого облікового запису: $1",
     "listgrouprights-addgroup-self-all": "Може додавати всі групи до свого облікового запису",
     "listgrouprights-removegroup-self-all": "може вилучати всі групи зі свого облікового запису",
+    "listgrouprights-namespaceprotection-header": "Обмеження простору імен",
+    "listgrouprights-namespaceprotection-namespace": "Простір імен",
+    "listgrouprights-namespaceprotection-restrictedto": "Права, що дозволяють учаснику редагувати",
+    "trackingcategories": "Відстежувані категорії",
+    "trackingcategories-summary": "На цій сторінці перераховані відстежують категорії, які заповнюються автоматично програмним забезпеченням MediaWiki. Їх можна перейменувати, змінивши відповідні системні повідомлення в просторі імен {{ns:8}}.",
+    "trackingcategories-msg": "Відстежувана категорія",
+    "trackingcategories-name": "Ім'я повідомлення",
+    "trackingcategories-desc": "Критерій включення в категорію",
+    "noindex-category-desc": "Сторінка не індексується пошуковими роботами, тому що на ній є «чарівне слово» <code><nowiki>__NOINDEX__</nowiki></code>, і вона знаходиться в просторі імен, де дозволений цей прапор).",
+    "index-category-desc": "На сторінці є «чарівне слово» __INDEX__ (і сторінка знаходиться в просторі імен, де дозволений цей прапор), тому вона індексуються пошуковими роботами в тих випадках, коли цього зазвичай не відбувається.",
+    "post-expand-template-inclusion-category-desc": "Після показу всіх шаблонів розмір сторінки стане більше, ніж <code>$wgMaxArticleSize</code>, тому деякі шаблони не були показані повністю.",
+    "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": "Категорія додається, якщо сторінка містить некоректну файлову посилання (посилання на неіснуючий файл).",
+    "hidden-category-category-desc": "Це категорія з доданою міткою <code><nowiki>__HIDDENCAT__</nowiki></code> в неї, що за замовчуванням запобігає її відображенню на сторінках в розділі категорій.",
+    "trackingcategories-nodesc": "Опис відсутній.",
+    "trackingcategories-disabled": "Категорія вимкнена",
     "mailnologin": "Відсутня адреса для відправки",
     "mailnologintext": "Ви повинні [[Special:UserLogin|ввійти до системи]] і мати підтверджену адресу електронної пошти у ваших [[Special:Preferences|налаштуваннях]], щоб мати змогу надсилати електронну пошту іншим користувачам.",
     "emailuser": "Надіслати листа",
     "emailuser-title-notarget": "Надіслати електронного листа користувачеві",
     "emailpage": "Лист користувачеві",
     "emailpagetext": "Заповнивши наведену нижче форму, можна надіслати повідомлення {{GENDER:$1|цьому користувачу|цій користувачці}}.\nЕлектронна адреса, яку Ви зазначили у [[Special:Preferences|своїх налаштуваннях]], буде зазначена в полі «Від кого» листа, тому одержувач матиме можливість відповісти безпосередньо вам.",
-    "usermailererror": "При відправці повідомлення електронної пошти сталася помилка:",
     "defemailsubject": "{{SITENAME}} - електронний лист від користувача \" $1 \"",
     "usermaildisabled": "Електронне листування між користувачами вимкнене",
     "usermaildisabledtext": "Ви не можете надсилати електронні листи іншим користувачам цієї вікі",
     "noemailtitle": "Відсутня адреса електронної пошти",
     "noemailtext": "Цей користувач не вказав коректної адреси електронної пошти.",
-    "nowikiemailtitle": "Ел. пошти не дозволено",
     "nowikiemailtext": "Цей користувач вирішив не отримувати ел. пошту від інших користувачів.",
     "emailnotarget": "Неіснуюче чи некоректне ім'я одержувача",
     "emailtarget": "Введіть ім'я користувача-одержувача",
     "watching": "Додавання до списку спостереження…",
     "unwatching": "Вилучення зі списку спостереження…",
     "watcherrortext": "Сталася помилка при заміні налаштувань списку спостереження для \" $1 \".",
-    "enotif_mailer": "{{SITENAME}} Служба сповіщення поштою",
     "enotif_reset": "Позначити всі сторінки як переглянуті",
     "enotif_impersonal_salutation": "Користувач {{grammar:genitive|{{SITENAME}}}}",
     "enotif_subject_deleted": "Сторінку {{GRAMMAR:genitive|{{SITENAME}}}} «$1» було вилучено {{GENDER:$2|користувачем|користувачкою}} $2",
     "excontent": "зміст: «$1»",
     "excontentauthor": "зміст був: «$1» (єдиний автор: [[Special:Contributions/$2|$2]])",
     "exbeforeblank": "зміст до очистки: «$1»",
-    "exblank": "стаття була порожньою",
     "delete-confirm": "Вилучення «$1»",
     "delete-legend": "Вилучення",
     "historywarning": "'''Попередження:''' Сторінка, яку ви збираєтеся вилучити, має історію редагувань з приблизно $1 {{PLURAL:$1|1=версії|версій}}:",
     "importunknownsource": "Невідомий тип імпортованої сторінки",
     "importcantopen": "Неможливо відкрити файл імпорту",
     "importbadinterwiki": "Невірне інтервікі-посилання",
-    "importnotext": "Текст відсутній",
     "importsuccess": "Імпорт виконано!",
-    "importhistoryconflict": "Конфлікт існуючих версій (можливо, цю сторінку вже імпортували)",
     "importnosources": "Не було вибране джерело міжвікі-імпорту, пряме завантаження історії змін вимкнуте.",
     "importnofile": "Файл імпорту не було завантажено.",
     "importuploaderrorsize": "Не вдалося завантажити або імпортувати файл. Розмір файлу перевищує встановлену межу.",
index f249faf..ff50887 100644 (file)
     "privacy": "Maxfiylik siyosati",
     "privacypage": "Project:Maxfiylik siyosati",
     "badaccess": "Ruxsatlilik xatosi",
-    "badaccess-group0": "Siz so'ralgan amallarni bajara olmaysiz",
-    "badaccess-groups": "So'ralgan amallarni kamida $1 {{PLURAL:$2|guruhi|guruhlari}} foydalanuvchilarigina amalga oshirishi mumkin.",
+    "badaccess-group0": "Sizda soʻralgan amallarni bajarish huquqi yoʻq.",
+    "badaccess-groups": "Soʻralgan amallarni kamida $1 {{PLURAL:$2|guruhi|guruhlari}} foydalanuvchilari amalga oshirishi mumkin.",
     "versionrequired": "$1 versiyasidagi MediaWiki talab etiladi",
     "versionrequiredtext": "Bu sahifada ishlash uchun MediaWikining $1-versiyasi talab etiladi.\n[[Special:Version|Dasturiy taʼminot haqida axborot]]ni koʻring.",
     "ok": "OK",
     "searchall": "barchasi",
     "showingresults": "Quyida №'''$2'''dan boshlab {{PLURAL:$1|'''bitta''' natija|'''$1''' ta natija}} koʻrsatilgan.",
     "showingresultsnum": "Quyida №'''$2'''dan boshlab '''$1''' ta {{PLURAL:$1|natija}} ko'rsatildi.",
-    "showingresultsheader": "$4 uchun {{PLURAL:$5|'''$3'''dan '''$1''' natija|'''$3'''dan '''$1 - $2''' natijalar}}",
+    "showingresultsheader": "<strong>$4</strong> uchun jami {{PLURAL:$5|<strong>$3</strong> tadan <strong>$1</strong> ta natija koʻrsatildi|<strong>$3</strong> tadan <strong>$1</strong> — <strong>$2</strong> chi natijalar koʻrsatildi}}",
     "search-nonefound": "Talabga javob beradigan natija topilmadi.",
     "powersearch-legend": "Kengaytirilgan qidiruv",
     "powersearch-ns": "Quyidagi nomfazolardan qidir:",
     "prefs-skin": "Tashqi ko‘rinishi",
     "skin-preview": "Ko‘rib chiqish",
     "datedefault": "Farqi yoʻq",
-    "prefs-datetime": "Sana va vaqt",
     "prefs-labs": "Tajribaviy imkoniyatlar",
     "prefs-user-pages": "Foydalanuvchi sahifalari",
     "prefs-personal": "Shaxsiy ma’lumotlar",
     "action-edit": "ushbu sahifani tahrirlash",
     "action-move": "bu sahifani koʻchirish",
     "action-move-subpages": "Bu sahifani va uning ostsahifalarini koʻchirish",
+    "action-deletedhistory": "ushbu sahifaning oʻchirilgan tarixini koʻrish",
     "action-sendemail": "elektron xatlar jo'natish",
     "nchanges": "$1 {{PLURAL:$1|oʻzgarish|oʻzgarishlar}}",
     "recentchanges": "Yangi oʻzgarishlar",
     "recentchanges-legend-heading": "'''Izoh:'''",
     "recentchanges-legend-newpage": "([[Special:NewPages|alohida roʻyxat]])",
     "rcnotefrom": "Quyida <strong>$2</strong> dan boshlab boʻlgan oʻzgarishlar keltirilgan (<strong>$1</strong> tasi koʻrsatildi).",
-    "rclistfrom": "$3, $2 dan boshlab yangi oʻzgarishlarni koʻrsat.",
+    "rclistfrom": "$3, $2 dan keyingi yangi oʻzgarishlarni koʻrsatish",
     "rcshowhideminor": "Kichik tahrirlarni $1",
+    "rcshowhideminor-show": "koʻrsat",
+    "rcshowhideminor-hide": "yashir",
     "rcshowhidebots": "Botlarni $1",
     "rcshowhidebots-show": "koʻrsat",
     "rcshowhidebots-hide": "yashir",
     "rcshowhideanons-show": "koʻrsat",
     "rcshowhideanons-hide": "yashir",
     "rcshowhidepatr": "Tekshirilgan tahrirlarni $1",
+    "rcshowhidepatr-hide": "yashir",
     "rcshowhidemine": "Oʻz tahrirlarimni $1",
+    "rcshowhidemine-show": "koʻrsat",
+    "rcshowhidemine-hide": "yashir",
     "rclinks": "Oxirgi $2 kun ichida sodir boʻlgan $1 ta oʻzgarish koʻrsatildi<br />$3",
     "diff": "farq",
     "hist": "tarix",
     "maximum-size": "Eng katta hajm:",
     "pagesize": "(bayt)",
     "restriction-edit": "Tahrirlash",
-    "restriction-move": "Ko'chirish",
+    "restriction-move": "Koʻchirish",
     "restriction-create": "Yaratish",
     "restriction-upload": "Yuklash",
     "restriction-level-sysop": "to'liq himoya",
     "block-log-flags-nousertalk": "o'zining munozara sahifasini tahrirlay olmaydi",
     "move-page": "$1 — qayta nomlash",
     "move-page-legend": "Sahifani qayta nomlash",
-    "movearticle": "Sahifani qayta nomlash",
+    "movearticle": "Hozirgi nomi:",
     "newtitle": "Yangi nom:",
     "move-watch": "Ushbu sahifani kuzatuv roʻyxatingizga qoʻshish",
     "movepagebtn": "Sahifani koʻchirish",
     "movepage-moved": "'''\"$1\" nomli sahifa \"$2\" nomli sahifaga koʻchirildi'''",
     "movepage-moved-redirect": "Qayta yo‘naltirish yaratildi.",
     "movetalk": "Mos munozara sahifasini qayta nomlash",
+    "move-subpages": "Ostsahifalarni ham qayta nomlash ($1 gacha)",
+    "move-talk-subpages": "Munozara sahifasining ostsahifalarini ham qayta nomlash ($1 gacha)",
     "movelogpage": "Koʻchirish qaydlari",
     "movesubpage": "{{PLURAL:$1|Ostsahifa|Ostsahifalar}}",
     "movesubpagetext": "Ushbu sahifaning $1 ta ostsahifasi bor.",
     "revertmove": "qaytarish",
     "delete_and_move": "O‘chirish va qayta nomlash",
     "delete_and_move_confirm": "Ha, ushbu sahifa o‘chirilsin",
+    "fix-double-redirects": "Oldingi nomga yoʻnaltirishlarni toʻgʻrilash",
     "move-leave-redirect": "Qayta yoʻnaltirish qoldirish",
     "move-over-sharedrepo": "== Fayl allaqachon mavjud ==\nUmumiy omborda [[:$1]] mavjud. Faylning bu nomga qayta nomlanishi faylning umumiy omborda to‘silishiga olib keladi.",
     "export": "Sahifalar eksporti",
index 6479d7d..1c7498b 100644 (file)
     "prefs-skin": "Hình dạng",
     "skin-preview": "Xem trước",
     "datedefault": "Không quan tâm",
-    "prefs-datetime": "Ngày tháng",
     "prefs-labs": "Tính năng phòng thí nghiệm",
     "prefs-user-pages": "Trang cá nhân",
     "prefs-personal": "Thông tin cá nhân",
     "listgrouprights-removegroup-self": "Có thể loại tài khoản của chính mình ra khỏi {{PLURAL:$2|nhóm|các nhóm}}: $1",
     "listgrouprights-addgroup-self-all": "Có thể đưa tài khoản của chính mình vào tất cả các nhóm",
     "listgrouprights-removegroup-self-all": "Có thể loại tài khoản của chính mình ra khỏi tất cả các nhóm",
+    "listgrouprights-namespaceprotection-header": "Hạn chế không gian tên",
+    "listgrouprights-namespaceprotection-namespace": "Không gian tên",
+    "listgrouprights-namespaceprotection-restrictedto": "Quyền cho phép người dùng chỉnh sửa",
     "trackingcategories": "Thể loại phần mềm",
     "trackingcategories-summary": "Đây là danh sách các thể loại được phần mềm MediaWiki tự động xếp trang vào. Các tên thể loại được định rõ trong các thông điệp thuộc không gian tên {{ns:8}}.",
     "trackingcategories-msg": "Thể loại phần mềm",
     "unwatchthispage": "Ngừng theo dõi",
     "notanarticle": "Không phải trang có nội dung",
     "notvisiblerev": "Phiên bản bị xóa",
-    "watchlist-details": "Bạn đang theo dõi {{PLURAL:$1|$1 trang|$1 trang}}, không kể các trang thảo luận.",
+    "watchlist-details": "Bạn đang theo dõi {{PLURAL:$1}}$1 trang, không kể riêng các trang thảo luận.",
     "wlheader-enotif": "Đã bật thông báo qua thư điện tử.",
     "wlheader-showupdated": "Các trang đã thay đổi kể từ lần cuối bạn xem chúng được in '''đậm'''",
     "watchmethod-recent": "Dưới đây hiện thay đổi mới với các trang theo dõi.",
index b006441..4d07e61 100644 (file)
     "permalink": "שטענדיגער לינק",
     "print": "דרוק",
     "view": "באַקוקן",
+    "view-foreign": "באקוקן אויף $1",
     "edit": "רעדאַקטירן",
+    "edit-local": "רעדאקטירן לאקאלע באשרײַבונג",
     "create": "שאַפֿן",
+    "create-local": "צולייגן לאקאלע באשרײַבונג",
     "editthispage": "ענדערן דעם בלאט",
     "create-this-page": "שאַפֿן דעם בלאַט",
     "delete": "אויסמעקן",
     "accountcreatedtext": "די באניצער קאנטע פאר [[{{ns:User}}:$1|$1]] \n([[{{ns:User talk}}:$1|שמועס]])  איז באַשאַפֿן געווארן.",
     "createaccount-title": "קאנטע באשאפֿן אין {{SITENAME}}",
     "createaccount-text": "עמעצער האט באשאפֿן א קאנטע פֿאר אייער ע-פאסט אדרעס אין {{SITENAME}} ($4) מיטן נאמען \"$2\" און  פאסווארט \"$3\". איר דארפט אצינד איינלאגירן און ענדערן דאס פאסווארט.\n\nאיר קענט איגנארירן די מעלדונג, ווען די קאנטע איז באשאפֿן בטעות.",
-    "usernamehasherror": "באַניצער נאמען טאָר נישט אַנטהאַלטן קיין לייטער סימבאל",
     "login-throttled": "איר האט געפרוווט צופֿיל מאל אריינלאגירן.\nזייט אזוי גוט און וואַרט $1 איידער איר פרוווט נאכאמאל.",
     "login-abort-generic": "אײַער ארײַנלאגירונג איז נישט געווען דערפֿאלגרייך—אָפגעשטעלט",
     "loginlanguagelabel": "שפראך: $1",
     "undo-success": "די ענדערונג קען ווערן מבוטל. ביטע נאכקוקן די פארגלייך פון אונטן צו זיין זיכער אז דאס איז וואס איר ווילט טאן, און דערנאך היט-אפ די ענדערונגן פון אונטן צו ענדיגן דאס בטל מאכן די ענדערונג.",
     "undo-failure": "די ענדערונג קען נישט מבוטל ווערן צוליב סתירות מיט צווישנצייטלעכע ענדערונגען.",
     "undo-norev": "ס'איז נישט מעגלעך צוריקקערן די רעדאַקטירונג ווײַל זי עקסיסטירט נישט אדער איז אויסגעמעקט.",
+    "undo-nochange": "אויבערפלעכטלעך איז די רעדאקטירונג שוין געווארן אנולירט.",
     "undo-summary": "זיי מבטל רי-ווערסיע $1 פון [[Special:Contributions/$2|$2]] ([[User talk:$2|רעדן]])",
     "undo-summary-username-hidden": "זײַט מבטל ווערסיע $1 פון א באהאלטענעם באניצער",
     "cantcreateaccounttitle": "מען קען נישט באשאפֿן קאנטע",
     "revdelete-no-file": "די ספעציפֿירטע טעקע עקזיסטירט נישט.",
     "revdelete-show-file-confirm": "צי זענט איר זעכער איר ווילט באַקוקן אַן אויסגעמעקטע רעוויזיע פון דער טעקע \"<nowiki>$1</nowiki>\" פון $2 בשעה $3?",
     "revdelete-show-file-submit": "יא",
+    "revdelete-selected-text": "'''{{PLURAL:$2|אויסדערוויילטע רעוויזיע| אויסדערוויילטע רעוויזיעס}} פון [[:$1]]:'''",
     "logdelete-selected": "{{PLURAL:$1| אויסדערוויילטע לאג אקציע|אויסדערוויילטע לאג אקציעס}}:",
     "revdelete-confirm": "זייט אזוי גוט און באשטעטיקט אז דאס איז טאקע אייער כוונה, אז איר פארשטייט די קאנסעקווענצן, און אז איר טוט דאס לויט  [[{{MediaWiki:Policy-url}}|דער פאליסי]].",
     "revdelete-suppress-text": "אונטערדרוקן זאל בלויז גענוצט ווערן '''נאר''' אין די פאלגנדע פעלער:\n* אינפארמאציע וואס קען זיין מוציא שם רע\n* אויפדעקונג פון פריוואטקייט אינפארמאציע\n*: ''היים אדרעסן, טעלעפאן נומערן, נאציאנאלע אידענטיפיקאציע נומערן, א.א.וו.''",
     "prefs-skin": "סקין",
     "skin-preview": "פארויסדיגע ווייזונג",
     "datedefault": "נישטא קיין פרעפערענץ",
-    "prefs-datetime": "דאטום און צייט",
     "prefs-labs": "לאַבאראַטאריע מעגלעכקייטן",
     "prefs-user-pages": "באניצער בלעטער",
     "prefs-personal": "באַניצער פראָפֿיל",
     "upload-permitted": "ערלויבטע טעקע טיפן: $1.",
     "upload-preferred": "פרעפֿרירטע טעקע טיפן: $1.",
     "upload-prohibited": "פֿאַרווערענע טעקע טיפן: $1.",
-    "uploadlog": "ארויפלאָדן לאָגבוך",
     "uploadlogpage": "ארויפֿלאדן לאג",
     "uploadlogpagetext": "פֿאָלגנד איז אַ ליסטע פֿון די לעצטע אַרױפֿגעלאָדענע טעקעס.\nזעט די  [[Special:NewFiles|גאלאריע פֿון נײַע טעקעס]] פֿאַר א מער וויזועלע איבערבליק.",
     "filename": "טעקע נאמען",
     "filereuploadsummary": "טעקע ענדערונגען:",
     "filestatus": "קאפירעכט סטאַטוס:",
     "filesource": "מקור:",
-    "uploadedfiles": "ארויפֿגעלאדעטע טעקעס",
     "ignorewarning": "איגנאָרירן ווארענונג און אויפֿהיטן טעקע סיי ווי סיי",
     "ignorewarnings": "איגנארירן וואָרענונגען",
     "minlength1": "א טעקע נאמען מוז האבן כאטש איין אות.",
     "overwroteimage": "אַרויפֿגעלאָדן א נײַע ווערסיע פון \"[[$1]]\"",
     "uploaddisabled": "אַרויפֿלאָדן טעקעס מבוטל",
     "copyuploaddisabled": "ארויפלאדן דורך URL אומאקטיווירט",
-    "uploadfromurl-queued": "אייער ארויפֿלאד איז אין דער רייע.",
     "uploaddisabledtext": "אַרויפֿלאָדן טעקעס נישט דערמעגלעכט.",
     "php-uploaddisabledtext": "אַרויפֿלאָדן טעקעס נישט דערמעגלעכט אין PHP.\nזייט אזוי גוט בודק זיין די file_uploads שטעלונג.",
     "uploadscripted": "די טעקע האט א סקריפט אדער HTML קאד וואס קען ווערן פֿאלש אויסגעטייטשט דורך א בלעטערער",
+    "uploadscriptednamespace": "די SVG טעקע אנטהאלט אן אומלעגאלן נאמענטייל  \"$1\"",
     "uploadvirus": "די טעקע האָט אַ ווירוס! פרטים: <div dir=\"rtl\">$1</div>",
     "upload-source": "מקור טעקע",
     "sourcefilename": "מקור טעקע נאמען:",
     "upload-misc-error": "אומבאַוואוסטער ארויפֿלאָדן גרײַז",
     "upload-misc-error-text": "אן אומבאקאנטער גרייז האט פאסירט בשעת דעם ארויפלאד.\nביטע באשטעטיקט אז דער  URL איז גילטיק און דערגרייכבאר און פרובירט נאכאמאל.\nווען דער פראבלעם בלייבט ווייטער, קאנטאקטירט  א [[Special:ListUsers/sysop|סיסאפ]].",
     "upload-too-many-redirects": "דער URL אַנטהאַלט צופֿיל ווײַטערפֿירונגען.",
-    "upload-unknown-size": "אומוויסנדע גרייס",
     "upload-http-error": "א HTTP גרײַז האט פאַסירט: $1",
     "backend-fail-stream": "קען נישט מאכן שטראמען טעקע $1.",
     "backend-fail-notexists": "נישט פֿאראן די טעקע $1.",
     "img-auth-isdir": "איר פֿארזיכט צוצוטרעטן אן ארכיוו \"$1\".\nנאר טעקע צוטריט איז ערלויבט.",
     "img-auth-streaming": "שטראָמענדיק \"$1\".",
     "img-auth-noread": "באניצער האט נישט קיין דערלויבניש צו ליינען \"$1\".",
-    "img-auth-bad-query-string": "דער URL האט אן אומגילטיק פראגע שנורל.",
     "http-invalid-url": "אומגילטיג URL: $1",
     "http-invalid-scheme": "URL אדרעסן מיט דער \"$1\" סכעמע ווערן נישט געשטיצט.",
     "http-request-error": "HTTP בקשה דורכגעפאלן צוליב אומבאוואוסטער פעלער.",
     "filehist-dimensions": "געמעסטן",
     "filehist-filesize": "טעקע גרייס",
     "filehist-comment": "באמערקונג",
-    "filehist-missing": "טעקע פעלט",
     "imagelinks": "טעקע באַניץ",
     "linkstoimage": "{{PLURAL:$1|דער פאלגנדער בלאט ניצט|די פאלגנדע בלעטער ניצן}} דאס דאזיגע בילד:",
     "linkstoimage-more": "מער ווי $1 {{PLURAL:$1|בלאַט פֿאַרבינדט|בלעטער פֿאַרבינדן}} צו דער דאזיגער טעקע.\nדי פֿאלגנדע ליסטע ווײַזט  {{PLURAL:$1|דעם ערשטן בלאַט לינק|די ערשטע $1 בלאַט לינקען}} צו דער טעקע.\nס'איז פֿאַראַן[[Special:WhatLinksHere/$2|פֿולע רשימה]].",
     "download": "אַראָפלאָדן",
     "unwatchedpages": "בלעטער וואס זענען נישט אויפגעפאסט",
     "listredirects": "ליסטע פון ווײַטערפֿירונגען",
+    "listduplicatedfiles": "ליסטע פון טעקעס מיט דופליקאטן",
     "unusedtemplates": "נישט באניצטע מוסטערן",
     "unusedtemplatestext": "דער בלאט ווײַזט אלע בלעטער אינעם {{ns:template}} נאמענטייל וואס זענען נישט אײַנגעשלאסן אין אן אנדער בלאט. געדענקט צו באקוקן אנדערע בלעטער פאר לינקען צו די מוסטערן איידער איר מעקט זיי אויס.",
     "unusedtemplateswlh": "אנדערע פֿאַרבינדונגען",
     "listgrouprights-removegroup-self": "א§ראָפנעמען {{PLURAL:$2|גרופּע |גרופּעס}} פון אייגענער קאנטע: $1",
     "listgrouprights-addgroup-self-all": "צולייגן אַלע גרופעס צו אייגענער קאנטע",
     "listgrouprights-removegroup-self-all": "אראָפנעמען אַלע גרופעס פֿון אייגענער קאנטע",
+    "listgrouprights-namespaceprotection-namespace": "נאָמענטייל",
     "mailnologin": "נישטא קיין אדרעס צו שיקן",
     "mailnologintext": "איר ברויכט זײַן [[Special:UserLogin|אַרײַנלאגירט]] און האָבן א גילטיגן ע־פאסט אַדרעס אין אײַער [[Special:Preferences|פרעפֿערענצן]] צו שיקן ע־פאסט צו אַנדערע באַניצער.",
     "emailuser": "שיקן ע-פאסט צו דעם באַניצער",
     "emailuser-title-notarget": "שיקן א באניצער ע־פאסט",
     "emailpage": "שיקן ע-פאסט צו באַניצער",
     "emailpagetext": "איר קענט ניצן די פֿארעם אונטן צו שיקן א בליצבריוו צו {{GENDER:$1|דעם דאזיגן באַניצער|דער דאזיגער באַניצערין}}.\nדער ע-פאסט אדרעס וואס איר האט אריינגעלייגט אין [[Special:Preferences| אייערע באַניצער פרעפערנעצן]] וועט זיך ווײַזן כאילו דאס איז געקומען פון דארטן, בכדי צו דערמעגלעכן א תשובה.",
-    "usermailererror": "בליצבריוו האט צוריקגעשיקט א טעות:",
     "defemailsubject": "ע-פאסט פון באַניצער \"$1\" {{SITENAME}}",
     "usermaildisabled": "באַניצער ע־פאסט אומאַקטיוויזירט",
     "usermaildisabledtext": "איר קענט נישט שיקן ע־פאסט צו אנדערע באַניצערס אויף דער דאָזיקער וויקי",
     "noemailtitle": "נישטא קיין אי-מעיל אדרעס",
     "noemailtext": "דער באַניצער האט נישט באשטימט קיין גילטיקן ע-פאסט אדרעס.",
-    "nowikiemailtitle": "קיין ע-פאסט נישט דערלויבט",
     "nowikiemailtext": "דער באַניצער האט געקליבן נישט באַקומען ע־פאסט פֿון אַנדערע באַניצער.",
     "emailnotarget": "נישט־פֿאראן אדער אומגילטיקער באַניצער־נאָמען פאר באַקומער.",
     "emailtarget": "אַרײַנגעבן באַניצער־נאָמען פון באַקומער",
     "unwatchthispage": "ענדיגן אויפֿפאַסן",
     "notanarticle": "דאס איז נישט קיין אינהאלט בלאט",
     "notvisiblerev": "די באארבעטונג איז געווארן אויסגעמעקט",
-    "watchlist-details": "{{PLURAL:$1|איין בלאט|$1 בלעטער}} אין אייער אויפֿפאסן ליסטע (נישט רעכענען  רעדן בלעטער).",
+    "watchlist-details": "{{PLURAL:$1|$1 בלאט|$1 בלעטער}} אין אייער אויפֿפאסן ליסטע, נישט רעכענען  רעדן בלעטער.",
     "wlheader-enotif": "ע-פאסט מעלדונג ערמעגליכט.",
     "wlheader-showupdated": "בלעטער געענדערט זײַט אײַער לעצטן וויזיט זען געוויזן '''דיק'''.",
     "watchmethod-recent": "קאנטראלירן לעצטע ענדערונגען פֿאַר אויפֿגעפאַסטע בלעטער",
     "watching": "אויפפאסענדונג…",
     "unwatching": "נעמט אראפ פון אויפפאסונג ליסטע…",
     "watcherrortext": "א גרײַז האט פאסירט ביים ענדערן אײַערע אויפֿפאסן ליסטע אײַנשטעלונגען פֿאר \"$1\".",
-    "enotif_mailer": "נאטיפאקאציע שיקער {{SITENAME}}",
     "enotif_reset": "באַצייכענען אלע בלעטער שוין געזען",
     "enotif_impersonal_salutation": "{{SITENAME}} באַניצער",
     "enotif_subject_deleted": "{{SITENAME}} בלאט $1 איז אויסגעמעקט געווארן דורך {{gender:$2|$2}}",
     "excontent": "אינהאלט געווען: \"$1\"",
     "excontentauthor": "אינהאלט געווען: '$1' (און דער איינציגסטער באארבעטער איז געווען '[[Special:Contributions/$2|$2]]')",
     "exbeforeblank": "אינהאַלט בעפֿאַרן אויסליידיגן איז געווען: \"$1\"",
-    "exblank": "בלאט איז געווען ליידיג",
     "delete-confirm": "אויסמעקן $1",
     "delete-legend": "אויסמעקן",
     "historywarning": "אכטונג – איר גייט אויסמעקן א בלאט וואָס האט א היסטאריע מיט $1 {{PLURAL:$1|ווערסיע|ווערסיעס}}:",
     "importunknownsource": "אומבאקאנטער  אימפארט טיפ",
     "importcantopen": "נישט געקענט עפֿענען אימפארט טעקע",
     "importbadinterwiki": "שלעכטע אינטערוויקי לינק",
-    "importnotext": "ליידיג אדער נישט קיין טעקסט",
     "importsuccess": "!אימפארט אדורכגעפירט מיט דערפאלג!",
-    "importhistoryconflict": "פאראן א קאנפליקט מיט דער עקזיסטירנדע היסטאריע רעוויזיע (מעגליך אז דער בלאט איז געווארן אימפארטירט שוין פריער)",
     "importnosources": "קיין מקורות פֿאַר צווישן־וויקי אימפארט, און דירעקט היסטאריע אַרויפֿלאָדן איז נישט דערמעגלעכט אַצינד.",
     "importnofile": "קיין אימפארט טעקע איז נישט ארויפֿגעלאדן.",
     "importuploaderrorsize": "אַרויפֿלאָדן פֿון אימפארט טעקע דורכגעפֿאלן.\nדי טעקע איז גרעסער פֿון דער דערלויבטער אַרויפֿלאָדן גרייס.",
index 76677a8..7e1e9c8 100644 (file)
     "prefs-skin": "畫面",
     "skin-preview": "預覽",
     "datedefault": "冇喜好",
-    "prefs-datetime": "日期同埋時間",
     "prefs-labs": "實驗性嘅特色",
     "prefs-personal": "用戶簡介",
     "prefs-rc": "最近更改",
index 68188eb..e538bc7 100644 (file)
@@ -72,7 +72,8 @@
             "御坂美琴",
             "燃玉",
             "范",
-            "阿pp"
+            "阿pp",
+            "Hudafu"
         ]
     },
     "tog-underline": "链接下划线:",
     "tog-shownumberswatching": "显示监视用户数",
     "tog-oldsig": "当前签名:",
     "tog-fancysig": "将签名视为维基文本(不自动生成链接)",
-    "tog-uselivepreview": "使用实时预览(测试)",
+    "tog-uselivepreview": "使用实时预览(试验中)",
     "tog-forceeditsummary": "未输入编辑摘要时提醒我",
     "tog-watchlisthideown": "隐藏监视列表中的我的编辑",
     "tog-watchlisthidebots": "隐藏监视列表中的机器人编辑",
     "edit": "编辑",
     "edit-local": "编辑本地说明",
     "create": "创建",
-    "create-local": "加入本地说明",
+    "create-local": "添加本地说明",
     "editthispage": "编辑本页",
     "create-this-page": "创建本页",
     "delete": "删除",
     "perfcachedts": "以下是缓存的数据,最后更新于$1。缓存中最多有{{PLURAL:$4|$4条结果}}。",
     "querypage-no-updates": "该页面的更新目前停用。这里的数据不会马上刷新。",
     "viewsource": "查看源代码",
-    "viewsource-title": "查看$1的源代码",
+    "viewsource-title": "查看“$1”的源代码",
     "actionthrottled": "操作被限制",
     "actionthrottledtext": "基于反垃圾的考量,您被限制在短时间内多次重复该操作,但您已超过此上限。请在数分钟后再尝试。",
     "protectedpagetext": "该页面已被保护以防止编辑和其他操作。",
     "viewsourcetext": "您可以查看并复制此页面的源代码:",
-    "viewyourtext": "您可以查看并复制'''您对此页面作出编辑后'''的源代码:",
+    "viewyourtext": "您可以查看并复制<strong>您对此页面作出编辑后</strong>的源代码:",
     "protectedinterface": "该页提供此wiki软件的界面文字,它已被保护以防止恶意修改。\n如欲修改所有wiki的翻译,请到[//translatewiki.net/ translatewiki.net]上的MediaWiki本地化计划。",
     "editinginterface": "'''警告:'''您正在编辑的页面是用于提供软件的界面文字。\n改变此页将影响其他在此wiki上的用户界面外观。\n如欲修改所有wiki的翻译,请到[//translatewiki.net/ translatewiki.net]上的MediaWiki本地化计划。",
     "cascadeprotected": "此页面已被保护,因为这个页面被以下已标注“联锁保护”的{{PLURAL:$1|一个|多个}}被保护页面包含:\n$2",
     "createacct-email-ph": "请输入你的电子邮件地址",
     "createacct-another-email-ph": "输入电子邮件地址",
     "createaccountmail": "使用一个临时的随机密码并将其发送到指定的电子邮件地址中",
-    "createacct-realname": "真实姓名 (可选)",
+    "createacct-realname": "真实姓名(可选)",
     "createaccountreason": "原因:",
     "createacct-reason": "原因",
     "createacct-reason-ph": "你为什么要创建另一个账户",
     "createacct-submit": "创建你的账户",
     "createacct-another-submit": "创建另一个账户",
     "createacct-benefit-heading": "{{SITENAME}}是由同你一样的人们构筑的。",
-    "createacct-benefit-body1": "{{PLURAL:$1|编辑}}",
-    "createacct-benefit-body2": "$1个页面",
-    "createacct-benefit-body3": "最近{{PLURAL:$1|贡献者}}",
+    "createacct-benefit-body1": "{{PLURAL:$1|编辑}}",
+    "createacct-benefit-body2": "{{PLURAL:$1|页面}}",
+    "createacct-benefit-body3": "最近{{PLURAL:$1|贡献者}}",
     "badretype": "您所输入的密码并不相同。",
     "userexists": "用户名已存在。请使用其他名称。",
     "loginerror": "登录错误",
     "password-login-forbidden": "这个用户名称及密码的使用是被禁止的。",
     "mailmypassword": "重置密码",
     "passwordremindertitle": "{{SITENAME}}的新临时密码",
-    "passwordremindertext": "有人(可能是您,来自IP地址$1)已请求{{SITENAME}}的新密码($4)。\n用户“$2”的一个新临时密码现在已被设置好为“$3”。\n如果这个动作是您所指示的,您便需要立即登录并选择一个新的密码。\n您的临时密码会于$5天内过期。\n\n如果是其他人发出了该请求,或者您已经记起了您的密码并不准备改变它,\n您可以忽略此消息并继续使用您的旧密码。",
+    "passwordremindertext": "有人(可能是您,来自IP地址$1)已请求{{SITENAME}}的新密码($4)。\n用户“$2”的一个新临时密码现在已被设置好为“$3”。\n如果这个动作是您所指示的,您便需要立即登录并选择一个新的密码。\n您的临时密码会于$5天内过期。\n\n如果是其他人发出了该请求,或者您已经记起了您的密码并不准备改变它,您可以忽略此消息并继续使用您的旧密码。",
     "noemail": "用户\"$1\"没有登记电子邮件地址。",
     "noemailcreate": "您需要提供一个有效的电子邮件地址",
     "passwordsent": "用户\"$1\"的新密码已经寄往所登记的电子邮件地址。\n请在收到后再登录。",
     "resetpass-recycled": "请重置您的密码为与当前密码不同的密码。",
     "resetpass-temp-emailed": "您通过一个暂时电子邮件发送的代码登录。要完成登录,您必须在此设置一个新密码:",
     "resetpass-temp-password": "临时密码:",
-    "resetpass-abort-generic": "密码更改已被一个扩展插件中止。",
+    "resetpass-abort-generic": "密码更改已经被扩展程序中止。",
     "resetpass-expired": "您的密码已经过期。请设置一个新的密码登录。",
     "resetpass-expired-soft": "您的密码已过期并且需要重置。请现在选择一个新密码,或单击“{{int:resetpass-submit-cancel}}”以便稍后重置。",
     "resetpass-validity-soft": "您的密码无效:$1\n请选择一个新密码,或单击“{{int:resetpass-submit-cancel}}”以稍后重置。",
     "noarticletext-nopermission": "本页面目前没有内容。你可以在其他页面中[[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}}}} 删除日志]中找到。",
     "userpage-userdoesnotexist": "用户账户“$1”没有注册。请在创建/编辑本页前检查。",
-    "userpage-userdoesnotexist-view": "ç\94¨æ\88·è´¦æ\88·â\80\9c$1â\80\9dæ\9cªæ\9b¾å\88\9b建。",
+    "userpage-userdoesnotexist-view": "ç\94¨æ\88·è´¦æ\88·â\80\9c$1â\80\9d没æ\9c\89被注å\86\8c。",
     "blocked-notice-logextract": "这位用户目前已被封禁。以下提供最近的封禁日志以供参考:",
     "clearyourcache": "'''注意:'''在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。\n* '''Firefox/Safari:'''按住“Shift”的同时单击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)\n* '''Google Chrome:'''按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)\n* '''Internet Explorer:'''按住“Ctrl”的同时单击“刷新”,或按“Ctrl-F5”\n* '''Opera:'''在“工具→首选项”中清除缓存",
     "usercssyoucanpreview": "'''提示:''' 在保存前请用“{{int:showpreview}}”按钮来测试您新的 CSS 。",
     "content-model-javascript": "JavaScript",
     "content-model-css": "CSS",
     "expensive-parserfunction-warning": "警告:这个页面有太多高昂的语法功能调用。\n\n它应该少过$2次呼叫,现在有$1次呼叫。",
-    "expensive-parserfunction-category": "页面中有太多耗费的语法功能呼叫",
+    "expensive-parserfunction-category": "有过多昂贵解析器函数调用的页面",
     "post-expand-template-inclusion-warning": "'''警告:'''包含模板大小过大。\n一些模板将不会包含。",
-    "post-expand-template-inclusion-category": "模板包含上限已经超过的页面",
+    "post-expand-template-inclusion-category": "模板包含大小超限的页面",
     "post-expand-template-argument-warning": "'''警告:'''本页面包含至少一个模板参数有过大扩展大小。这些参数会被略过。",
-    "post-expand-template-argument-category": "å\8c\85å\90«ç\9d\80略过模板参数的页面",
+    "post-expand-template-argument-category": "å\90«æ\9c\89略过模板参数的页面",
     "parser-template-loop-warning": "检查到模板循环:[[$1]]",
     "parser-template-recursion-depth-warning": "模板递归深度越限($1)",
     "language-converter-depth-warning": "字词转换器深度越限($1)",
     "showhideselectedversions": "显示/隐藏选择的版本",
     "editundo": "撤销",
     "diff-empty": "(没有差异)",
-    "diff-multi-sameuser": "(相同用户的{{PLURAL:$1|一个|$1个}}中间修订版本未显示)",
-    "diff-multi-otherusers": "({{PLURAL:$1|某位用户|$2位用户}}的{{PLURAL:$1|一个|$1个}}中间修订版本未显示)",
+    "diff-multi-sameuser": "(未显示同一用户的{{PLURAL:$1|$1个中间版本}})",
+    "diff-multi-otherusers": "(未显示{{PLURAL:$1|另一用户|$2个用户}}的{{PLURAL:$1|$1个中间版本}})",
     "diff-multi-manyusers": "(未显示超过$2个用户的$1个中间版本)",
     "difference-missing-revision": "此差异对比的{{PLURAL:$2|一个修订|$2个修订}}($1){{PLURAL:$2|没有}}找到。\n\n这通常是因为进入了一个已被删除的页面的修订差异对比链接。\n详细信息可以在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中找到。",
     "searchresults": "搜索结果",
     "prefs-skin": "皮肤",
     "skin-preview": "预览",
     "datedefault": "默认格式",
-    "prefs-datetime": "日期时间",
     "prefs-labs": "实验室特性",
     "prefs-user-pages": "用户页",
     "prefs-personal": "用户资料",
     "filename-tooshort": "文件名过短。",
     "filetype-banned": "此类文件被禁止。",
     "verification-error": "文件未通过验证。",
-    "hookaborted": "您所尝试的修改被一个扩展程序终止。",
+    "hookaborted": "你尝试的修改被扩展程序中止。",
     "illegal-filename": "文件名非法。",
     "overwrite": "不允许覆盖现有文件。",
     "unknown-error": "发生未知错误。",
     "protect-summary-cascade": "联锁",
     "protect-expiring": "终止于$1(UTC)",
     "protect-expiring-local": "$1到期",
-    "protect-expiry-indefinite": "限期",
+    "protect-expiry-indefinite": "限期",
     "protect-cascade": "保护本页中包含的页面(连锁保护)",
     "protect-cantedit": "您无法更改这个页面的保护等级,因为您没有权限去编辑它。",
     "protect-othertime": "其它时间:",
     "contributions-title": "$1的用户贡献",
     "mycontris": "贡献",
     "contribsub2": "{{GENDER:$3|$1}}的贡献($2)",
+    "contributions-userdoesnotexist": "用户“$1”尚未注册。",
     "nocontribs": "没有找到符合特征的更改。",
     "uctop": "(当前)",
     "month": "截止月份:",
     "ipblocklist-submit": "搜索",
     "ipblocklist-localblock": "本地封禁",
     "ipblocklist-otherblocks": "其他{{PLURAL:$1|封禁}}",
-    "infiniteblock": "限期",
+    "infiniteblock": "限期",
     "expiringblock": "$1 $2到期",
     "anononlyblock": "仅匿名用户",
     "noautoblockblock": "自动封禁停用",
     "watchlistall2": "所有",
     "namespacesall": "所有",
     "monthsall": "所有",
-    "confirmemail": "确认邮箱地址",
+    "confirmemail": "确认电子邮件地址",
     "confirmemail_noemail": "你还没有在你的[[Special:Preferences|系统设置]]中设置有效的电子邮件地址。",
     "confirmemail_text": "{{SITENAME}}要求您在使用邮件功能之前验证您的邮箱地址。\n点击以下按钮可向您的邮箱发送一封确认邮件。该邮件包含有一行代码链接;\n请在您的浏览器中加载此链接以确认您的邮箱地址是有效的。",
     "confirmemail_pending": "一个确认码已经被发送到您的邮箱,您可能需要等几分钟才能收到。如果无法收到,请再申请一个新的确认码。",
     "watchlisttools-edit": "查看并编辑监视列表",
     "watchlisttools-raw": "编辑原始监视列表",
     "signature": "[[{{ns:user}}:$1|$2]]([[{{ns:user_talk}}:$1|讨论]])",
-    "unknown_extension_tag": "不明的扩展标签“$1”",
+    "unknown_extension_tag": "未知扩展标签“$1”",
     "duplicate-defaultsort": "'''警告:'''默认排序关键词“$2”覆盖了之前的默认排序关键词“$1”。",
     "version": "版本",
-    "version-extensions": "å·²å®\89è£\85ç\9a\84æ\89©å±\95ç¨\8båº\8f",
+    "version-extensions": "安装的扩展程序",
     "version-specialpages": "特殊页面",
     "version-parserhooks": "解析器钩",
     "version-variables": "变量",
     "version-version": "(版本 $1)",
     "version-license": "MediaWiki协议",
     "version-ext-license": "许可协议",
-    "version-ext-colheader-name": "扩展",
+    "version-ext-colheader-name": "扩展程序",
     "version-ext-colheader-version": "版本",
     "version-ext-colheader-license": "许可协议",
     "version-ext-colheader-description": "说明",
     "version-poweredby-translators": "translatewiki.net上的翻译者",
     "version-credits-summary": "我们感谢下列人士为[[Special:Version|MediaWiki]]作出的贡献。",
     "version-license-info": "MediaWiki是自由软件,你可以依据自由软件基金会发行的'''GNU公众授权协议'''第2版或任意后续版本的条款,传播和/或修改本软件。\n\nMediaWiki发表时预期有用,但对此'''无任何保证''',亦无隐含的'''可以销售'''或'''适合特定目的'''的保证。详情请见GNU公众授权协议。\n\n你应该已经接受本程序附带的[{{SERVER}}{{SCRIPTPATH}}/COPYING GNU公众授权协议的副本]。如果没有,请写信至美国马萨诸塞州波士顿富兰克林大街51号5楼自由软件基金会,邮编MA 02110-1301(Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA),或[//www.gnu.org/licenses/old-licenses/gpl-2.0.html 在线阅读该协议]。",
-    "version-software": "å·²å®\89è£\85ç\9a\84软件",
+    "version-software": "安装的软件",
     "version-software-product": "产品",
     "version-software-version": "版本",
     "version-entrypoints": "接入点URL",
index 161a3d1..f3199db 100644 (file)
     "prefs-skin": "外觀",
     "skin-preview": "預覽",
     "datedefault": "預設值",
-    "prefs-datetime": "日期和時間",
     "prefs-labs": "實驗中的功能",
     "prefs-user-pages": "使用者頁面",
     "prefs-personal": "使用者概況表",
     "unwatchthispage": "停止監視",
     "notanarticle": "不是頁面",
     "notvisiblerev": "上次由不同用戶所作的修訂版本已經刪除",
-    "watchlist-details": "不包含討論頁,您的監視列表上有 $1 個頁面。",
+    "watchlist-details": "不包含討論頁,您的監視列表上有$1個頁面。",
     "wlheader-enotif": "已經啟動電子郵件通知功能。",
     "wlheader-showupdated": "在{{GENDER:|你|妳|你}}上次檢視後有被修改過的頁面會顯示為'''粗體'''。",
     "watchmethod-recent": "檢查被監視頁面的最近編輯",
     "contributions-title": "$1 的使用者貢獻",
     "mycontris": "我的貢獻",
     "contribsub2": "{{GENDER:$3|$1}} 的貢獻 ($2)",
+    "contributions-userdoesnotexist": "用戶賬戶「$1」未曾註冊。",
     "nocontribs": "沒有找到符合特徵的更改。",
     "uctop": "(最新修改)",
     "month": "截止月份:",
diff --git a/maintenance/jsduck/CustomTags.rb b/maintenance/jsduck/CustomTags.rb
new file mode 100644 (file)
index 0000000..2aff988
--- /dev/null
@@ -0,0 +1,116 @@
+# Custom tags for JSDuck 5.x
+# See also:
+# - https://github.com/senchalabs/jsduck/wiki/Tags
+# - https://github.com/senchalabs/jsduck/wiki/Custom-tags
+# - https://github.com/senchalabs/jsduck/wiki/Custom-tags/7f5c32e568eab9edc8e3365e935bcb836cb11f1d
+require 'jsduck/tag/tag'
+
+class CommonTag < JsDuck::Tag::Tag
+  def initialize
+    @html_position = POS_DOC + 0.1
+    @repeatable = true
+  end
+
+  def parse_doc(scanner, position)
+    if @multiline
+      return { :tagname => @tagname, :doc => :multiline }
+    else
+      text = scanner.match(/.*$/)
+      return { :tagname => @tagname, :doc => text }
+    end
+  end
+
+  def process_doc(context, tags, position)
+    context[@tagname] = tags
+  end
+
+  def format(context, formatter)
+    context[@tagname].each do |tag|
+      tag[:doc] = formatter.format(tag[:doc])
+    end
+  end
+end
+
+class SourceTag < CommonTag
+  def initialize
+    @tagname = :source
+    @pattern = "source"
+    super
+  end
+
+  def to_html(context)
+    context[@tagname].map do |source|
+      <<-EOHTML
+        <h3 class='pa'>Source</h3>
+        #{source[:doc]}
+      EOHTML
+    end.join
+  end
+end
+
+class SeeTag < CommonTag
+  def initialize
+    @tagname = :see
+    @pattern = "see"
+    super
+  end
+
+  def format(context, formatter)
+    position = context[:files][0]
+    context[@tagname].each do |tag|
+      tag[:doc] = '<li>' + render_long_see(tag[:doc], formatter, position) + '</li>'
+    end
+  end
+
+  def to_html(context)
+    <<-EOHTML
+      <h3 class="pa">Related</h3>
+      <ul>
+      #{ context[@tagname].map {|tag| tag[:doc] }.join("\n") }
+      </ul>
+    EOHTML
+  end
+
+  def render_long_see(tag, formatter, position)
+    if tag =~ /\A([^\s]+)( .*)?\Z/m
+      name = $1
+      doc = $2 ? ': ' + $2 : ''
+      return formatter.format("{@link #{name}} #{doc}")
+    else
+      JsDuck::Logger.warn(nil, 'Unexpected @see argument: "'+tag+'"', position)
+      return tag
+    end
+  end
+end
+
+class ContextTag < CommonTag
+  def initialize
+    @tagname = :context
+    @pattern = 'context'
+    super
+  end
+
+  def format(context, formatter)
+    position = context[:files][0]
+    context[@tagname].each do |tag|
+      tag[:doc] = render_long_context(tag[:doc], formatter, position)
+    end
+  end
+
+  def to_html(context)
+    <<-EOHTML
+      <h3 class="pa">Context</h3>
+      #{ context[@tagname].last[:doc] }
+    EOHTML
+  end
+
+  def render_long_context(tag, formatter, position)
+    if tag =~ /\A([^\s]+)/m
+      name = $1
+      return formatter.format("`context` : {@link #{name}}")
+    else
+      JsDuck::Logger.warn(nil, 'Unexpected @context argument: "'+tag+'"', position)
+      return tag
+    end
+  end
+end
index 0635769..493815e 100644 (file)
@@ -2,9 +2,7 @@
        "--title": "MediaWiki core - Documentation",
        "--footer": "Documentation for MediaWiki core. Generated on {DATE} by {JSDUCK} {VERSION}.",
        "--categories": "./categories.json",
-       "--meta-tags": "./MetaTags.rb",
        "--eg-iframe": "./eg-iframe.html",
-       "--warnings": ["-no_doc"],
        "--builtin-classes": true,
        "--output": "../../docs/js",
        "--external": "HTMLElement,HTMLDocument,Window",
index 4254887..62d1bba 100755 (executable)
@@ -11,10 +11,20 @@ then
        exit 1
 fi
 
+# Support jsduck 4.x and 5.x
+JSDUCK_VERSION="$(jsduck --version | sed -e 's/[.].*//')"
+if [  "$JSDUCK_VERSION" = "JSDuck 4" ]; then
+       JSDUCK_VERSION_OPT="--meta-tags ./maintenance/jsduck/MetaTags.rb --warnings=-no_doc"
+else
+       JSDUCK_VERSION_OPT="--tags ./maintenance/jsduck/CustomTags.rb --warnings=-nodoc(class,public)"
+fi
+
 MWCORE_DIR=$(cd $(dirname $0)/..; pwd)
 
 jsduck \
 --config=$MWCORE_DIR/maintenance/jsduck/config.json \
---footer="Documentation for MediaWiki core ($JSDUCK_MWVERSION). Generated on {DATE} by {JSDUCK} {VERSION}." \
+$JSDUCK_VERSION_OPT \
+--footer="Documentation for branch ($JSDUCK_MWVERSION) on {DATE} by {JSDUCK} {VERSION}." \
+--processes 0 --warnings-exit-nonzero \
 && echo 'JSDuck execution finished.' \
 && ln -s ../../resources $MWCORE_DIR/docs/js/modules
index 642897c..cea012a 100644 (file)
@@ -236,9 +236,6 @@ return array(
                'scripts' => 'resources/lib/jquery/jquery.cookie.js',
                'targets' => array( 'desktop', 'mobile' ),
        ),
-       'jquery.delayedBind' => array(
-               'scripts' => 'resources/src/jquery/jquery.delayedBind.js',
-       ),
        'jquery.expandableField' => array(
                'scripts' => 'resources/src/jquery/jquery.expandableField.js',
        ),
index d7fc0c8..93026e3 100644 (file)
@@ -1,11 +1,12 @@
-/**
- * QUnit v1.11.0 - A JavaScript Unit Testing Framework
+/*!
+ * QUnit 1.14.0
+ * http://qunitjs.com/
  *
- * http://qunitjs.com
- *
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license.
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license
  * http://jquery.org/license
+ *
+ * Date: 2014-01-31T16:40Z
  */
 
 /** Font Family and Sizes */
 #qunit-header {
        padding: 0.5em 0 0.5em 1em;
 
-       color: #8699a4;
-       background-color: #0d3349;
+       color: #8699A4;
+       background-color: #0D3349;
 
        font-size: 1.5em;
        line-height: 1em;
-       font-weight: normal;
+       font-weight: 400;
 
        border-radius: 5px 5px 0 0;
-       -moz-border-radius: 5px 5px 0 0;
-       -webkit-border-top-right-radius: 5px;
-       -webkit-border-top-left-radius: 5px;
 }
 
 #qunit-header a {
        text-decoration: none;
-       color: #c2ccd1;
+       color: #C2CCD1;
 }
 
 #qunit-header a:hover,
 #qunit-header a:focus {
-       color: #fff;
+       color: #FFF;
 }
 
 #qunit-testrunner-toolbar label {
        display: inline-block;
-       padding: 0 .5em 0 .1em;
+       padding: 0 0.5em 0 0.1em;
 }
 
 #qunit-banner {
 #qunit-testrunner-toolbar {
        padding: 0.5em 0 0.5em 2em;
        color: #5E740B;
-       background-color: #eee;
+       background-color: #EEE;
        overflow: hidden;
 }
 
 #qunit-userAgent {
        padding: 0.5em 0 0.5em 2.5em;
-       background-color: #2b81af;
-       color: #fff;
+       background-color: #2B81AF;
+       color: #FFF;
        text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
 }
 
@@ -89,7 +87,7 @@
 
 #qunit-tests li {
        padding: 0.4em 0.5em 0.4em 2.5em;
-       border-bottom: 1px solid #fff;
+       border-bottom: 1px solid #FFF;
        list-style-position: inside;
 }
 
 
 #qunit-tests li a {
        padding: 0.5em;
-       color: #c2ccd1;
+       color: #C2CCD1;
        text-decoration: none;
 }
 #qunit-tests li a:hover,
        margin-top: 0.5em;
        padding: 0.5em;
 
-       background-color: #fff;
+       background-color: #FFF;
 
        border-radius: 5px;
-       -moz-border-radius: 5px;
-       -webkit-border-radius: 5px;
 }
 
 .qunit-collapsed {
 
 #qunit-tests table {
        border-collapse: collapse;
-       margin-top: .2em;
+       margin-top: 0.2em;
 }
 
 #qunit-tests th {
        text-align: right;
        vertical-align: top;
-       padding: 0 .5em 0 0;
+       padding: 0 0.5em 0 0;
 }
 
 #qunit-tests td {
 }
 
 #qunit-tests del {
-       background-color: #e0f2be;
-       color: #374e0c;
+       background-color: #E0F2BE;
+       color: #374E0C;
        text-decoration: none;
 }
 
 #qunit-tests ins {
-       background-color: #ffcaca;
+       background-color: #FFCACA;
        color: #500;
        text-decoration: none;
 }
 
 /*** Test Counts */
 
-#qunit-tests b.counts                       { color: black; }
+#qunit-tests b.counts                       { color: #000; }
 #qunit-tests b.passed                       { color: #5E740B; }
 #qunit-tests b.failed                       { color: #710909; }
 
 #qunit-tests li li {
        padding: 5px;
-       background-color: #fff;
+       background-color: #FFF;
        border-bottom: none;
        list-style-position: inside;
 }
 /*** Passing Styles */
 
 #qunit-tests li li.pass {
-       color: #3c510c;
-       background-color: #fff;
+       color: #3C510C;
+       background-color: #FFF;
        border-left: 10px solid #C6E746;
 }
 
 #qunit-tests .pass .test-name               { color: #366097; }
 
 #qunit-tests .pass .test-actual,
-#qunit-tests .pass .test-expected           { color: #999999; }
+#qunit-tests .pass .test-expected           { color: #999; }
 
 #qunit-banner.qunit-pass                    { background-color: #C6E746; }
 
 
 #qunit-tests li li.fail {
        color: #710909;
-       background-color: #fff;
+       background-color: #FFF;
        border-left: 10px solid #EE5757;
        white-space: pre;
 }
 
 #qunit-tests > li:last-child {
        border-radius: 0 0 5px 5px;
-       -moz-border-radius: 0 0 5px 5px;
-       -webkit-border-bottom-right-radius: 5px;
-       -webkit-border-bottom-left-radius: 5px;
 }
 
-#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail                          { color: #000; background-color: #EE5757; }
 #qunit-tests .fail .test-name,
-#qunit-tests .fail .module-name             { color: #000000; }
+#qunit-tests .fail .module-name             { color: #000; }
 
 #qunit-tests .fail .test-actual             { color: #EE5757; }
-#qunit-tests .fail .test-expected           { color: green;   }
+#qunit-tests .fail .test-expected           { color: #008000; }
 
 #qunit-banner.qunit-fail                    { background-color: #EE5757; }
 
 #qunit-testresult {
        padding: 0.5em 0.5em 0.5em 2.5em;
 
-       color: #2b81af;
+       color: #2B81AF;
        background-color: #D2E0E6;
 
-       border-bottom: 1px solid white;
+       border-bottom: 1px solid #FFF;
 }
 #qunit-testresult .module-name {
-       font-weight: bold;
+       font-weight: 700;
 }
 
 /** Fixture */
index 302545f..0e279fd 100644 (file)
@@ -1,11 +1,12 @@
-/**
- * QUnit v1.11.0 - A JavaScript Unit Testing Framework
- *
- * http://qunitjs.com
+/*!
+ * QUnit 1.14.0
+ * http://qunitjs.com/
  *
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license.
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license
  * http://jquery.org/license
+ *
+ * Date: 2014-01-31T16:40Z
  */
 
 (function( window ) {
@@ -20,7 +21,10 @@ var QUnit,
        hasOwn = Object.prototype.hasOwnProperty,
        // Keep a local reference to Date (GH-283)
        Date = window.Date,
+       setTimeout = window.setTimeout,
+       clearTimeout = window.clearTimeout,
        defined = {
+               document: typeof window.document !== "undefined",
                setTimeout: typeof window.setTimeout !== "undefined",
                sessionStorage: (function() {
                        var x = "qunit-test-string";
@@ -83,1485 +87,1601 @@ var QUnit,
                return vals;
        };
 
-function Test( settings ) {
-       extend( this, settings );
-       this.assertions = [];
-       this.testNumber = ++Test.count;
-}
 
-Test.count = 0;
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
 
-Test.prototype = {
-       init: function() {
-               var a, b, li,
-                       tests = id( "qunit-tests" );
+       // call on start of module test to prepend name to all tests
+       module: function( name, testEnvironment ) {
+               config.currentModule = name;
+               config.currentModuleTestEnvironment = testEnvironment;
+               config.modules[name] = true;
+       },
 
-               if ( tests ) {
-                       b = document.createElement( "strong" );
-                       b.innerHTML = this.nameHtml;
+       asyncTest: function( testName, expected, callback ) {
+               if ( arguments.length === 2 ) {
+                       callback = expected;
+                       expected = null;
+               }
 
-                       // `a` initialized at top of scope
-                       a = document.createElement( "a" );
-                       a.innerHTML = "Rerun";
-                       a.href = QUnit.url({ testNumber: this.testNumber });
+               QUnit.test( testName, expected, callback, true );
+       },
 
-                       li = document.createElement( "li" );
-                       li.appendChild( b );
-                       li.appendChild( a );
-                       li.className = "running";
-                       li.id = this.id = "qunit-test-output" + testId++;
+       test: function( testName, expected, callback, async ) {
+               var test,
+                       nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
 
-                       tests.appendChild( li );
-               }
-       },
-       setup: function() {
-               if ( this.module !== config.previousModule ) {
-                       if ( config.previousModule ) {
-                               runLoggingCallbacks( "moduleDone", QUnit, {
-                                       name: config.previousModule,
-                                       failed: config.moduleStats.bad,
-                                       passed: config.moduleStats.all - config.moduleStats.bad,
-                                       total: config.moduleStats.all
-                               });
-                       }
-                       config.previousModule = this.module;
-                       config.moduleStats = { all: 0, bad: 0 };
-                       runLoggingCallbacks( "moduleStart", QUnit, {
-                               name: this.module
-                       });
-               } else if ( config.autorun ) {
-                       runLoggingCallbacks( "moduleStart", QUnit, {
-                               name: this.module
-                       });
+               if ( arguments.length === 2 ) {
+                       callback = expected;
+                       expected = null;
                }
 
-               config.current = this;
-
-               this.testEnvironment = extend({
-                       setup: function() {},
-                       teardown: function() {}
-               }, this.moduleTestEnvironment );
+               if ( config.currentModule ) {
+                       nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+               }
 
-               this.started = +new Date();
-               runLoggingCallbacks( "testStart", QUnit, {
-                       name: this.testName,
-                       module: this.module
+               test = new Test({
+                       nameHtml: nameHtml,
+                       testName: testName,
+                       expected: expected,
+                       async: async,
+                       callback: callback,
+                       module: config.currentModule,
+                       moduleTestEnvironment: config.currentModuleTestEnvironment,
+                       stack: sourceFromStacktrace( 2 )
                });
 
-               // allow utility functions to access the current test environment
-               // TODO why??
-               QUnit.current_testEnvironment = this.testEnvironment;
-
-               if ( !config.pollution ) {
-                       saveGlobal();
-               }
-               if ( config.notrycatch ) {
-                       this.testEnvironment.setup.call( this.testEnvironment );
+               if ( !validTest( test ) ) {
                        return;
                }
-               try {
-                       this.testEnvironment.setup.call( this.testEnvironment );
-               } catch( e ) {
-                       QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
-               }
-       },
-       run: function() {
-               config.current = this;
-
-               var running = id( "qunit-testresult" );
 
-               if ( running ) {
-                       running.innerHTML = "Running: <br/>" + this.nameHtml;
-               }
+               test.queue();
+       },
 
-               if ( this.async ) {
-                       QUnit.stop();
+       // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
+       expect: function( asserts ) {
+               if (arguments.length === 1) {
+                       config.current.expected = asserts;
+               } else {
+                       return config.current.expected;
                }
+       },
 
-               this.callbackStarted = +new Date();
-
-               if ( config.notrycatch ) {
-                       this.callback.call( this.testEnvironment, QUnit.assert );
-                       this.callbackRuntime = +new Date() - this.callbackStarted;
+       start: function( count ) {
+               // QUnit hasn't been initialized yet.
+               // Note: RequireJS (et al) may delay onLoad
+               if ( config.semaphore === undefined ) {
+                       QUnit.begin(function() {
+                               // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+                               setTimeout(function() {
+                                       QUnit.start( count );
+                               });
+                       });
                        return;
                }
 
-               try {
-                       this.callback.call( this.testEnvironment, QUnit.assert );
-                       this.callbackRuntime = +new Date() - this.callbackStarted;
-               } catch( e ) {
-                       this.callbackRuntime = +new Date() - this.callbackStarted;
-
-                       QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
-                       // else next test will carry the responsibility
-                       saveGlobal();
-
-                       // Restart the tests if they're blocking
-                       if ( config.blocking ) {
-                               QUnit.start();
-                       }
+               config.semaphore -= count || 1;
+               // don't start until equal number of stop-calls
+               if ( config.semaphore > 0 ) {
+                       return;
                }
-       },
-       teardown: function() {
-               config.current = this;
-               if ( config.notrycatch ) {
-                       if ( typeof this.callbackRuntime === "undefined" ) {
-                               this.callbackRuntime = +new Date() - this.callbackStarted;
-                       }
-                       this.testEnvironment.teardown.call( this.testEnvironment );
+               // ignore if start is called more often then stop
+               if ( config.semaphore < 0 ) {
+                       config.semaphore = 0;
+                       QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
                        return;
+               }
+               // A slight delay, to avoid any current callbacks
+               if ( defined.setTimeout ) {
+                       setTimeout(function() {
+                               if ( config.semaphore > 0 ) {
+                                       return;
+                               }
+                               if ( config.timeout ) {
+                                       clearTimeout( config.timeout );
+                               }
+
+                               config.blocking = false;
+                               process( true );
+                       }, 13);
                } else {
-                       try {
-                               this.testEnvironment.teardown.call( this.testEnvironment );
-                       } catch( e ) {
-                               QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
-                       }
+                       config.blocking = false;
+                       process( true );
                }
-               checkPollution();
        },
-       finish: function() {
-               config.current = this;
-               if ( config.requireExpects && this.expected === null ) {
-                       QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
-               } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
-                       QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
-               } else if ( this.expected === null && !this.assertions.length ) {
-                       QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+
+       stop: function( count ) {
+               config.semaphore += count || 1;
+               config.blocking = true;
+
+               if ( config.testTimeout && defined.setTimeout ) {
+                       clearTimeout( config.timeout );
+                       config.timeout = setTimeout(function() {
+                               QUnit.ok( false, "Test timed out" );
+                               config.semaphore = 1;
+                               QUnit.start();
+                       }, config.testTimeout );
                }
+       }
+};
 
-               var i, assertion, a, b, time, li, ol,
-                       test = this,
-                       good = 0,
-                       bad = 0,
-                       tests = id( "qunit-tests" );
+// We use the prototype to distinguish between properties that should
+// be exposed as globals (and in exports) and those that shouldn't
+(function() {
+       function F() {}
+       F.prototype = QUnit;
+       QUnit = new F();
+       // Make F QUnit's constructor so that we can add to the prototype later
+       QUnit.constructor = F;
+}());
 
-               this.runtime = +new Date() - this.started;
-               config.stats.all += this.assertions.length;
-               config.moduleStats.all += this.assertions.length;
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+       // The queue of tests to run
+       queue: [],
 
-               if ( tests ) {
-                       ol = document.createElement( "ol" );
-                       ol.className = "qunit-assert-list";
+       // block until document ready
+       blocking: true,
 
-                       for ( i = 0; i < this.assertions.length; i++ ) {
-                               assertion = this.assertions[i];
+       // when enabled, show only failing tests
+       // gets persisted through sessionStorage and can be changed in UI via checkbox
+       hidepassed: false,
 
-                               li = document.createElement( "li" );
-                               li.className = assertion.result ? "pass" : "fail";
-                               li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
-                               ol.appendChild( li );
+       // by default, run previously failed tests first
+       // very useful in combination with "Hide passed tests" checked
+       reorder: true,
 
-                               if ( assertion.result ) {
-                                       good++;
-                               } else {
-                                       bad++;
-                                       config.stats.bad++;
-                                       config.moduleStats.bad++;
-                               }
-                       }
+       // by default, modify document.title when suite is done
+       altertitle: true,
 
-                       // store result when possible
-                       if ( QUnit.config.reorder && defined.sessionStorage ) {
-                               if ( bad ) {
-                                       sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
-                               } else {
-                                       sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
-                               }
-                       }
+       // by default, scroll to top of the page when suite is done
+       scrolltop: true,
 
-                       if ( bad === 0 ) {
-                               addClass( ol, "qunit-collapsed" );
-                       }
+       // when enabled, all tests must call expect()
+       requireExpects: false,
 
-                       // `b` initialized at top of scope
-                       b = document.createElement( "strong" );
-                       b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+       // add checkboxes that are persisted in the query-string
+       // when enabled, the id is set to `true` as a `QUnit.config` property
+       urlConfig: [
+               {
+                       id: "noglobals",
+                       label: "Check for Globals",
+                       tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+               },
+               {
+                       id: "notrycatch",
+                       label: "No try-catch",
+                       tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+               }
+       ],
 
-                       addEvent(b, "click", function() {
-                               var next = b.parentNode.lastChild,
-                                       collapsed = hasClass( next, "qunit-collapsed" );
-                               ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
-                       });
+       // Set of all modules.
+       modules: {},
 
-                       addEvent(b, "dblclick", function( e ) {
-                               var target = e && e.target ? e.target : window.event.srcElement;
-                               if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
-                                       target = target.parentNode;
-                               }
-                               if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
-                                       window.location = QUnit.url({ testNumber: test.testNumber });
-                               }
-                       });
+       // logging callback queues
+       begin: [],
+       done: [],
+       log: [],
+       testStart: [],
+       testDone: [],
+       moduleStart: [],
+       moduleDone: []
+};
 
-                       // `time` initialized at top of scope
-                       time = document.createElement( "span" );
-                       time.className = "runtime";
-                       time.innerHTML = this.runtime + " ms";
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+       var i, current,
+               location = window.location || { search: "", protocol: "file:" },
+               params = location.search.slice( 1 ).split( "&" ),
+               length = params.length,
+               urlParams = {};
 
-                       // `li` initialized at top of scope
-                       li = id( this.id );
-                       li.className = bad ? "fail" : "pass";
-                       li.removeChild( li.firstChild );
-                       a = li.firstChild;
-                       li.appendChild( b );
-                       li.appendChild( a );
-                       li.appendChild( time );
-                       li.appendChild( ol );
+       if ( params[ 0 ] ) {
+               for ( i = 0; i < length; i++ ) {
+                       current = params[ i ].split( "=" );
+                       current[ 0 ] = decodeURIComponent( current[ 0 ] );
 
-               } else {
-                       for ( i = 0; i < this.assertions.length; i++ ) {
-                               if ( !this.assertions[i].result ) {
-                                       bad++;
-                                       config.stats.bad++;
-                                       config.moduleStats.bad++;
-                               }
+                       // allow just a key to turn on a flag, e.g., test.html?noglobals
+                       current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+                       if ( urlParams[ current[ 0 ] ] ) {
+                               urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] );
+                       } else {
+                               urlParams[ current[ 0 ] ] = current[ 1 ];
                        }
                }
+       }
 
-               runLoggingCallbacks( "testDone", QUnit, {
-                       name: this.testName,
-                       module: this.module,
-                       failed: bad,
-                       passed: this.assertions.length - bad,
-                       total: this.assertions.length,
-                       duration: this.runtime
-               });
-
-               QUnit.reset();
-
-               config.current = undefined;
-       },
+       QUnit.urlParams = urlParams;
 
-       queue: function() {
-               var bad,
-                       test = this;
+       // String search anywhere in moduleName+testName
+       config.filter = urlParams.filter;
 
-               synchronize(function() {
-                       test.init();
-               });
-               function run() {
-                       // each of these can by async
-                       synchronize(function() {
-                               test.setup();
-                       });
-                       synchronize(function() {
-                               test.run();
-                       });
-                       synchronize(function() {
-                               test.teardown();
-                       });
-                       synchronize(function() {
-                               test.finish();
-                       });
-               }
+       // Exact match of the module name
+       config.module = urlParams.module;
 
-               // `bad` initialized at top of scope
-               // defer when previous test run passed, if storage is available
-               bad = QUnit.config.reorder && defined.sessionStorage &&
-                                               +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+       config.testNumber = [];
+       if ( urlParams.testNumber ) {
 
-               if ( bad ) {
-                       run();
-               } else {
-                       synchronize( run, true );
+               // Ensure that urlParams.testNumber is an array
+               urlParams.testNumber = [].concat( urlParams.testNumber );
+               for ( i = 0; i < urlParams.testNumber.length; i++ ) {
+                       current = urlParams.testNumber[ i ];
+                       config.testNumber.push( parseInt( current, 10 ) );
                }
        }
-};
 
-// Root QUnit object.
-// `QUnit` initialized at top of scope
-QUnit = {
+       // Figure out if we're running the tests from a server or not
+       QUnit.isLocal = location.protocol === "file:";
+}());
 
-       // call on start of module test to prepend name to all tests
-       module: function( name, testEnvironment ) {
-               config.currentModule = name;
-               config.currentModuleTestEnvironment = testEnvironment;
-               config.modules[name] = true;
-       },
+extend( QUnit, {
 
-       asyncTest: function( testName, expected, callback ) {
-               if ( arguments.length === 2 ) {
-                       callback = expected;
-                       expected = null;
-               }
+       config: config,
 
-               QUnit.test( testName, expected, callback, true );
-       },
+       // Initialize the configuration options
+       init: function() {
+               extend( config, {
+                       stats: { all: 0, bad: 0 },
+                       moduleStats: { all: 0, bad: 0 },
+                       started: +new Date(),
+                       updateRate: 1000,
+                       blocking: false,
+                       autostart: true,
+                       autorun: false,
+                       filter: "",
+                       queue: [],
+                       semaphore: 1
+               });
 
-       test: function( testName, expected, callback, async ) {
-               var test,
-                       nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
+               var tests, banner, result,
+                       qunit = id( "qunit" );
 
-               if ( arguments.length === 2 ) {
-                       callback = expected;
-                       expected = null;
+               if ( qunit ) {
+                       qunit.innerHTML =
+                               "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+                               "<h2 id='qunit-banner'></h2>" +
+                               "<div id='qunit-testrunner-toolbar'></div>" +
+                               "<h2 id='qunit-userAgent'></h2>" +
+                               "<ol id='qunit-tests'></ol>";
                }
 
-               if ( config.currentModule ) {
-                       nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
+               tests = id( "qunit-tests" );
+               banner = id( "qunit-banner" );
+               result = id( "qunit-testresult" );
+
+               if ( tests ) {
+                       tests.innerHTML = "";
                }
 
-               test = new Test({
-                       nameHtml: nameHtml,
-                       testName: testName,
-                       expected: expected,
-                       async: async,
-                       callback: callback,
-                       module: config.currentModule,
-                       moduleTestEnvironment: config.currentModuleTestEnvironment,
-                       stack: sourceFromStacktrace( 2 )
-               });
+               if ( banner ) {
+                       banner.className = "";
+               }
 
-               if ( !validTest( test ) ) {
-                       return;
+               if ( result ) {
+                       result.parentNode.removeChild( result );
                }
 
-               test.queue();
+               if ( tests ) {
+                       result = document.createElement( "p" );
+                       result.id = "qunit-testresult";
+                       result.className = "result";
+                       tests.parentNode.insertBefore( result, tests );
+                       result.innerHTML = "Running...<br/>&nbsp;";
+               }
        },
 
-       // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
-       expect: function( asserts ) {
-               if (arguments.length === 1) {
-                       config.current.expected = asserts;
-               } else {
-                       return config.current.expected;
+       // Resets the test setup. Useful for tests that modify the DOM.
+       /*
+       DEPRECATED: Use multiple tests instead of resetting inside a test.
+       Use testStart or testDone for custom cleanup.
+       This method will throw an error in 2.0, and will be removed in 2.1
+       */
+       reset: function() {
+               var fixture = id( "qunit-fixture" );
+               if ( fixture ) {
+                       fixture.innerHTML = config.fixture;
                }
        },
 
-       start: function( count ) {
-               // QUnit hasn't been initialized yet.
-               // Note: RequireJS (et al) may delay onLoad
-               if ( config.semaphore === undefined ) {
-                       QUnit.begin(function() {
-                               // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
-                               setTimeout(function() {
-                                       QUnit.start( count );
-                               });
-                       });
-                       return;
-               }
+       // Safe object type checking
+       is: function( type, obj ) {
+               return QUnit.objectType( obj ) === type;
+       },
 
-               config.semaphore -= count || 1;
-               // don't start until equal number of stop-calls
-               if ( config.semaphore > 0 ) {
-                       return;
+       objectType: function( obj ) {
+               if ( typeof obj === "undefined" ) {
+                       return "undefined";
                }
-               // ignore if start is called more often then stop
-               if ( config.semaphore < 0 ) {
-                       config.semaphore = 0;
-                       QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
-                       return;
+
+               // Consider: typeof null === object
+               if ( obj === null ) {
+                       return "null";
                }
-               // A slight delay, to avoid any current callbacks
-               if ( defined.setTimeout ) {
-                       window.setTimeout(function() {
-                               if ( config.semaphore > 0 ) {
-                                       return;
-                               }
-                               if ( config.timeout ) {
-                                       clearTimeout( config.timeout );
-                               }
-
-                               config.blocking = false;
-                               process( true );
-                       }, 13);
-               } else {
-                       config.blocking = false;
-                       process( true );
-               }
-       },
 
-       stop: function( count ) {
-               config.semaphore += count || 1;
-               config.blocking = true;
+               var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+                       type = match && match[1] || "";
 
-               if ( config.testTimeout && defined.setTimeout ) {
-                       clearTimeout( config.timeout );
-                       config.timeout = window.setTimeout(function() {
-                               QUnit.ok( false, "Test timed out" );
-                               config.semaphore = 1;
-                               QUnit.start();
-                       }, config.testTimeout );
+               switch ( type ) {
+                       case "Number":
+                               if ( isNaN(obj) ) {
+                                       return "nan";
+                               }
+                               return "number";
+                       case "String":
+                       case "Boolean":
+                       case "Array":
+                       case "Date":
+                       case "RegExp":
+                       case "Function":
+                               return type.toLowerCase();
                }
-       }
-};
+               if ( typeof obj === "object" ) {
+                       return "object";
+               }
+               return undefined;
+       },
 
-// `assert` initialized at top of scope
-// Asssert helpers
-// All of these must either call QUnit.push() or manually do:
-// - runLoggingCallbacks( "log", .. );
-// - config.current.assertions.push({ .. });
-// We attach it to the QUnit object *after* we expose the public API,
-// otherwise `assert` will become a global variable in browsers (#341).
-assert = {
-       /**
-        * Asserts rough true-ish result.
-        * @name ok
-        * @function
-        * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
-        */
-       ok: function( result, msg ) {
+       push: function( result, actual, expected, message ) {
                if ( !config.current ) {
-                       throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+                       throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
                }
-               result = !!result;
 
-               var source,
+               var output, source,
                        details = {
                                module: config.current.module,
                                name: config.current.testName,
                                result: result,
-                               message: msg
+                               message: message,
+                               actual: actual,
+                               expected: expected
                        };
 
-               msg = escapeText( msg || (result ? "okay" : "failed" ) );
-               msg = "<span class='test-message'>" + msg + "</span>";
+               message = escapeText( message ) || ( result ? "okay" : "failed" );
+               message = "<span class='test-message'>" + message + "</span>";
+               output = message;
 
                if ( !result ) {
-                       source = sourceFromStacktrace( 2 );
+                       expected = escapeText( QUnit.jsDump.parse(expected) );
+                       actual = escapeText( QUnit.jsDump.parse(actual) );
+                       output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+
+                       if ( actual !== expected ) {
+                               output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
+                               output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
+                       }
+
+                       source = sourceFromStacktrace();
+
                        if ( source ) {
                                details.source = source;
-                               msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
+                               output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
                        }
+
+                       output += "</table>";
                }
+
                runLoggingCallbacks( "log", QUnit, details );
+
                config.current.assertions.push({
-                       result: result,
-                       message: msg
+                       result: !!result,
+                       message: output
                });
        },
 
-       /**
-        * Assert that the first two arguments are equal, with an optional message.
-        * Prints out both actual and expected values.
-        * @name equal
-        * @function
-        * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
-        */
-       equal: function( actual, expected, message ) {
-               /*jshint eqeqeq:false */
-               QUnit.push( expected == actual, actual, expected, message );
-       },
-
-       /**
-        * @name notEqual
-        * @function
-        */
-       notEqual: function( actual, expected, message ) {
-               /*jshint eqeqeq:false */
-               QUnit.push( expected != actual, actual, expected, message );
-       },
+       pushFailure: function( message, source, actual ) {
+               if ( !config.current ) {
+                       throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+               }
 
-       /**
-        * @name propEqual
-        * @function
-        */
-       propEqual: function( actual, expected, message ) {
-               actual = objectValues(actual);
-               expected = objectValues(expected);
-               QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
-       },
+               var output,
+                       details = {
+                               module: config.current.module,
+                               name: config.current.testName,
+                               result: false,
+                               message: message
+                       };
 
-       /**
-        * @name notPropEqual
-        * @function
-        */
-       notPropEqual: function( actual, expected, message ) {
-               actual = objectValues(actual);
-               expected = objectValues(expected);
-               QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
-       },
+               message = escapeText( message ) || "error";
+               message = "<span class='test-message'>" + message + "</span>";
+               output = message;
 
-       /**
-        * @name deepEqual
-        * @function
-        */
-       deepEqual: function( actual, expected, message ) {
-               QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
-       },
+               output += "<table>";
 
-       /**
-        * @name notDeepEqual
-        * @function
-        */
-       notDeepEqual: function( actual, expected, message ) {
-               QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
-       },
+               if ( actual ) {
+                       output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
+               }
 
-       /**
-        * @name strictEqual
-        * @function
-        */
-       strictEqual: function( actual, expected, message ) {
-               QUnit.push( expected === actual, actual, expected, message );
-       },
+               if ( source ) {
+                       details.source = source;
+                       output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+               }
 
-       /**
-        * @name notStrictEqual
-        * @function
-        */
-       notStrictEqual: function( actual, expected, message ) {
-               QUnit.push( expected !== actual, actual, expected, message );
-       },
+               output += "</table>";
 
-       "throws": function( block, expected, message ) {
-               var actual,
-                       expectedOutput = expected,
-                       ok = false;
+               runLoggingCallbacks( "log", QUnit, details );
 
-               // 'expected' is optional
-               if ( typeof expected === "string" ) {
-                       message = expected;
-                       expected = null;
-               }
+               config.current.assertions.push({
+                       result: false,
+                       message: output
+               });
+       },
 
-               config.current.ignoreGlobalErrors = true;
-               try {
-                       block.call( config.current.testEnvironment );
-               } catch (e) {
-                       actual = e;
-               }
-               config.current.ignoreGlobalErrors = false;
+       url: function( params ) {
+               params = extend( extend( {}, QUnit.urlParams ), params );
+               var key,
+                       querystring = "?";
 
-               if ( actual ) {
-                       // we don't want to validate thrown error
-                       if ( !expected ) {
-                               ok = true;
-                               expectedOutput = null;
-                       // expected is a regexp
-                       } else if ( QUnit.objectType( expected ) === "regexp" ) {
-                               ok = expected.test( errorString( actual ) );
-                       // expected is a constructor
-                       } else if ( actual instanceof expected ) {
-                               ok = true;
-                       // expected is a validation function which returns true is validation passed
-                       } else if ( expected.call( {}, actual ) === true ) {
-                               expectedOutput = null;
-                               ok = true;
+               for ( key in params ) {
+                       if ( hasOwn.call( params, key ) ) {
+                               querystring += encodeURIComponent( key ) + "=" +
+                                       encodeURIComponent( params[ key ] ) + "&";
                        }
-
-                       QUnit.push( ok, actual, expectedOutput, message );
-               } else {
-                       QUnit.pushFailure( message, null, 'No exception was thrown.' );
                }
-       }
-};
+               return window.location.protocol + "//" + window.location.host +
+                       window.location.pathname + querystring.slice( 0, -1 );
+       },
 
-/**
- * @deprecate since 1.8.0
- * Kept assertion helpers in root for backwards compatibility.
- */
-extend( QUnit, assert );
+       extend: extend,
+       id: id,
+       addEvent: addEvent,
+       addClass: addClass,
+       hasClass: hasClass,
+       removeClass: removeClass
+       // load, equiv, jsDump, diff: Attached later
+});
 
 /**
- * @deprecated since 1.9.0
- * Kept root "raises()" for backwards compatibility.
- * (Note that we don't introduce assert.raises).
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
  */
-QUnit.raises = assert[ "throws" ];
+extend( QUnit.constructor.prototype, {
 
-/**
- * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
- * Kept to avoid TypeErrors for undefined methods.
- */
-QUnit.equals = function() {
-       QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
-};
-QUnit.same = function() {
-       QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
-};
+       // Logging callbacks; all receive a single argument with the listed properties
+       // run test/logs.html for any related changes
+       begin: registerLoggingCallback( "begin" ),
 
-// We want access to the constructor's prototype
-(function() {
-       function F() {}
-       F.prototype = QUnit;
-       QUnit = new F();
-       // Make F QUnit's constructor so that we can add to the prototype later
-       QUnit.constructor = F;
-}());
-
-/**
- * Config object: Maintain internal state
- * Later exposed as QUnit.config
- * `config` initialized at top of scope
- */
-config = {
-       // The queue of tests to run
-       queue: [],
+       // done: { failed, passed, total, runtime }
+       done: registerLoggingCallback( "done" ),
 
-       // block until document ready
-       blocking: true,
+       // log: { result, actual, expected, message }
+       log: registerLoggingCallback( "log" ),
 
-       // when enabled, show only failing tests
-       // gets persisted through sessionStorage and can be changed in UI via checkbox
-       hidepassed: false,
+       // testStart: { name }
+       testStart: registerLoggingCallback( "testStart" ),
 
-       // by default, run previously failed tests first
-       // very useful in combination with "Hide passed tests" checked
-       reorder: true,
+       // testDone: { name, failed, passed, total, runtime }
+       testDone: registerLoggingCallback( "testDone" ),
 
-       // by default, modify document.title when suite is done
-       altertitle: true,
+       // moduleStart: { name }
+       moduleStart: registerLoggingCallback( "moduleStart" ),
 
-       // when enabled, all tests must call expect()
-       requireExpects: false,
+       // moduleDone: { name, failed, passed, total }
+       moduleDone: registerLoggingCallback( "moduleDone" )
+});
 
-       // add checkboxes that are persisted in the query-string
-       // when enabled, the id is set to `true` as a `QUnit.config` property
-       urlConfig: [
-               {
-                       id: "noglobals",
-                       label: "Check for Globals",
-                       tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
-               },
-               {
-                       id: "notrycatch",
-                       label: "No try-catch",
-                       tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
-               }
-       ],
+if ( !defined.document || document.readyState === "complete" ) {
+       config.autorun = true;
+}
 
-       // Set of all modules.
-       modules: {},
+QUnit.load = function() {
+       runLoggingCallbacks( "begin", QUnit, {} );
 
-       // logging callback queues
-       begin: [],
-       done: [],
-       log: [],
-       testStart: [],
-       testDone: [],
-       moduleStart: [],
-       moduleDone: []
-};
+       // Initialize the config, saving the execution queue
+       var banner, filter, i, j, label, len, main, ol, toolbar, val, selection,
+               urlConfigContainer, moduleFilter, userAgent,
+               numModules = 0,
+               moduleNames = [],
+               moduleFilterHtml = "",
+               urlConfigHtml = "",
+               oldconfig = extend( {}, config );
 
-// Export global variables, unless an 'exports' object exists,
-// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
-if ( typeof exports === "undefined" ) {
-       extend( window, QUnit );
+       QUnit.init();
+       extend(config, oldconfig);
 
-       // Expose QUnit object
-       window.QUnit = QUnit;
-}
+       config.blocking = false;
 
-// Initialize more QUnit.config and QUnit.urlParams
-(function() {
-       var i,
-               location = window.location || { search: "", protocol: "file:" },
-               params = location.search.slice( 1 ).split( "&" ),
-               length = params.length,
-               urlParams = {},
-               current;
+       len = config.urlConfig.length;
 
-       if ( params[ 0 ] ) {
-               for ( i = 0; i < length; i++ ) {
-                       current = params[ i ].split( "=" );
-                       current[ 0 ] = decodeURIComponent( current[ 0 ] );
-                       // allow just a key to turn on a flag, e.g., test.html?noglobals
-                       current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
-                       urlParams[ current[ 0 ] ] = current[ 1 ];
+       for ( i = 0; i < len; i++ ) {
+               val = config.urlConfig[i];
+               if ( typeof val === "string" ) {
+                       val = {
+                               id: val,
+                               label: val
+                       };
+               }
+               config[ val.id ] = QUnit.urlParams[ val.id ];
+               if ( !val.value || typeof val.value === "string" ) {
+                       urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
+                               "' name='" + escapeText( val.id ) +
+                               "' type='checkbox'" +
+                               ( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
+                               ( config[ val.id ] ? " checked='checked'" : "" ) +
+                               " title='" + escapeText( val.tooltip ) +
+                               "'><label for='qunit-urlconfig-" + escapeText( val.id ) +
+                               "' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
+               } else {
+                       urlConfigHtml += "<label for='qunit-urlconfig-" + escapeText( val.id ) +
+                               "' title='" + escapeText( val.tooltip ) +
+                               "'>" + val.label +
+                               ": </label><select id='qunit-urlconfig-" + escapeText( val.id ) +
+                               "' name='" + escapeText( val.id ) +
+                               "' title='" + escapeText( val.tooltip ) +
+                               "'><option></option>";
+                       selection = false;
+                       if ( QUnit.is( "array", val.value ) ) {
+                               for ( j = 0; j < val.value.length; j++ ) {
+                                       urlConfigHtml += "<option value='" + escapeText( val.value[j] ) + "'" +
+                                               ( config[ val.id ] === val.value[j] ?
+                                                       (selection = true) && " selected='selected'" :
+                                                       "" ) +
+                                               ">" + escapeText( val.value[j] ) + "</option>";
+                               }
+                       } else {
+                               for ( j in val.value ) {
+                                       if ( hasOwn.call( val.value, j ) ) {
+                                               urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
+                                                       ( config[ val.id ] === j ?
+                                                               (selection = true) && " selected='selected'" :
+                                                               "" ) +
+                                                       ">" + escapeText( val.value[j] ) + "</option>";
+                                       }
+                               }
+                       }
+                       if ( config[ val.id ] && !selection ) {
+                               urlConfigHtml += "<option value='" + escapeText( config[ val.id ] ) +
+                                       "' selected='selected' disabled='disabled'>" +
+                                       escapeText( config[ val.id ] ) +
+                                       "</option>";
+                       }
+                       urlConfigHtml += "</select>";
                }
        }
+       for ( i in config.modules ) {
+               if ( config.modules.hasOwnProperty( i ) ) {
+                       moduleNames.push(i);
+               }
+       }
+       numModules = moduleNames.length;
+       moduleNames.sort( function( a, b ) {
+               return a.localeCompare( b );
+       });
+       moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+               ( config.module === undefined  ? "selected='selected'" : "" ) +
+               ">< All Modules ></option>";
 
-       QUnit.urlParams = urlParams;
-
-       // String search anywhere in moduleName+testName
-       config.filter = urlParams.filter;
 
-       // Exact match of the module name
-       config.module = urlParams.module;
+       for ( i = 0; i < numModules; i++) {
+                       moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
+                               ( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
+                               ">" + escapeText(moduleNames[i]) + "</option>";
+       }
+       moduleFilterHtml += "</select>";
 
-       config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
+       // `userAgent` initialized at top of scope
+       userAgent = id( "qunit-userAgent" );
+       if ( userAgent ) {
+               userAgent.innerHTML = navigator.userAgent;
+       }
 
-       // Figure out if we're running the tests from a server or not
-       QUnit.isLocal = location.protocol === "file:";
-}());
+       // `banner` initialized at top of scope
+       banner = id( "qunit-header" );
+       if ( banner ) {
+               banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+       }
 
-// Extend QUnit object,
-// these after set here because they should not be exposed as global functions
-extend( QUnit, {
-       assert: assert,
+       // `toolbar` initialized at top of scope
+       toolbar = id( "qunit-testrunner-toolbar" );
+       if ( toolbar ) {
+               // `filter` initialized at top of scope
+               filter = document.createElement( "input" );
+               filter.type = "checkbox";
+               filter.id = "qunit-filter-pass";
 
-       config: config,
+               addEvent( filter, "click", function() {
+                       var tmp,
+                               ol = id( "qunit-tests" );
 
-       // Initialize the configuration options
-       init: function() {
-               extend( config, {
-                       stats: { all: 0, bad: 0 },
-                       moduleStats: { all: 0, bad: 0 },
-                       started: +new Date(),
-                       updateRate: 1000,
-                       blocking: false,
-                       autostart: true,
-                       autorun: false,
-                       filter: "",
-                       queue: [],
-                       semaphore: 1
+                       if ( filter.checked ) {
+                               ol.className = ol.className + " hidepass";
+                       } else {
+                               tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+                               ol.className = tmp.replace( / hidepass /, " " );
+                       }
+                       if ( defined.sessionStorage ) {
+                               if (filter.checked) {
+                                       sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+                               } else {
+                                       sessionStorage.removeItem( "qunit-filter-passed-tests" );
+                               }
+                       }
                });
 
-               var tests, banner, result,
-                       qunit = id( "qunit" );
-
-               if ( qunit ) {
-                       qunit.innerHTML =
-                               "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
-                               "<h2 id='qunit-banner'></h2>" +
-                               "<div id='qunit-testrunner-toolbar'></div>" +
-                               "<h2 id='qunit-userAgent'></h2>" +
-                               "<ol id='qunit-tests'></ol>";
+               if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+                       filter.checked = true;
+                       // `ol` initialized at top of scope
+                       ol = id( "qunit-tests" );
+                       ol.className = ol.className + " hidepass";
                }
+               toolbar.appendChild( filter );
 
-               tests = id( "qunit-tests" );
-               banner = id( "qunit-banner" );
-               result = id( "qunit-testresult" );
+               // `label` initialized at top of scope
+               label = document.createElement( "label" );
+               label.setAttribute( "for", "qunit-filter-pass" );
+               label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
+               label.innerHTML = "Hide passed tests";
+               toolbar.appendChild( label );
 
-               if ( tests ) {
-                       tests.innerHTML = "";
-               }
+               urlConfigContainer = document.createElement("span");
+               urlConfigContainer.innerHTML = urlConfigHtml;
+               // For oldIE support:
+               // * Add handlers to the individual elements instead of the container
+               // * Use "click" instead of "change" for checkboxes
+               // * Fallback from event.target to event.srcElement
+               addEvents( urlConfigContainer.getElementsByTagName("input"), "click", function( event ) {
+                       var params = {},
+                               target = event.target || event.srcElement;
+                       params[ target.name ] = target.checked ?
+                               target.defaultValue || true :
+                               undefined;
+                       window.location = QUnit.url( params );
+               });
+               addEvents( urlConfigContainer.getElementsByTagName("select"), "change", function( event ) {
+                       var params = {},
+                               target = event.target || event.srcElement;
+                       params[ target.name ] = target.options[ target.selectedIndex ].value || undefined;
+                       window.location = QUnit.url( params );
+               });
+               toolbar.appendChild( urlConfigContainer );
 
-               if ( banner ) {
-                       banner.className = "";
-               }
+               if (numModules > 1) {
+                       moduleFilter = document.createElement( "span" );
+                       moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+                       moduleFilter.innerHTML = moduleFilterHtml;
+                       addEvent( moduleFilter.lastChild, "change", function() {
+                               var selectBox = moduleFilter.getElementsByTagName("select")[0],
+                                       selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
 
-               if ( result ) {
-                       result.parentNode.removeChild( result );
+                               window.location = QUnit.url({
+                                       module: ( selectedModule === "" ) ? undefined : selectedModule,
+                                       // Remove any existing filters
+                                       filter: undefined,
+                                       testNumber: undefined
+                               });
+                       });
+                       toolbar.appendChild(moduleFilter);
                }
+       }
 
-               if ( tests ) {
-                       result = document.createElement( "p" );
-                       result.id = "qunit-testresult";
-                       result.className = "result";
-                       tests.parentNode.insertBefore( result, tests );
-                       result.innerHTML = "Running...<br/>&nbsp;";
-               }
-       },
+       // `main` initialized at top of scope
+       main = id( "qunit-fixture" );
+       if ( main ) {
+               config.fixture = main.innerHTML;
+       }
 
-       // Resets the test setup. Useful for tests that modify the DOM.
-       reset: function() {
-               var fixture = id( "qunit-fixture" );
-               if ( fixture ) {
-                       fixture.innerHTML = config.fixture;
-               }
-       },
+       if ( config.autostart ) {
+               QUnit.start();
+       }
+};
 
-       // Trigger an event on an element.
-       // @example triggerEvent( document.body, "click" );
-       triggerEvent: function( elem, type, event ) {
-               if ( document.createEvent ) {
-                       event = document.createEvent( "MouseEvents" );
-                       event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
-                               0, 0, 0, 0, 0, false, false, false, false, 0, null);
+if ( defined.document ) {
+       addEvent( window, "load", QUnit.load );
+}
 
-                       elem.dispatchEvent( event );
-               } else if ( elem.fireEvent ) {
-                       elem.fireEvent( "on" + type );
-               }
-       },
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
 
-       // Safe object type checking
-       is: function( type, obj ) {
-               return QUnit.objectType( obj ) === type;
-       },
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+       var ret = false;
+       if ( onErrorFnPrev ) {
+               ret = onErrorFnPrev( error, filePath, linerNr );
+       }
 
-       objectType: function( obj ) {
-               if ( typeof obj === "undefined" ) {
-                               return "undefined";
-               // consider: typeof null === object
-               }
-               if ( obj === null ) {
-                               return "null";
+       // Treat return value as window.onerror itself does,
+       // Only do our handling if not suppressed.
+       if ( ret !== true ) {
+               if ( QUnit.config.current ) {
+                       if ( QUnit.config.current.ignoreGlobalErrors ) {
+                               return true;
+                       }
+                       QUnit.pushFailure( error, filePath + ":" + linerNr );
+               } else {
+                       QUnit.test( "global failure", extend( function() {
+                               QUnit.pushFailure( error, filePath + ":" + linerNr );
+                       }, { validTest: validTest } ) );
                }
+               return false;
+       }
 
-               var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
-                       type = match && match[1] || "";
-
-               switch ( type ) {
-                       case "Number":
-                               if ( isNaN(obj) ) {
-                                       return "nan";
-                               }
-                               return "number";
-                       case "String":
-                       case "Boolean":
-                       case "Array":
-                       case "Date":
-                       case "RegExp":
-                       case "Function":
-                               return type.toLowerCase();
-               }
-               if ( typeof obj === "object" ) {
-                       return "object";
-               }
-               return undefined;
-       },
+       return ret;
+};
 
-       push: function( result, actual, expected, message ) {
-               if ( !config.current ) {
-                       throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
-               }
+function done() {
+       config.autorun = true;
 
-               var output, source,
-                       details = {
-                               module: config.current.module,
-                               name: config.current.testName,
-                               result: result,
-                               message: message,
-                               actual: actual,
-                               expected: expected
-                       };
+       // Log the last module results
+       if ( config.previousModule ) {
+               runLoggingCallbacks( "moduleDone", QUnit, {
+                       name: config.previousModule,
+                       failed: config.moduleStats.bad,
+                       passed: config.moduleStats.all - config.moduleStats.bad,
+                       total: config.moduleStats.all
+               });
+       }
+       delete config.previousModule;
 
-               message = escapeText( message ) || ( result ? "okay" : "failed" );
-               message = "<span class='test-message'>" + message + "</span>";
-               output = message;
+       var i, key,
+               banner = id( "qunit-banner" ),
+               tests = id( "qunit-tests" ),
+               runtime = +new Date() - config.started,
+               passed = config.stats.all - config.stats.bad,
+               html = [
+                       "Tests completed in ",
+                       runtime,
+                       " milliseconds.<br/>",
+                       "<span class='passed'>",
+                       passed,
+                       "</span> assertions of <span class='total'>",
+                       config.stats.all,
+                       "</span> passed, <span class='failed'>",
+                       config.stats.bad,
+                       "</span> failed."
+               ].join( "" );
 
-               if ( !result ) {
-                       expected = escapeText( QUnit.jsDump.parse(expected) );
-                       actual = escapeText( QUnit.jsDump.parse(actual) );
-                       output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
+       if ( banner ) {
+               banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+       }
 
-                       if ( actual !== expected ) {
-                               output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
-                               output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
-                       }
+       if ( tests ) {
+               id( "qunit-testresult" ).innerHTML = html;
+       }
 
-                       source = sourceFromStacktrace();
+       if ( config.altertitle && defined.document && document.title ) {
+               // show ✖ for good, ✔ for bad suite result in title
+               // use escape sequences in case file gets loaded with non-utf-8-charset
+               document.title = [
+                       ( config.stats.bad ? "\u2716" : "\u2714" ),
+                       document.title.replace( /^[\u2714\u2716] /i, "" )
+               ].join( " " );
+       }
 
-                       if ( source ) {
-                               details.source = source;
-                               output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
+       // clear own sessionStorage items if all tests passed
+       if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+               // `key` & `i` initialized at top of scope
+               for ( i = 0; i < sessionStorage.length; i++ ) {
+                       key = sessionStorage.key( i++ );
+                       if ( key.indexOf( "qunit-test-" ) === 0 ) {
+                               sessionStorage.removeItem( key );
                        }
-
-                       output += "</table>";
                }
+       }
 
-               runLoggingCallbacks( "log", QUnit, details );
+       // scroll back to top to show results
+       if ( config.scrolltop && window.scrollTo ) {
+               window.scrollTo(0, 0);
+       }
 
-               config.current.assertions.push({
-                       result: !!result,
-                       message: output
-               });
-       },
+       runLoggingCallbacks( "done", QUnit, {
+               failed: config.stats.bad,
+               passed: passed,
+               total: config.stats.all,
+               runtime: runtime
+       });
+}
 
-       pushFailure: function( message, source, actual ) {
-               if ( !config.current ) {
-                       throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
-               }
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+       var include,
+               filter = config.filter && config.filter.toLowerCase(),
+               module = config.module && config.module.toLowerCase(),
+               fullName = ( test.module + ": " + test.testName ).toLowerCase();
 
-               var output,
-                       details = {
-                               module: config.current.module,
-                               name: config.current.testName,
-                               result: false,
-                               message: message
-                       };
+       // Internally-generated tests are always valid
+       if ( test.callback && test.callback.validTest === validTest ) {
+               delete test.callback.validTest;
+               return true;
+       }
 
-               message = escapeText( message ) || "error";
-               message = "<span class='test-message'>" + message + "</span>";
-               output = message;
+       if ( config.testNumber.length > 0 ) {
+               if ( inArray( test.testNumber, config.testNumber ) < 0 ) {
+                       return false;
+               }
+       }
 
-               output += "<table>";
+       if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+               return false;
+       }
 
-               if ( actual ) {
-                       output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
-               }
+       if ( !filter ) {
+               return true;
+       }
 
-               if ( source ) {
-                       details.source = source;
-                       output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
-               }
+       include = filter.charAt( 0 ) !== "!";
+       if ( !include ) {
+               filter = filter.slice( 1 );
+       }
 
-               output += "</table>";
+       // If the filter matches, we need to honour include
+       if ( fullName.indexOf( filter ) !== -1 ) {
+               return include;
+       }
 
-               runLoggingCallbacks( "log", QUnit, details );
+       // Otherwise, do the opposite
+       return !include;
+}
 
-               config.current.assertions.push({
-                       result: false,
-                       message: output
-               });
-       },
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+       offset = offset === undefined ? 3 : offset;
 
-       url: function( params ) {
-               params = extend( extend( {}, QUnit.urlParams ), params );
-               var key,
-                       querystring = "?";
+       var stack, include, i;
 
-               for ( key in params ) {
-                       if ( !hasOwn.call( params, key ) ) {
-                               continue;
+       if ( e.stacktrace ) {
+               // Opera
+               return e.stacktrace.split( "\n" )[ offset + 3 ];
+       } else if ( e.stack ) {
+               // Firefox, Chrome
+               stack = e.stack.split( "\n" );
+               if (/^error$/i.test( stack[0] ) ) {
+                       stack.shift();
+               }
+               if ( fileName ) {
+                       include = [];
+                       for ( i = offset; i < stack.length; i++ ) {
+                               if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+                                       break;
+                               }
+                               include.push( stack[ i ] );
+                       }
+                       if ( include.length ) {
+                               return include.join( "\n" );
                        }
-                       querystring += encodeURIComponent( key ) + "=" +
-                               encodeURIComponent( params[ key ] ) + "&";
                }
-               return window.location.protocol + "//" + window.location.host +
-                       window.location.pathname + querystring.slice( 0, -1 );
-       },
-
-       extend: extend,
-       id: id,
-       addEvent: addEvent
-       // load, equiv, jsDump, diff: Attached later
-});
+               return stack[ offset ];
+       } else if ( e.sourceURL ) {
+               // Safari, PhantomJS
+               // hopefully one day Safari provides actual stacktraces
+               // exclude useless self-reference for generated Error objects
+               if ( /qunit.js$/.test( e.sourceURL ) ) {
+                       return;
+               }
+               // for actual exceptions, this is useful
+               return e.sourceURL + ":" + e.line;
+       }
+}
+function sourceFromStacktrace( offset ) {
+       try {
+               throw new Error();
+       } catch ( e ) {
+               return extractStacktrace( e, offset );
+       }
+}
 
 /**
- * @deprecated: Created for backwards compatibility with test runner that set the hook function
- * into QUnit.{hook}, instead of invoking it and passing the hook function.
- * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
- * Doing this allows us to tell if the following methods have been overwritten on the actual
- * QUnit object.
+ * Escape text for attribute or text content.
  */
-extend( QUnit.constructor.prototype, {
-
-       // Logging callbacks; all receive a single argument with the listed properties
-       // run test/logs.html for any related changes
-       begin: registerLoggingCallback( "begin" ),
-
-       // done: { failed, passed, total, runtime }
-       done: registerLoggingCallback( "done" ),
-
-       // log: { result, actual, expected, message }
-       log: registerLoggingCallback( "log" ),
-
-       // testStart: { name }
-       testStart: registerLoggingCallback( "testStart" ),
-
-       // testDone: { name, failed, passed, total, duration }
-       testDone: registerLoggingCallback( "testDone" ),
-
-       // moduleStart: { name }
-       moduleStart: registerLoggingCallback( "moduleStart" ),
-
-       // moduleDone: { name, failed, passed, total }
-       moduleDone: registerLoggingCallback( "moduleDone" )
-});
-
-if ( typeof document === "undefined" || document.readyState === "complete" ) {
-       config.autorun = true;
+function escapeText( s ) {
+       if ( !s ) {
+               return "";
+       }
+       s = s + "";
+       // Both single quotes and double quotes (for attributes)
+       return s.replace( /['"<>&]/g, function( s ) {
+               switch( s ) {
+                       case "'":
+                               return "&#039;";
+                       case "\"":
+                               return "&quot;";
+                       case "<":
+                               return "&lt;";
+                       case ">":
+                               return "&gt;";
+                       case "&":
+                               return "&amp;";
+               }
+       });
 }
 
-QUnit.load = function() {
-       runLoggingCallbacks( "begin", QUnit, {} );
-
-       // Initialize the config, saving the execution queue
-       var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
-               urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
-               numModules = 0,
-               moduleFilterHtml = "",
-               urlConfigHtml = "",
-               oldconfig = extend( {}, config );
-
-       QUnit.init();
-       extend(config, oldconfig);
+function synchronize( callback, last ) {
+       config.queue.push( callback );
 
-       config.blocking = false;
+       if ( config.autorun && !config.blocking ) {
+               process( last );
+       }
+}
 
-       len = config.urlConfig.length;
+function process( last ) {
+       function next() {
+               process( last );
+       }
+       var start = new Date().getTime();
+       config.depth = config.depth ? config.depth + 1 : 1;
 
-       for ( i = 0; i < len; i++ ) {
-               val = config.urlConfig[i];
-               if ( typeof val === "string" ) {
-                       val = {
-                               id: val,
-                               label: val,
-                               tooltip: "[no tooltip available]"
-                       };
+       while ( config.queue.length && !config.blocking ) {
+               if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+                       config.queue.shift()();
+               } else {
+                       setTimeout( next, 13 );
+                       break;
                }
-               config[ val.id ] = QUnit.urlParams[ val.id ];
-               urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
-                       "' name='" + escapeText( val.id ) +
-                       "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
-                       " title='" + escapeText( val.tooltip ) +
-                       "'><label for='qunit-urlconfig-" + escapeText( val.id ) +
-                       "' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
        }
+       config.depth--;
+       if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+               done();
+       }
+}
 
-       moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
-               ( config.module === undefined  ? "selected='selected'" : "" ) +
-               ">< All Modules ></option>";
+function saveGlobal() {
+       config.pollution = [];
 
-       for ( i in config.modules ) {
-               if ( config.modules.hasOwnProperty( i ) ) {
-                       numModules += 1;
-                       moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(i) ) + "' " +
-                               ( config.module === i ? "selected='selected'" : "" ) +
-                               ">" + escapeText(i) + "</option>";
+       if ( config.noglobals ) {
+               for ( var key in window ) {
+                       if ( hasOwn.call( window, key ) ) {
+                               // in Opera sometimes DOM element ids show up here, ignore them
+                               if ( /^qunit-test-output/.test( key ) ) {
+                                       continue;
+                               }
+                               config.pollution.push( key );
+                       }
                }
        }
-       moduleFilterHtml += "</select>";
+}
 
-       // `userAgent` initialized at top of scope
-       userAgent = id( "qunit-userAgent" );
-       if ( userAgent ) {
-               userAgent.innerHTML = navigator.userAgent;
-       }
+function checkPollution() {
+       var newGlobals,
+               deletedGlobals,
+               old = config.pollution;
 
-       // `banner` initialized at top of scope
-       banner = id( "qunit-header" );
-       if ( banner ) {
-               banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> ";
+       saveGlobal();
+
+       newGlobals = diff( config.pollution, old );
+       if ( newGlobals.length > 0 ) {
+               QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
        }
 
-       // `toolbar` initialized at top of scope
-       toolbar = id( "qunit-testrunner-toolbar" );
-       if ( toolbar ) {
-               // `filter` initialized at top of scope
-               filter = document.createElement( "input" );
-               filter.type = "checkbox";
-               filter.id = "qunit-filter-pass";
+       deletedGlobals = diff( old, config.pollution );
+       if ( deletedGlobals.length > 0 ) {
+               QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+       }
+}
 
-               addEvent( filter, "click", function() {
-                       var tmp,
-                               ol = document.getElementById( "qunit-tests" );
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+       var i, j,
+               result = a.slice();
 
-                       if ( filter.checked ) {
-                               ol.className = ol.className + " hidepass";
-                       } else {
-                               tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
-                               ol.className = tmp.replace( / hidepass /, " " );
+       for ( i = 0; i < result.length; i++ ) {
+               for ( j = 0; j < b.length; j++ ) {
+                       if ( result[i] === b[j] ) {
+                               result.splice( i, 1 );
+                               i--;
+                               break;
                        }
-                       if ( defined.sessionStorage ) {
-                               if (filter.checked) {
-                                       sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+               }
+       }
+       return result;
+}
+
+function extend( a, b ) {
+       for ( var prop in b ) {
+               if ( hasOwn.call( b, prop ) ) {
+                       // Avoid "Member not found" error in IE8 caused by messing with window.constructor
+                       if ( !( prop === "constructor" && a === window ) ) {
+                               if ( b[ prop ] === undefined ) {
+                                       delete a[ prop ];
                                } else {
-                                       sessionStorage.removeItem( "qunit-filter-passed-tests" );
+                                       a[ prop ] = b[ prop ];
                                }
                        }
-               });
-
-               if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
-                       filter.checked = true;
-                       // `ol` initialized at top of scope
-                       ol = document.getElementById( "qunit-tests" );
-                       ol.className = ol.className + " hidepass";
                }
-               toolbar.appendChild( filter );
+       }
 
-               // `label` initialized at top of scope
-               label = document.createElement( "label" );
-               label.setAttribute( "for", "qunit-filter-pass" );
-               label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." );
-               label.innerHTML = "Hide passed tests";
-               toolbar.appendChild( label );
+       return a;
+}
 
-               urlConfigCheckboxesContainer = document.createElement("span");
-               urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
-               urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
-               // For oldIE support:
-               // * Add handlers to the individual elements instead of the container
-               // * Use "click" instead of "change"
-               // * Fallback from event.target to event.srcElement
-               addEvents( urlConfigCheckboxes, "click", function( event ) {
-                       var params = {},
-                               target = event.target || event.srcElement;
-                       params[ target.name ] = target.checked ? true : undefined;
-                       window.location = QUnit.url( params );
-               });
-               toolbar.appendChild( urlConfigCheckboxesContainer );
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+       if ( elem.addEventListener ) {
 
-               if (numModules > 1) {
-                       moduleFilter = document.createElement( 'span' );
-                       moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
-                       moduleFilter.innerHTML = moduleFilterHtml;
-                       addEvent( moduleFilter.lastChild, "change", function() {
-                               var selectBox = moduleFilter.getElementsByTagName("select")[0],
-                                       selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+               // Standards-based browsers
+               elem.addEventListener( type, fn, false );
+       } else if ( elem.attachEvent ) {
 
-                               window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
-                       });
-                       toolbar.appendChild(moduleFilter);
-               }
-       }
+               // support: IE <9
+               elem.attachEvent( "on" + type, fn );
+       } else {
 
-       // `main` initialized at top of scope
-       main = id( "qunit-fixture" );
-       if ( main ) {
-               config.fixture = main.innerHTML;
+               // Caller must ensure support for event listeners is present
+               throw new Error( "addEvent() was called in a context without event listener support" );
        }
+}
 
-       if ( config.autostart ) {
-               QUnit.start();
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+       var i = elems.length;
+       while ( i-- ) {
+               addEvent( elems[i], type, fn );
        }
-};
-
-addEvent( window, "load", QUnit.load );
+}
 
-// `onErrorFnPrev` initialized at top of scope
-// Preserve other handlers
-onErrorFnPrev = window.onerror;
+function hasClass( elem, name ) {
+       return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
+}
 
-// Cover uncaught exceptions
-// Returning true will surpress the default browser handler,
-// returning false will let it run.
-window.onerror = function ( error, filePath, linerNr ) {
-       var ret = false;
-       if ( onErrorFnPrev ) {
-               ret = onErrorFnPrev( error, filePath, linerNr );
+function addClass( elem, name ) {
+       if ( !hasClass( elem, name ) ) {
+               elem.className += (elem.className ? " " : "") + name;
        }
+}
 
-       // Treat return value as window.onerror itself does,
-       // Only do our handling if not surpressed.
-       if ( ret !== true ) {
-               if ( QUnit.config.current ) {
-                       if ( QUnit.config.current.ignoreGlobalErrors ) {
-                               return true;
-                       }
-                       QUnit.pushFailure( error, filePath + ":" + linerNr );
-               } else {
-                       QUnit.test( "global failure", extend( function() {
-                               QUnit.pushFailure( error, filePath + ":" + linerNr );
-                       }, { validTest: validTest } ) );
-               }
-               return false;
+function removeClass( elem, name ) {
+       var set = " " + elem.className + " ";
+       // Class name may appear multiple times
+       while ( set.indexOf(" " + name + " ") > -1 ) {
+               set = set.replace(" " + name + " " , " ");
        }
+       // If possible, trim it for prettiness, but not necessarily
+       elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
+}
 
-       return ret;
-};
-
-function done() {
-       config.autorun = true;
+function id( name ) {
+       return defined.document && document.getElementById && document.getElementById( name );
+}
 
-       // Log the last module results
-       if ( config.currentModule ) {
-               runLoggingCallbacks( "moduleDone", QUnit, {
-                       name: config.currentModule,
-                       failed: config.moduleStats.bad,
-                       passed: config.moduleStats.all - config.moduleStats.bad,
-                       total: config.moduleStats.all
-               });
-       }
-
-       var i, key,
-               banner = id( "qunit-banner" ),
-               tests = id( "qunit-tests" ),
-               runtime = +new Date() - config.started,
-               passed = config.stats.all - config.stats.bad,
-               html = [
-                       "Tests completed in ",
-                       runtime,
-                       " milliseconds.<br/>",
-                       "<span class='passed'>",
-                       passed,
-                       "</span> assertions of <span class='total'>",
-                       config.stats.all,
-                       "</span> passed, <span class='failed'>",
-                       config.stats.bad,
-                       "</span> failed."
-               ].join( "" );
+function registerLoggingCallback( key ) {
+       return function( callback ) {
+               config[key].push( callback );
+       };
+}
 
-       if ( banner ) {
-               banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+       var i, callbacks;
+       if ( QUnit.hasOwnProperty( key ) ) {
+               QUnit[ key ].call(scope, args );
+       } else {
+               callbacks = config[ key ];
+               for ( i = 0; i < callbacks.length; i++ ) {
+                       callbacks[ i ].call( scope, args );
+               }
        }
+}
 
-       if ( tests ) {
-               id( "qunit-testresult" ).innerHTML = html;
+// from jquery.js
+function inArray( elem, array ) {
+       if ( array.indexOf ) {
+               return array.indexOf( elem );
        }
 
-       if ( config.altertitle && typeof document !== "undefined" && document.title ) {
-               // show ✖ for good, ✔ for bad suite result in title
-               // use escape sequences in case file gets loaded with non-utf-8-charset
-               document.title = [
-                       ( config.stats.bad ? "\u2716" : "\u2714" ),
-                       document.title.replace( /^[\u2714\u2716] /i, "" )
-               ].join( " " );
+       for ( var i = 0, length = array.length; i < length; i++ ) {
+               if ( array[ i ] === elem ) {
+                       return i;
+               }
        }
 
-       // clear own sessionStorage items if all tests passed
-       if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
-               // `key` & `i` initialized at top of scope
-               for ( i = 0; i < sessionStorage.length; i++ ) {
-                       key = sessionStorage.key( i++ );
-                       if ( key.indexOf( "qunit-test-" ) === 0 ) {
-                               sessionStorage.removeItem( key );
+       return -1;
+}
+
+function Test( settings ) {
+       extend( this, settings );
+       this.assertions = [];
+       this.testNumber = ++Test.count;
+}
+
+Test.count = 0;
+
+Test.prototype = {
+       init: function() {
+               var a, b, li,
+                       tests = id( "qunit-tests" );
+
+               if ( tests ) {
+                       b = document.createElement( "strong" );
+                       b.innerHTML = this.nameHtml;
+
+                       // `a` initialized at top of scope
+                       a = document.createElement( "a" );
+                       a.innerHTML = "Rerun";
+                       a.href = QUnit.url({ testNumber: this.testNumber });
+
+                       li = document.createElement( "li" );
+                       li.appendChild( b );
+                       li.appendChild( a );
+                       li.className = "running";
+                       li.id = this.id = "qunit-test-output" + testId++;
+
+                       tests.appendChild( li );
+               }
+       },
+       setup: function() {
+               if (
+                       // Emit moduleStart when we're switching from one module to another
+                       this.module !== config.previousModule ||
+                               // They could be equal (both undefined) but if the previousModule property doesn't
+                               // yet exist it means this is the first test in a suite that isn't wrapped in a
+                               // module, in which case we'll just emit a moduleStart event for 'undefined'.
+                               // Without this, reporters can get testStart before moduleStart  which is a problem.
+                               !hasOwn.call( config, "previousModule" )
+               ) {
+                       if ( hasOwn.call( config, "previousModule" ) ) {
+                               runLoggingCallbacks( "moduleDone", QUnit, {
+                                       name: config.previousModule,
+                                       failed: config.moduleStats.bad,
+                                       passed: config.moduleStats.all - config.moduleStats.bad,
+                                       total: config.moduleStats.all
+                               });
                        }
+                       config.previousModule = this.module;
+                       config.moduleStats = { all: 0, bad: 0 };
+                       runLoggingCallbacks( "moduleStart", QUnit, {
+                               name: this.module
+                       });
                }
-       }
 
-       // scroll back to top to show results
-       if ( window.scrollTo ) {
-               window.scrollTo(0, 0);
-       }
+               config.current = this;
 
-       runLoggingCallbacks( "done", QUnit, {
-               failed: config.stats.bad,
-               passed: passed,
-               total: config.stats.all,
-               runtime: runtime
-       });
-}
+               this.testEnvironment = extend({
+                       setup: function() {},
+                       teardown: function() {}
+               }, this.moduleTestEnvironment );
 
-/** @return Boolean: true if this test should be ran */
-function validTest( test ) {
-       var include,
-               filter = config.filter && config.filter.toLowerCase(),
-               module = config.module && config.module.toLowerCase(),
-               fullName = (test.module + ": " + test.testName).toLowerCase();
+               this.started = +new Date();
+               runLoggingCallbacks( "testStart", QUnit, {
+                       name: this.testName,
+                       module: this.module
+               });
 
-       // Internally-generated tests are always valid
-       if ( test.callback && test.callback.validTest === validTest ) {
-               delete test.callback.validTest;
-               return true;
-       }
+               /*jshint camelcase:false */
 
-       if ( config.testNumber ) {
-               return test.testNumber === config.testNumber;
-       }
 
-       if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
-               return false;
-       }
+               /**
+                * Expose the current test environment.
+                *
+                * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
+                */
+               QUnit.current_testEnvironment = this.testEnvironment;
 
-       if ( !filter ) {
-               return true;
-       }
+               /*jshint camelcase:true */
 
-       include = filter.charAt( 0 ) !== "!";
-       if ( !include ) {
-               filter = filter.slice( 1 );
-       }
+               if ( !config.pollution ) {
+                       saveGlobal();
+               }
+               if ( config.notrycatch ) {
+                       this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+                       return;
+               }
+               try {
+                       this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
+               } catch( e ) {
+                       QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+               }
+       },
+       run: function() {
+               config.current = this;
 
-       // If the filter matches, we need to honour include
-       if ( fullName.indexOf( filter ) !== -1 ) {
-               return include;
-       }
+               var running = id( "qunit-testresult" );
 
-       // Otherwise, do the opposite
-       return !include;
-}
+               if ( running ) {
+                       running.innerHTML = "Running: <br/>" + this.nameHtml;
+               }
 
-// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
-// Later Safari and IE10 are supposed to support error.stack as well
-// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
-function extractStacktrace( e, offset ) {
-       offset = offset === undefined ? 3 : offset;
+               if ( this.async ) {
+                       QUnit.stop();
+               }
 
-       var stack, include, i;
+               this.callbackStarted = +new Date();
 
-       if ( e.stacktrace ) {
-               // Opera
-               return e.stacktrace.split( "\n" )[ offset + 3 ];
-       } else if ( e.stack ) {
-               // Firefox, Chrome
-               stack = e.stack.split( "\n" );
-               if (/^error$/i.test( stack[0] ) ) {
-                       stack.shift();
+               if ( config.notrycatch ) {
+                       this.callback.call( this.testEnvironment, QUnit.assert );
+                       this.callbackRuntime = +new Date() - this.callbackStarted;
+                       return;
                }
-               if ( fileName ) {
-                       include = [];
-                       for ( i = offset; i < stack.length; i++ ) {
-                               if ( stack[ i ].indexOf( fileName ) !== -1 ) {
-                                       break;
+
+               try {
+                       this.callback.call( this.testEnvironment, QUnit.assert );
+                       this.callbackRuntime = +new Date() - this.callbackStarted;
+               } catch( e ) {
+                       this.callbackRuntime = +new Date() - this.callbackStarted;
+
+                       QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+                       // else next test will carry the responsibility
+                       saveGlobal();
+
+                       // Restart the tests if they're blocking
+                       if ( config.blocking ) {
+                               QUnit.start();
+                       }
+               }
+       },
+       teardown: function() {
+               config.current = this;
+               if ( config.notrycatch ) {
+                       if ( typeof this.callbackRuntime === "undefined" ) {
+                               this.callbackRuntime = +new Date() - this.callbackStarted;
+                       }
+                       this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+                       return;
+               } else {
+                       try {
+                               this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
+                       } catch( e ) {
+                               QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
+                       }
+               }
+               checkPollution();
+       },
+       finish: function() {
+               config.current = this;
+               if ( config.requireExpects && this.expected === null ) {
+                       QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+               } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+                       QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
+               } else if ( this.expected === null && !this.assertions.length ) {
+                       QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
+               }
+
+               var i, assertion, a, b, time, li, ol,
+                       test = this,
+                       good = 0,
+                       bad = 0,
+                       tests = id( "qunit-tests" );
+
+               this.runtime = +new Date() - this.started;
+               config.stats.all += this.assertions.length;
+               config.moduleStats.all += this.assertions.length;
+
+               if ( tests ) {
+                       ol = document.createElement( "ol" );
+                       ol.className = "qunit-assert-list";
+
+                       for ( i = 0; i < this.assertions.length; i++ ) {
+                               assertion = this.assertions[i];
+
+                               li = document.createElement( "li" );
+                               li.className = assertion.result ? "pass" : "fail";
+                               li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
+                               ol.appendChild( li );
+
+                               if ( assertion.result ) {
+                                       good++;
+                               } else {
+                                       bad++;
+                                       config.stats.bad++;
+                                       config.moduleStats.bad++;
                                }
-                               include.push( stack[ i ] );
                        }
-                       if ( include.length ) {
-                               return include.join( "\n" );
+
+                       // store result when possible
+                       if ( QUnit.config.reorder && defined.sessionStorage ) {
+                               if ( bad ) {
+                                       sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
+                               } else {
+                                       sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
+                               }
+                       }
+
+                       if ( bad === 0 ) {
+                               addClass( ol, "qunit-collapsed" );
+                       }
+
+                       // `b` initialized at top of scope
+                       b = document.createElement( "strong" );
+                       b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
+
+                       addEvent(b, "click", function() {
+                               var next = b.parentNode.lastChild,
+                                       collapsed = hasClass( next, "qunit-collapsed" );
+                               ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
+                       });
+
+                       addEvent(b, "dblclick", function( e ) {
+                               var target = e && e.target ? e.target : window.event.srcElement;
+                               if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
+                                       target = target.parentNode;
+                               }
+                               if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
+                                       window.location = QUnit.url({ testNumber: test.testNumber });
+                               }
+                       });
+
+                       // `time` initialized at top of scope
+                       time = document.createElement( "span" );
+                       time.className = "runtime";
+                       time.innerHTML = this.runtime + " ms";
+
+                       // `li` initialized at top of scope
+                       li = id( this.id );
+                       li.className = bad ? "fail" : "pass";
+                       li.removeChild( li.firstChild );
+                       a = li.firstChild;
+                       li.appendChild( b );
+                       li.appendChild( a );
+                       li.appendChild( time );
+                       li.appendChild( ol );
+
+               } else {
+                       for ( i = 0; i < this.assertions.length; i++ ) {
+                               if ( !this.assertions[i].result ) {
+                                       bad++;
+                                       config.stats.bad++;
+                                       config.moduleStats.bad++;
+                               }
                        }
                }
-               return stack[ offset ];
-       } else if ( e.sourceURL ) {
-               // Safari, PhantomJS
-               // hopefully one day Safari provides actual stacktraces
-               // exclude useless self-reference for generated Error objects
-               if ( /qunit.js$/.test( e.sourceURL ) ) {
-                       return;
+
+               runLoggingCallbacks( "testDone", QUnit, {
+                       name: this.testName,
+                       module: this.module,
+                       failed: bad,
+                       passed: this.assertions.length - bad,
+                       total: this.assertions.length,
+                       runtime: this.runtime,
+                       // DEPRECATED: this property will be removed in 2.0.0, use runtime instead
+                       duration: this.runtime
+               });
+
+               QUnit.reset();
+
+               config.current = undefined;
+       },
+
+       queue: function() {
+               var bad,
+                       test = this;
+
+               synchronize(function() {
+                       test.init();
+               });
+               function run() {
+                       // each of these can by async
+                       synchronize(function() {
+                               test.setup();
+                       });
+                       synchronize(function() {
+                               test.run();
+                       });
+                       synchronize(function() {
+                               test.teardown();
+                       });
+                       synchronize(function() {
+                               test.finish();
+                       });
+               }
+
+               // `bad` initialized at top of scope
+               // defer when previous test run passed, if storage is available
+               bad = QUnit.config.reorder && defined.sessionStorage &&
+                                               +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
+
+               if ( bad ) {
+                       run();
+               } else {
+                       synchronize( run, true );
                }
-               // for actual exceptions, this is useful
-               return e.sourceURL + ":" + e.line;
-       }
-}
-function sourceFromStacktrace( offset ) {
-       try {
-               throw new Error();
-       } catch ( e ) {
-               return extractStacktrace( e, offset );
        }
-}
+};
+
+// `assert` initialized at top of scope
+// Assert helpers
+// All of these must either call QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+assert = QUnit.assert = {
+       /**
+        * Asserts rough true-ish result.
+        * @name ok
+        * @function
+        * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+        */
+       ok: function( result, msg ) {
+               if ( !config.current ) {
+                       throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
+               }
+               result = !!result;
+               msg = msg || ( result ? "okay" : "failed" );
+
+               var source,
+                       details = {
+                               module: config.current.module,
+                               name: config.current.testName,
+                               result: result,
+                               message: msg
+                       };
+
+               msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
+
+               if ( !result ) {
+                       source = sourceFromStacktrace( 2 );
+                       if ( source ) {
+                               details.source = source;
+                               msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" +
+                                       escapeText( source ) +
+                                       "</pre></td></tr></table>";
+                       }
+               }
+               runLoggingCallbacks( "log", QUnit, details );
+               config.current.assertions.push({
+                       result: result,
+                       message: msg
+               });
+       },
+
+       /**
+        * Assert that the first two arguments are equal, with an optional message.
+        * Prints out both actual and expected values.
+        * @name equal
+        * @function
+        * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+        */
+       equal: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
+               QUnit.push( expected == actual, actual, expected, message );
+       },
+
+       /**
+        * @name notEqual
+        * @function
+        */
+       notEqual: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
+               QUnit.push( expected != actual, actual, expected, message );
+       },
+
+       /**
+        * @name propEqual
+        * @function
+        */
+       propEqual: function( actual, expected, message ) {
+               actual = objectValues(actual);
+               expected = objectValues(expected);
+               QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+       },
 
-/**
- * Escape text for attribute or text content.
- */
-function escapeText( s ) {
-       if ( !s ) {
-               return "";
-       }
-       s = s + "";
-       // Both single quotes and double quotes (for attributes)
-       return s.replace( /['"<>&]/g, function( s ) {
-               switch( s ) {
-                       case '\'':
-                               return '&#039;';
-                       case '"':
-                               return '&quot;';
-                       case '<':
-                               return '&lt;';
-                       case '>':
-                               return '&gt;';
-                       case '&':
-                               return '&amp;';
-               }
-       });
-}
+       /**
+        * @name notPropEqual
+        * @function
+        */
+       notPropEqual: function( actual, expected, message ) {
+               actual = objectValues(actual);
+               expected = objectValues(expected);
+               QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+       },
 
-function synchronize( callback, last ) {
-       config.queue.push( callback );
+       /**
+        * @name deepEqual
+        * @function
+        */
+       deepEqual: function( actual, expected, message ) {
+               QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
+       },
 
-       if ( config.autorun && !config.blocking ) {
-               process( last );
-       }
-}
+       /**
+        * @name notDeepEqual
+        * @function
+        */
+       notDeepEqual: function( actual, expected, message ) {
+               QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
+       },
 
-function process( last ) {
-       function next() {
-               process( last );
-       }
-       var start = new Date().getTime();
-       config.depth = config.depth ? config.depth + 1 : 1;
+       /**
+        * @name strictEqual
+        * @function
+        */
+       strictEqual: function( actual, expected, message ) {
+               QUnit.push( expected === actual, actual, expected, message );
+       },
 
-       while ( config.queue.length && !config.blocking ) {
-               if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
-                       config.queue.shift()();
-               } else {
-                       window.setTimeout( next, 13 );
-                       break;
-               }
-       }
-       config.depth--;
-       if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
-               done();
-       }
-}
+       /**
+        * @name notStrictEqual
+        * @function
+        */
+       notStrictEqual: function( actual, expected, message ) {
+               QUnit.push( expected !== actual, actual, expected, message );
+       },
 
-function saveGlobal() {
-       config.pollution = [];
+       "throws": function( block, expected, message ) {
+               var actual,
+                       expectedOutput = expected,
+                       ok = false;
 
-       if ( config.noglobals ) {
-               for ( var key in window ) {
-                       // in Opera sometimes DOM element ids show up here, ignore them
-                       if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) {
-                               continue;
-                       }
-                       config.pollution.push( key );
+               // 'expected' is optional
+               if ( !message && typeof expected === "string" ) {
+                       message = expected;
+                       expected = null;
                }
-       }
-}
 
-function checkPollution() {
-       var newGlobals,
-               deletedGlobals,
-               old = config.pollution;
+               config.current.ignoreGlobalErrors = true;
+               try {
+                       block.call( config.current.testEnvironment );
+               } catch (e) {
+                       actual = e;
+               }
+               config.current.ignoreGlobalErrors = false;
 
-       saveGlobal();
+               if ( actual ) {
 
-       newGlobals = diff( config.pollution, old );
-       if ( newGlobals.length > 0 ) {
-               QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
-       }
+                       // we don't want to validate thrown error
+                       if ( !expected ) {
+                               ok = true;
+                               expectedOutput = null;
 
-       deletedGlobals = diff( old, config.pollution );
-       if ( deletedGlobals.length > 0 ) {
-               QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
-       }
-}
+                       // expected is an Error object
+                       } else if ( expected instanceof Error ) {
+                               ok = actual instanceof Error &&
+                                        actual.name === expected.name &&
+                                        actual.message === expected.message;
 
-// returns a new Array with the elements that are in a but not in b
-function diff( a, b ) {
-       var i, j,
-               result = a.slice();
+                       // expected is a regexp
+                       } else if ( QUnit.objectType( expected ) === "regexp" ) {
+                               ok = expected.test( errorString( actual ) );
 
-       for ( i = 0; i < result.length; i++ ) {
-               for ( j = 0; j < b.length; j++ ) {
-                       if ( result[i] === b[j] ) {
-                               result.splice( i, 1 );
-                               i--;
-                               break;
-                       }
-               }
-       }
-       return result;
-}
+                       // expected is a string
+                       } else if ( QUnit.objectType( expected ) === "string" ) {
+                               ok = expected === errorString( actual );
 
-function extend( a, b ) {
-       for ( var prop in b ) {
-               if ( b[ prop ] === undefined ) {
-                       delete a[ prop ];
+                       // expected is a constructor
+                       } else if ( actual instanceof expected ) {
+                               ok = true;
+
+                       // expected is a validation function which returns true is validation passed
+                       } else if ( expected.call( {}, actual ) === true ) {
+                               expectedOutput = null;
+                               ok = true;
+                       }
 
-               // Avoid "Member not found" error in IE8 caused by setting window.constructor
-               } else if ( prop !== "constructor" || a !== window ) {
-                       a[ prop ] = b[ prop ];
+                       QUnit.push( ok, actual, expectedOutput, message );
+               } else {
+                       QUnit.pushFailure( message, null, "No exception was thrown." );
                }
        }
-
-       return a;
-}
+};
 
 /**
- * @param {HTMLElement} elem
- * @param {string} type
- * @param {Function} fn
+ * @deprecated since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility.
  */
-function addEvent( elem, type, fn ) {
-       // Standards-based browsers
-       if ( elem.addEventListener ) {
-               elem.addEventListener( type, fn, false );
-       // IE
-       } else {
-               elem.attachEvent( "on" + type, fn );
-       }
-}
+extend( QUnit.constructor.prototype, assert );
 
 /**
- * @param {Array|NodeList} elems
- * @param {string} type
- * @param {Function} fn
+ * @deprecated since 1.9.0
+ * Kept to avoid TypeErrors for undefined methods.
  */
-function addEvents( elems, type, fn ) {
-       var i = elems.length;
-       while ( i-- ) {
-               addEvent( elems[i], type, fn );
-       }
-}
-
-function hasClass( elem, name ) {
-       return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
-}
-
-function addClass( elem, name ) {
-       if ( !hasClass( elem, name ) ) {
-               elem.className += (elem.className ? " " : "") + name;
-       }
-}
-
-function removeClass( elem, name ) {
-       var set = " " + elem.className + " ";
-       // Class name may appear multiple times
-       while ( set.indexOf(" " + name + " ") > -1 ) {
-               set = set.replace(" " + name + " " , " ");
-       }
-       // If possible, trim it for prettiness, but not neccecarily
-       elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set );
-}
-
-function id( name ) {
-       return !!( typeof document !== "undefined" && document && document.getElementById ) &&
-               document.getElementById( name );
-}
-
-function registerLoggingCallback( key ) {
-       return function( callback ) {
-               config[key].push( callback );
-       };
-}
+QUnit.constructor.prototype.raises = function() {
+       QUnit.push( false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead" );
+};
 
-// Supports deprecated method of completely overwriting logging callbacks
-function runLoggingCallbacks( key, scope, args ) {
-       var i, callbacks;
-       if ( QUnit.hasOwnProperty( key ) ) {
-               QUnit[ key ].call(scope, args );
-       } else {
-               callbacks = config[ key ];
-               for ( i = 0; i < callbacks.length; i++ ) {
-                       callbacks[ i ].call( scope, args );
-               }
-       }
-}
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
+ */
+QUnit.constructor.prototype.equals = function() {
+       QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.constructor.prototype.same = function() {
+       QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
+};
 
 // Test for equality any JavaScript type.
 // Author: Philippe Rathé <prathe@gmail.com>
@@ -1585,8 +1705,10 @@ QUnit.equiv = (function() {
                callers = [],
                // stack to avoiding loops from circular referencing
                parents = [],
+               parentsB = [],
 
                getProto = Object.getPrototypeOf || function ( obj ) {
+                       /*jshint camelcase:false */
                        return obj.__proto__;
                },
                callbacks = (function () {
@@ -1595,7 +1717,7 @@ QUnit.equiv = (function() {
                        function useStrictEquality( b, a ) {
                                /*jshint eqeqeq:false */
                                if ( b instanceof a.constructor || a instanceof b.constructor ) {
-                                       // to catch short annotaion VS 'new' annotation of a
+                                       // to catch short annotation VS 'new' annotation of a
                                        // declaration
                                        // e.g. var i = 1;
                                        // var j = new Number(1);
@@ -1624,7 +1746,7 @@ QUnit.equiv = (function() {
                                        return QUnit.objectType( b ) === "regexp" &&
                                                // the regex itself
                                                a.source === b.source &&
-                                               // and its modifers
+                                               // and its modifiers
                                                a.global === b.global &&
                                                // (gmi) ...
                                                a.ignoreCase === b.ignoreCase &&
@@ -1641,7 +1763,7 @@ QUnit.equiv = (function() {
                                },
 
                                "array": function( b, a ) {
-                                       var i, j, len, loop;
+                                       var i, j, len, loop, aCircular, bCircular;
 
                                        // b could be an object literal here
                                        if ( QUnit.objectType( b ) !== "array" ) {
@@ -1656,24 +1778,36 @@ QUnit.equiv = (function() {
 
                                        // track reference to avoid circular references
                                        parents.push( a );
+                                       parentsB.push( b );
                                        for ( i = 0; i < len; i++ ) {
                                                loop = false;
                                                for ( j = 0; j < parents.length; j++ ) {
-                                                       if ( parents[j] === a[i] ) {
-                                                               loop = true;// dont rewalk array
+                                                       aCircular = parents[j] === a[i];
+                                                       bCircular = parentsB[j] === b[i];
+                                                       if ( aCircular || bCircular ) {
+                                                               if ( a[i] === b[i] || aCircular && bCircular ) {
+                                                                       loop = true;
+                                                               } else {
+                                                                       parents.pop();
+                                                                       parentsB.pop();
+                                                                       return false;
+                                                               }
                                                        }
                                                }
                                                if ( !loop && !innerEquiv(a[i], b[i]) ) {
                                                        parents.pop();
+                                                       parentsB.pop();
                                                        return false;
                                                }
                                        }
                                        parents.pop();
+                                       parentsB.pop();
                                        return true;
                                },
 
                                "object": function( b, a ) {
-                                       var i, j, loop,
+                                       /*jshint forin:false */
+                                       var i, j, loop, aCircular, bCircular,
                                                // Default to true
                                                eq = true,
                                                aProperties = [],
@@ -1692,28 +1826,36 @@ QUnit.equiv = (function() {
 
                                        // stack constructor before traversing properties
                                        callers.push( a.constructor );
+
                                        // track reference to avoid circular references
                                        parents.push( a );
+                                       parentsB.push( b );
 
-                                       for ( i in a ) { // be strict: don't ensures hasOwnProperty
-                                                                       // and go deep
+                                       // be strict: don't ensure hasOwnProperty and go deep
+                                       for ( i in a ) {
                                                loop = false;
                                                for ( j = 0; j < parents.length; j++ ) {
-                                                       if ( parents[j] === a[i] ) {
-                                                               // don't go down the same path twice
-                                                               loop = true;
+                                                       aCircular = parents[j] === a[i];
+                                                       bCircular = parentsB[j] === b[i];
+                                                       if ( aCircular || bCircular ) {
+                                                               if ( a[i] === b[i] || aCircular && bCircular ) {
+                                                                       loop = true;
+                                                               } else {
+                                                                       eq = false;
+                                                                       break;
+                                                               }
                                                        }
                                                }
-                                               aProperties.push(i); // collect a's properties
-
-                                               if (!loop && !innerEquiv( a[i], b[i] ) ) {
+                                               aProperties.push(i);
+                                               if ( !loop && !innerEquiv(a[i], b[i]) ) {
                                                        eq = false;
                                                        break;
                                                }
                                        }
 
-                                       callers.pop(); // unstack, we are done
                                        parents.pop();
+                                       parentsB.pop();
+                                       callers.pop(); // unstack, we are done
 
                                        for ( i in b ) {
                                                bProperties.push( i ); // collect b's properties
@@ -1743,7 +1885,7 @@ QUnit.equiv = (function() {
                        }
 
                        // apply transition with (1..n) arguments
-               }( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) );
+               }( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
        };
 
        return innerEquiv;
@@ -1761,7 +1903,7 @@ QUnit.equiv = (function() {
  */
 QUnit.jsDump = (function() {
        function quote( str ) {
-               return '"' + str.toString().replace( /"/g, '\\"' ) + '"';
+               return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
        }
        function literal( o ) {
                return o + "";
@@ -1854,13 +1996,13 @@ QUnit.jsDump = (function() {
                                if ( this.HTML ) {
                                        chr = chr.replace( /\t/g, "   " ).replace( / /g, "&nbsp;" );
                                }
-                               return new Array( this._depth_ + (extra||0) ).join(chr);
+                               return new Array( this.depth + ( extra || 0 ) ).join(chr);
                        },
                        up: function( a ) {
-                               this._depth_ += a || 1;
+                               this.depth += a || 1;
                        },
                        down: function( a ) {
-                               this._depth_ -= a || 1;
+                               this.depth -= a || 1;
                        },
                        setParser: function( name, parser ) {
                                this.parsers[name] = parser;
@@ -1870,7 +2012,7 @@ QUnit.jsDump = (function() {
                        literal: literal,
                        join: join,
                        //
-                       _depth_: 1,
+                       depth: 1,
                        // This is the list of parsers, to modify them, use jsDump.setParser
                        parsers: {
                                window: "[Window]",
@@ -1898,6 +2040,7 @@ QUnit.jsDump = (function() {
                                nodelist: array,
                                "arguments": array,
                                object: function( map, stack ) {
+                                       /*jshint forin:false */
                                        var ret = [ ], keys, key, val, i;
                                        QUnit.jsDump.up();
                                        keys = [];
@@ -1979,21 +2122,6 @@ QUnit.jsDump = (function() {
        return jsDump;
 }());
 
-// from jquery.js
-function inArray( elem, array ) {
-       if ( array.indexOf ) {
-               return array.indexOf( elem );
-       }
-
-       for ( var i = 0, length = array.length; i < length; i++ ) {
-               if ( array[ i ] === elem ) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
 /*
  * Javascript Diff Algorithm
  *  By John Resig (http://ejohn.org/)
@@ -2036,18 +2164,17 @@ QUnit.diff = (function() {
                }
 
                for ( i in ns ) {
-                       if ( !hasOwn.call( ns, i ) ) {
-                               continue;
-                       }
-                       if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
-                               n[ ns[i].rows[0] ] = {
-                                       text: n[ ns[i].rows[0] ],
-                                       row: os[i].rows[0]
-                               };
-                               o[ os[i].rows[0] ] = {
-                                       text: o[ os[i].rows[0] ],
-                                       row: ns[i].rows[0]
-                               };
+                       if ( hasOwn.call( ns, i ) ) {
+                               if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
+                                       n[ ns[i].rows[0] ] = {
+                                               text: n[ ns[i].rows[0] ],
+                                               row: os[i].rows[0]
+                                       };
+                                       o[ os[i].rows[0] ] = {
+                                               text: o[ os[i].rows[0] ],
+                                               row: ns[i].rows[0]
+                                       };
+                               }
                        }
                }
 
@@ -2143,10 +2270,19 @@ QUnit.diff = (function() {
        };
 }());
 
-// for CommonJS enviroments, export everything
-if ( typeof exports !== "undefined" ) {
-       extend( exports, QUnit );
+// For browser, export only select globals
+if ( typeof window !== "undefined" ) {
+       extend( window, QUnit.constructor.prototype );
+       window.QUnit = QUnit;
+}
+
+// For CommonJS environments, export everything
+if ( typeof module !== "undefined" && module.exports ) {
+       module.exports = QUnit;
 }
 
-// get at whatever the global object is, like window in browsers
-}( (function() {return this;}.call()) ));
+
+// Get a reference to the global object, like window in browsers
+}( (function() {
+       return this;
+})() ));
index 9629087..64a8e38 100644 (file)
   opacity: 0.2;
 }
 
+.oo-ui-listToolGroup.oo-ui-widget-disabled {
+  color: #ccc;
+}
+
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatedElement-indicator,
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconedElement-icon {
   opacity: 0.2;
 
 .oo-ui-menuToolGroup.oo-ui-widget-disabled {
   color: #ccc;
-  text-shadow: 0 1px 1px #fff;
   border-color: rgba(0, 0, 0, 0.05);
 }
 
index 6e00086..958bc1c 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (ac6848398c)
+ * OOjs UI v0.1.0-pre (eca1fc20e7)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Wed Apr 09 2014 17:58:17 GMT-0700 (PDT)
+ * Date: Fri Apr 11 2014 16:47:56 GMT-0700 (PDT)
  */
 ( function ( OO ) {
 
@@ -205,8 +205,8 @@ OO.initClass( OO.ui.Element );
  * This may be ignored if getTagName is overridden.
  *
  * @static
- * @property {string}
  * @inheritable
+ * @property {string}
  */
 OO.ui.Element.static.tagName = 'div';
 
@@ -593,6 +593,26 @@ OO.ui.Element.prototype.scrollElementIntoView = function ( config ) {
        return OO.ui.Element.scrollIntoView( this.$element[0], config );
 };
 
+/**
+ * Bind a handler for an event on this.$element
+ * @see #static-method-onDOMEvent
+ * @param {string} event
+ * @param {Function} callback
+ */
+OO.ui.Element.prototype.onDOMEvent = function ( event, callback ) {
+       OO.ui.Element.onDOMEvent( this.$element, event, callback );
+};
+
+/**
+ * Unbind a handler bound with #offDOMEvent
+ * @see #static-method-offDOMEvent
+ * @param {string} event
+ * @param {Function} callback
+ */
+OO.ui.Element.prototype.offDOMEvent = function ( event, callback ) {
+       OO.ui.Element.offDOMEvent( this.$element, event, callback );
+};
+
 ( function () {
        // Static
        var specialFocusin;
@@ -623,16 +643,18 @@ OO.ui.Element.prototype.scrollElementIntoView = function ( config ) {
        };
 
        /**
-        * Bind a handler for an event on the DOM element.
+        * Bind a handler for an event on a DOM element.
         *
         * Uses jQuery internally for everything except for events which are
         * known to have issues in the browser or in jQuery. This method
         * should become obsolete eventually.
         *
-        * @param {string} event
-        * @param {Function} callback
+        * @static
+        * @param {HTMLElement|jQuery} el DOM element
+        * @param {string} event Event to bind
+        * @param {Function} callback Callback to call when the event fires
         */
-       OO.ui.Element.prototype.onDOMEvent = function ( event, callback ) {
+       OO.ui.Element.onDOMEvent = function ( el, event, callback ) {
                var orig;
 
                if ( event === 'focusin' ) {
@@ -649,29 +671,33 @@ OO.ui.Element.prototype.scrollElementIntoView = function ( config ) {
                        orig = $.event.special.focusin;
                        $.event.special.focusin = specialFocusin;
 
-                       this.$element.on( event, callback );
+                       $( el ).on( event, callback );
 
                        // Restore
                        $.event.special.focusin = orig;
 
                } else {
-                       this.$element.on( event, callback );
+                       $( el ).on( event, callback );
                }
        };
 
        /**
-        * @param {string} event
-        * @param {Function} callback
+        * Unbind a handler bound with #static-method-onDOMEvent.
+        *
+        * @static
+        * @param {HTMLElement|jQuery} el DOM element
+        * @param {string} event Event to unbind
+        * @param {Function} [callback] Callback to unbind
         */
-       OO.ui.Element.prototype.offDOMEvent = function ( event, callback ) {
+       OO.ui.Element.offDOMEvent = function ( el, event, callback ) {
                var orig;
                if ( event === 'focusin' ) {
                        orig = $.event.special.focusin;
                        $.event.special.focusin = specialFocusin;
-                       this.$element.off( event, callback );
+                       $( el ).off( event, callback );
                        $.event.special.focusin = orig;
                } else {
-                       this.$element.off( event, callback );
+                       $( el ).off( event, callback );
                }
        };
 }() );
@@ -871,7 +897,7 @@ OO.ui.Frame.prototype.load = function () {
 
        // Properties
        this.$ = OO.ui.Element.getJQuery( doc, this );
-       this.$content = this.$( '.oo-ui-frame-content' );
+       this.$content = this.$( '.oo-ui-frame-content' ).attr( 'tabIndex', 0 );
        this.$document = this.$( doc );
 
        this.constructor.static.transplantStyles(
@@ -908,7 +934,7 @@ OO.ui.Frame.prototype.run = function ( callback ) {
 };
 
 /**
- * Sets the size of the frame.
+ * Set the size of the frame.
  *
  * @param {number} width Frame width in pixels
  * @param {number} height Frame height in pixels
@@ -1265,11 +1291,14 @@ OO.ui.Window.prototype.open = function ( data ) {
                this.frame.run( OO.ui.bind( function () {
                        this.$element.show();
                        this.visible = true;
-                       this.frame.$element.focus();
                        this.emit( 'opening', data );
                        this.setup( data );
                        this.emit( 'open', data );
                        this.opening = false;
+                       // Focus the content div (which has a tabIndex) to inactivate
+                       // (but not clear) selections in the parent frame.
+                       // Must happen after the window has opened.
+                       this.frame.$content.focus();
                }, this ) );
        }
 
@@ -1528,8 +1557,8 @@ OO.inheritClass( OO.ui.Dialog, OO.ui.Window );
  *
  * @abstract
  * @static
- * @property {string}
  * @inheritable
+ * @property {string}
  */
 OO.ui.Dialog.static.name = '';
 
@@ -1537,8 +1566,8 @@ OO.ui.Dialog.static.name = '';
  * Map of symbolic size names and CSS classes.
  *
  * @static
- * @property {Object}
  * @inheritable
+ * @property {Object}
  */
 OO.ui.Dialog.static.sizeCssClasses = {
        'small': 'oo-ui-dialog-small',
@@ -1808,8 +1837,8 @@ OO.ui.Widget.prototype.setDisabled = function ( disabled ) {
 /**
  * Element with a button.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {jQuery} $button Button node, assigned to #$button
@@ -1848,14 +1877,16 @@ OO.ui.ButtonedElement = function OoUiButtonedElement( $button, config ) {
 /**
  * Handles mouse down events.
  *
- * @method
  * @param {jQuery.Event} e Mouse down event
  */
 OO.ui.ButtonedElement.prototype.onMouseDown = function () {
-       this.tabIndex = this.$button.attr( 'tabIndex' );
+       // tabIndex should generally be interacted with via the property,
+       // but it's not possible to reliably unset a tabIndex via a property
+       // so we use the (lowercase) "tabindex" attribute instead.
+       this.tabIndex = this.$button.attr( 'tabindex' );
        // Remove the tab-index while the button is down to prevent the button from stealing focus
        this.$button
-               .removeAttr( 'tabIndex' )
+               .removeAttr( 'tabindex' )
                .addClass( 'oo-ui-buttonedElement-pressed' );
        this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
 };
@@ -1863,13 +1894,12 @@ OO.ui.ButtonedElement.prototype.onMouseDown = function () {
 /**
  * Handles mouse up events.
  *
- * @method
  * @param {jQuery.Event} e Mouse up event
  */
 OO.ui.ButtonedElement.prototype.onMouseUp = function () {
        // Restore the tab-index after the button is up to restore the button's accesssibility
        this.$button
-               .attr( 'tabIndex', this.tabIndex )
+               .attr( 'tabindex', this.tabIndex )
                .removeClass( 'oo-ui-buttonedElement-pressed' );
        this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
 };
@@ -1877,7 +1907,6 @@ OO.ui.ButtonedElement.prototype.onMouseUp = function () {
 /**
  * Set active state.
  *
- * @method
  * @param {boolean} [value] Make button active
  * @chainable
  */
@@ -1888,8 +1917,8 @@ OO.ui.ButtonedElement.prototype.setActive = function ( value ) {
 /**
  * Element that can be automatically clipped to visible boundaies.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {jQuery} $clippable Nodes to clip, assigned to #$clippable
@@ -1920,7 +1949,6 @@ OO.ui.ClippableElement = function OoUiClippableElement( $clippable, config ) {
 /**
  * Set clipping.
  *
- * @method
  * @param {boolean} value Enable clipping
  * @chainable
  */
@@ -1956,7 +1984,6 @@ OO.ui.ClippableElement.prototype.setClipping = function ( value ) {
 /**
  * Check if the element will be clipped to fit the visible area of the nearest scrollable container.
  *
- * @method
  * @return {boolean} Element will be clipped to the visible area
  */
 OO.ui.ClippableElement.prototype.isClipping = function () {
@@ -1966,7 +1993,6 @@ OO.ui.ClippableElement.prototype.isClipping = function () {
 /**
  * Check if the bottom or right of the element is being clipped by the nearest scrollable container.
  *
- * @method
  * @return {boolean} Part of the element is being clipped
  */
 OO.ui.ClippableElement.prototype.isClipped = function () {
@@ -1976,7 +2002,6 @@ OO.ui.ClippableElement.prototype.isClipped = function () {
 /**
  * Set the ideal size.
  *
- * @method
  * @param {number|string} [width] Width as a number of pixels or CSS string with unit suffix
  * @param {number|string} [height] Height as a number of pixels or CSS string with unit suffix
  */
@@ -1991,7 +2016,6 @@ OO.ui.ClippableElement.prototype.setIdealSize = function ( width, height ) {
  * Element will be clipped the bottom or right of the element is within 10px of the edge of, or
  * overlapped by, the visible area of the nearest scrollable container.
  *
- * @method
  * @chainable
  */
 OO.ui.ClippableElement.prototype.clip = function () {
@@ -2035,8 +2059,8 @@ OO.ui.ClippableElement.prototype.clip = function () {
  * A flag, when set, adds a CSS class on the `$element` by combing `oo-ui-flaggableElement-` with
  * the flag name. Flags are primarily useful for styling.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -2058,19 +2082,17 @@ OO.ui.FlaggableElement = function OoUiFlaggableElement( config ) {
 /**
  * Check if a flag is set.
  *
- * @method
- * @param {string} flag Flag name to check
- * @returns {boolean} Has flag
+ * @param {string} flag Name of flag
+ * @return {boolean} Has flag
  */
 OO.ui.FlaggableElement.prototype.hasFlag = function ( flag ) {
        return flag in this.flags;
 };
 
 /**
- * Get the names of all flags.
+ * Get the names of all flags set.
  *
- * @method
- * @returns {string[]} flags Flag names
+ * @return {string[]} flags Flag names
  */
 OO.ui.FlaggableElement.prototype.getFlags = function () {
        return Object.keys( this.flags );
@@ -2079,7 +2101,6 @@ OO.ui.FlaggableElement.prototype.getFlags = function () {
 /**
  * Add one or more flags.
  *
- * @method
  * @param {string[]|Object.<string, boolean>} flags List of flags to add, or list of set/remove
  *  values, keyed by flag name
  * @chainable
@@ -2113,8 +2134,8 @@ OO.ui.FlaggableElement.prototype.setFlags = function ( flags ) {
 /**
  * Element containing a sequence of child elements.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {jQuery} $group Container node, assigned to #$group
@@ -2138,8 +2159,7 @@ OO.ui.GroupElement = function OoUiGroupElement( $group, config ) {
 /**
  * Get items.
  *
- * @method
- * @returns {OO.ui.Element[]} Items
+ * @return {OO.ui.Element[]} Items
  */
 OO.ui.GroupElement.prototype.getItems = function () {
        return this.items.slice( 0 );
@@ -2148,7 +2168,6 @@ OO.ui.GroupElement.prototype.getItems = function () {
 /**
  * Add items.
  *
- * @method
  * @param {OO.ui.Element[]} items Item
  * @param {number} [index] Index to insert items at
  * @chainable
@@ -2202,7 +2221,6 @@ OO.ui.GroupElement.prototype.addItems = function ( items, index ) {
  *
  * Items will be detached, not removed, so they can be used later.
  *
- * @method
  * @param {OO.ui.Element[]} items Items to remove
  * @chainable
  */
@@ -2232,7 +2250,6 @@ OO.ui.GroupElement.prototype.removeItems = function ( items ) {
  *
  * Items will be detached, not removed, so they can be used later.
  *
- * @method
  * @chainable
  */
 OO.ui.GroupElement.prototype.clearItems = function () {
@@ -2249,12 +2266,14 @@ OO.ui.GroupElement.prototype.clearItems = function () {
        this.items = [];
        this.$items.detach();
        this.$items = this.$( [] );
+
+       return this;
 };
 /**
  * Element containing an icon.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {jQuery} $icon Icon node, assigned to #$icon
@@ -2306,7 +2325,6 @@ OO.ui.IconedElement.static.icon = null;
 /**
  * Set icon.
  *
- * @method
  * @param {Object|string} icon Symbolic icon name, or map of icon names keyed by language ID;
  *  use the 'default' key to specify the icon to be used when there is no icon in the user's
  *  language
@@ -2333,8 +2351,7 @@ OO.ui.IconedElement.prototype.setIcon = function ( icon ) {
 /**
  * Get icon.
  *
- * @method
- * @returns {string} Icon
+ * @return {string} Icon
  */
 OO.ui.IconedElement.prototype.getIcon = function () {
        return this.icon;
@@ -2342,8 +2359,8 @@ OO.ui.IconedElement.prototype.getIcon = function () {
 /**
  * Element containing an indicator.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {jQuery} $indicator Indicator node, assigned to #$indicator
@@ -2396,7 +2413,6 @@ OO.ui.IndicatedElement.static.indicatorTitle = null;
 /**
  * Set indicator.
  *
- * @method
  * @param {string|null} indicator Symbolic name of indicator to use or null for no indicator
  * @chainable
  */
@@ -2420,7 +2436,6 @@ OO.ui.IndicatedElement.prototype.setIndicator = function ( indicator ) {
 /**
  * Set indicator label.
  *
- * @method
  * @param {string|Function|null} indicator Indicator title text, a function that return text or null
  *  for no indicator title
  * @chainable
@@ -2440,8 +2455,7 @@ OO.ui.IndicatedElement.prototype.setIndicatorTitle = function ( indicatorTitle )
 /**
  * Get indicator.
  *
- * @method
- * @returns {string} title Symbolic name of indicator
+ * @return {string} title Symbolic name of indicator
  */
 OO.ui.IndicatedElement.prototype.getIndicator = function () {
        return this.indicator;
@@ -2450,8 +2464,7 @@ OO.ui.IndicatedElement.prototype.getIndicator = function () {
 /**
  * Get indicator title.
  *
- * @method
- * @returns {string} Indicator title text
+ * @return {string} Indicator title text
  */
 OO.ui.IndicatedElement.prototype.getIndicatorTitle = function () {
        return this.indicatorTitle;
@@ -2459,8 +2472,8 @@ OO.ui.IndicatedElement.prototype.getIndicatorTitle = function () {
 /**
  * Element containing a label.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {jQuery} $label Label node, assigned to #$label
@@ -2506,7 +2519,6 @@ OO.ui.LabeledElement.static.label = null;
  * An empty string will result in the label being hidden. A string containing only whitespace will
  * be converted to a single &nbsp;
  *
- * @method
  * @param {jQuery|string|Function|null} label Label nodes; text; a function that retuns nodes or
  *  text; or null for no label
  * @chainable
@@ -2537,8 +2549,7 @@ OO.ui.LabeledElement.prototype.setLabel = function ( label ) {
 /**
  * Get the label.
  *
- * @method
- * @returns {jQuery|string|Function|null} label Label nodes; text; a function that returns nodes or
+ * @return {jQuery|string|Function|null} label Label nodes; text; a function that returns nodes or
  *  text; or null for no label
  */
 OO.ui.LabeledElement.prototype.getLabel = function () {
@@ -2548,7 +2559,6 @@ OO.ui.LabeledElement.prototype.getLabel = function () {
 /**
  * Fit the label.
  *
- * @method
  * @chainable
  */
 OO.ui.LabeledElement.prototype.fitLabel = function () {
@@ -2560,8 +2570,8 @@ OO.ui.LabeledElement.prototype.fitLabel = function () {
 /**
  * Popuppable element.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -2588,8 +2598,7 @@ OO.ui.PopuppableElement = function OoUiPopuppableElement( config ) {
 /**
  * Get popup.
  *
- * @method
- * @returns {OO.ui.PopupWidget} Popup widget
+ * @return {OO.ui.PopupWidget} Popup widget
  */
 OO.ui.PopuppableElement.prototype.getPopup = function () {
        return this.popup;
@@ -2597,8 +2606,6 @@ OO.ui.PopuppableElement.prototype.getPopup = function () {
 
 /**
  * Show popup.
- *
- * @method
  */
 OO.ui.PopuppableElement.prototype.showPopup = function () {
        this.popup.show().display( this.popupWidth, this.popupHeight );
@@ -2606,8 +2613,6 @@ OO.ui.PopuppableElement.prototype.showPopup = function () {
 
 /**
  * Hide popup.
- *
- * @method
  */
 OO.ui.PopuppableElement.prototype.hidePopup = function () {
        this.popup.hide();
@@ -2615,8 +2620,8 @@ OO.ui.PopuppableElement.prototype.hidePopup = function () {
 /**
  * Element with a title.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {jQuery} $label Titled node, assigned to #$titled
@@ -2655,7 +2660,6 @@ OO.ui.TitledElement.static.title = null;
 /**
  * Set title.
  *
- * @method
  * @param {string|Function|null} title Title text, a function that returns text or null for no title
  * @chainable
  */
@@ -2674,8 +2678,7 @@ OO.ui.TitledElement.prototype.setTitle = function ( title ) {
 /**
  * Get title.
  *
- * @method
- * @returns {string} Title string
+ * @return {string} Title string
  */
 OO.ui.TitledElement.prototype.getTitle = function () {
        return this.title;
@@ -2753,8 +2756,8 @@ OO.ui.Tool.static.tagName = 'span';
  *
  * @abstract
  * @static
- * @property {string}
  * @inheritable
+ * @property {string}
  */
 OO.ui.Tool.static.name = '';
 
@@ -2763,8 +2766,8 @@ OO.ui.Tool.static.name = '';
  *
  * @abstract
  * @static
- * @property {string}
  * @inheritable
+ * @property {string}
  */
 OO.ui.Tool.static.group = '';
 
@@ -2778,8 +2781,8 @@ OO.ui.Tool.static.group = '';
  *
  * @abstract
  * @static
- * @property {string|Function} Title text or a function that returns text
  * @inheritable
+ * @property {string|Function} Title text or a function that returns text
  */
 OO.ui.Tool.static.title = '';
 
@@ -2787,8 +2790,8 @@ OO.ui.Tool.static.title = '';
  * Tool can be automatically added to catch-all groups.
  *
  * @static
- * @property {boolean}
  * @inheritable
+ * @property {boolean}
  */
 OO.ui.Tool.static.autoAddToCatchall = true;
 
@@ -2805,7 +2808,6 @@ OO.ui.Tool.static.autoAddToGroup = true;
  * Check if this tool is compatible with given data.
  *
  * @static
- * @method
  * @inheritable
  * @param {Mixed} data Data to check
  * @return {boolean} Tool can be used with data
@@ -3332,8 +3334,8 @@ OO.mixinClass( OO.ui.ToolGroup, OO.ui.GroupElement );
  * Show labels in tooltips.
  *
  * @static
- * @property {boolean}
  * @inheritable
+ * @property {boolean}
  */
 OO.ui.ToolGroup.static.titleTooltips = false;
 
@@ -3341,8 +3343,8 @@ OO.ui.ToolGroup.static.titleTooltips = false;
  * Show acceleration labels in tooltips.
  *
  * @static
- * @property {boolean}
  * @inheritable
+ * @property {boolean}
  */
 OO.ui.ToolGroup.static.accelTooltips = false;
 
@@ -3350,8 +3352,8 @@ OO.ui.ToolGroup.static.accelTooltips = false;
  * Automatically disable the toolgroup when all tools are disabled
  *
  * @static
- * @property {boolean}
  * @inheritable
+ * @property {boolean}
  */
 OO.ui.ToolGroup.static.autoDisable = true;
 
@@ -3599,6 +3601,7 @@ OO.inheritClass( OO.ui.ToolGroupFactory, OO.Factory );
 
 /**
  * Get a default set of classes to be registered on construction
+ *
  * @return {Function[]} Default classes
  */
 OO.ui.ToolGroupFactory.static.getDefaultClasses = function () {
@@ -3726,7 +3729,6 @@ OO.ui.FieldLayout.prototype.onFieldDisable = function ( value ) {
 /**
  * Handle label mouse click events.
  *
- * @method
  * @param {jQuery.Event} e Mouse click event
  */
 OO.ui.FieldLayout.prototype.onLabelClick = function () {
@@ -3737,7 +3739,7 @@ OO.ui.FieldLayout.prototype.onLabelClick = function () {
 /**
  * Get the field.
  *
- * @returns {OO.ui.Widget} Field widget
+ * @return {OO.ui.Widget} Field widget
  */
 OO.ui.FieldLayout.prototype.getField = function () {
        return this.field;
@@ -3838,7 +3840,6 @@ OO.ui.GridLayout.static.tagName = 'div';
 /**
  * Set grid dimensions.
  *
- * @method
  * @param {number[]} widths Widths of columns as ratios
  * @param {number[]} heights Heights of rows as ratios
  * @fires layout
@@ -3880,7 +3881,6 @@ OO.ui.GridLayout.prototype.layout = function ( widths, heights ) {
 /**
  * Update panel positions and sizes.
  *
- * @method
  * @fires update
  */
 OO.ui.GridLayout.prototype.update = function () {
@@ -3926,10 +3926,9 @@ OO.ui.GridLayout.prototype.update = function () {
  *
  * The x and y position is affected by the current grid layout.
  *
- * @method
  * @param {number} x Horizontal position
  * @param {number} y Vertical position
- * @returns {OO.ui.PanelLayout} The panel at the given postion
+ * @return {OO.ui.PanelLayout} The panel at the given postion
  */
 OO.ui.GridLayout.prototype.getPanel = function ( x, y ) {
        return this.panels[( x * this.widths.length ) + y];
@@ -4036,7 +4035,6 @@ OO.inheritClass( OO.ui.BookletLayout, OO.ui.Layout );
 /**
  * Handle stack layout focus.
  *
- * @method
  * @param {jQuery.Event} e Focusin event
  */
 OO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {
@@ -4059,7 +4057,6 @@ OO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {
 /**
  * Handle stack layout set events.
  *
- * @method
  * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel
  */
 OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
@@ -4078,7 +4075,6 @@ OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
 /**
  * Handle outline widget select events.
  *
- * @method
  * @param {OO.ui.OptionWidget|null} item Selected item
  */
 OO.ui.BookletLayout.prototype.onOutlineWidgetSelect = function ( item ) {
@@ -4090,8 +4086,7 @@ OO.ui.BookletLayout.prototype.onOutlineWidgetSelect = function ( item ) {
 /**
  * Check if booklet has an outline.
  *
- * @method
- * @returns {boolean} Booklet is outlined
+ * @return {boolean}
  */
 OO.ui.BookletLayout.prototype.isOutlined = function () {
        return this.outlined;
@@ -4100,18 +4095,16 @@ OO.ui.BookletLayout.prototype.isOutlined = function () {
 /**
  * Check if booklet has editing controls.
  *
- * @method
- * @returns {boolean} Booklet is outlined
+ * @return {boolean}
  */
 OO.ui.BookletLayout.prototype.isEditable = function () {
        return this.editable;
 };
 
 /**
- * Check if booklet has editing controls.
+ * Check if booklet has a visible outline.
  *
- * @method
- * @returns {boolean} Booklet is outlined
+ * @return {boolean}
  */
 OO.ui.BookletLayout.prototype.isOutlineVisible = function () {
        return this.outlined && this.outlineVisible;
@@ -4136,9 +4129,8 @@ OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
 /**
  * Get the outline widget.
  *
- * @method
  * @param {OO.ui.PageLayout} page Page to be selected
- * @returns {OO.ui.PageLayout|null} Closest page to another
+ * @return {OO.ui.PageLayout|null} Closest page to another
  */
 OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) {
        var next, prev, level,
@@ -4171,8 +4163,7 @@ OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) {
 /**
  * Get the outline widget.
  *
- * @method
- * @returns {OO.ui.OutlineWidget|null} Outline widget, or null if boolet has no outline
+ * @return {OO.ui.OutlineWidget|null} Outline widget, or null if boolet has no outline
  */
 OO.ui.BookletLayout.prototype.getOutline = function () {
        return this.outlineWidget;
@@ -4181,8 +4172,7 @@ OO.ui.BookletLayout.prototype.getOutline = function () {
 /**
  * Get the outline controls widget. If the outline is not editable, null is returned.
  *
- * @method
- * @returns {OO.ui.OutlineControlsWidget|null} The outline controls widget.
+ * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget.
  */
 OO.ui.BookletLayout.prototype.getOutlineControls = function () {
        return this.outlineControlsWidget;
@@ -4191,9 +4181,8 @@ OO.ui.BookletLayout.prototype.getOutlineControls = function () {
 /**
  * Get a page by name.
  *
- * @method
  * @param {string} name Symbolic name of page
- * @returns {OO.ui.PageLayout|undefined} Page, if found
+ * @return {OO.ui.PageLayout|undefined} Page, if found
  */
 OO.ui.BookletLayout.prototype.getPage = function ( name ) {
        return this.pages[name];
@@ -4202,8 +4191,7 @@ OO.ui.BookletLayout.prototype.getPage = function ( name ) {
 /**
  * Get the current page name.
  *
- * @method
- * @returns {string|null} Current page name
+ * @return {string|null} Current page name
  */
 OO.ui.BookletLayout.prototype.getPageName = function () {
        return this.currentPageName;
@@ -4215,7 +4203,6 @@ OO.ui.BookletLayout.prototype.getPageName = function () {
  * When pages are added with the same names as existing pages, the existing pages will be
  * automatically removed before the new pages are added.
  *
- * @method
  * @param {OO.ui.PageLayout[]} pages Pages to add
  * @param {number} index Index to insert pages after
  * @fires add
@@ -4270,7 +4257,6 @@ OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
 /**
  * Remove a page from the layout.
  *
- * @method
  * @fires remove
  * @chainable
  */
@@ -4300,7 +4286,6 @@ OO.ui.BookletLayout.prototype.removePages = function ( pages ) {
 /**
  * Clear all pages from the layout.
  *
- * @method
  * @fires remove
  * @chainable
  */
@@ -4326,7 +4311,6 @@ OO.ui.BookletLayout.prototype.clearPages = function () {
 /**
  * Set the current page by name.
  *
- * @method
  * @fires set
  * @param {string} name Symbolic name of page
  */
@@ -4356,7 +4340,6 @@ OO.ui.BookletLayout.prototype.setPage = function ( name ) {
 /**
  * Call this after adding or removing items from the OutlineWidget.
  *
- * @method
  * @chainable
  */
 OO.ui.BookletLayout.prototype.updateOutlineWidget = function () {
@@ -4445,7 +4428,7 @@ OO.inheritClass( OO.ui.PageLayout, OO.ui.PanelLayout );
 /**
  * Get page name.
  *
- * @returns {string} Symbolic name of page
+ * @return {string} Symbolic name of page
  */
 OO.ui.PageLayout.prototype.getName = function () {
        return this.name;
@@ -4454,7 +4437,7 @@ OO.ui.PageLayout.prototype.getName = function () {
 /**
  * Check if page is active.
  *
- * @returns {boolean} Page is active
+ * @return {boolean} Page is active
  */
 OO.ui.PageLayout.prototype.isActive = function () {
        return this.active;
@@ -4463,7 +4446,7 @@ OO.ui.PageLayout.prototype.isActive = function () {
 /**
  * Get outline item.
  *
- * @returns {OO.ui.OutlineItemWidget|null} Outline item widget
+ * @return {OO.ui.OutlineItemWidget|null} Outline item widget
  */
 OO.ui.PageLayout.prototype.getOutlineItem = function () {
        return this.outlineItem;
@@ -4551,7 +4534,6 @@ OO.mixinClass( OO.ui.StackLayout, OO.ui.GroupElement );
  *
  * Adding an existing item (by value) will move it.
  *
- * @method
  * @param {OO.ui.PanelLayout[]} items Items to add
  * @param {number} [index] Index to insert items after
  * @chainable
@@ -4571,7 +4553,6 @@ OO.ui.StackLayout.prototype.addItems = function ( items, index ) {
  *
  * Items will be detached, not removed, so they can be used later.
  *
- * @method
  * @param {OO.ui.PanelLayout[]} items Items to remove
  * @chainable
  */
@@ -4592,7 +4573,6 @@ OO.ui.StackLayout.prototype.removeItems = function ( items ) {
  *
  * Items will be detached, not removed, so they can be used later.
  *
- * @method
  * @chainable
  */
 OO.ui.StackLayout.prototype.clearItems = function () {
@@ -4607,7 +4587,6 @@ OO.ui.StackLayout.prototype.clearItems = function () {
  *
  * Any currently shown item will be hidden.
  *
- * @method
  * @param {OO.ui.PanelLayout} item Item to show
  * @chainable
  */
@@ -4632,8 +4611,8 @@ OO.ui.StackLayout.prototype.setItem = function ( item ) {
 /**
  * Horizontal bar layout of tools as icon buttons.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.ToolGroup
  *
  * @constructor
@@ -4662,8 +4641,8 @@ OO.ui.BarToolGroup.static.name = 'bar';
 /**
  * Popup list of tools with an icon and optional label.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.ToolGroup
  * @mixins OO.ui.IconedElement
  * @mixins OO.ui.IndicatedElement
@@ -4740,7 +4719,6 @@ OO.ui.PopupToolGroup.prototype.setDisabled = function () {
  *
  * The event is actually generated from a mouseup, so it is not a normal blur event object.
  *
- * @method
  * @param {jQuery.Event} e Mouse up event
  */
 OO.ui.PopupToolGroup.prototype.onBlur = function ( e ) {
@@ -4763,7 +4741,6 @@ OO.ui.PopupToolGroup.prototype.onMouseUp = function ( e ) {
 /**
  * Handle mouse up events.
  *
- * @method
  * @param {jQuery.Event} e Mouse up event
  */
 OO.ui.PopupToolGroup.prototype.onHandleMouseUp = function () {
@@ -4773,7 +4750,6 @@ OO.ui.PopupToolGroup.prototype.onHandleMouseUp = function () {
 /**
  * Handle mouse down events.
  *
- * @method
  * @param {jQuery.Event} e Mouse down event
  */
 OO.ui.PopupToolGroup.prototype.onHandleMouseDown = function ( e ) {
@@ -4787,8 +4763,6 @@ OO.ui.PopupToolGroup.prototype.onHandleMouseDown = function ( e ) {
  * Switch into active mode.
  *
  * When active, mouseup events anywhere in the document will trigger deactivation.
- *
- * @method
  */
 OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
        value = !!value;
@@ -4808,8 +4782,8 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
 /**
  * Drop down list layout of tools as labeled icon buttons.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.PopupToolGroup
  *
  * @constructor
@@ -4836,8 +4810,8 @@ OO.ui.ListToolGroup.static.name = 'list';
 /**
  * Drop down menu layout of tools as selectable menu items.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.PopupToolGroup
  *
  * @constructor
@@ -4875,8 +4849,6 @@ OO.ui.MenuToolGroup.static.name = 'menu';
  *
  * When the state changes, the title of each active item in the menu will be joined together and
  * used as a label for the group. The label will be empty if none of the items are active.
- *
- * @method
  */
 OO.ui.MenuToolGroup.prototype.onUpdateState = function () {
        var name,
@@ -4954,8 +4926,8 @@ OO.ui.PopupTool.prototype.onUpdateState = function () {
  *
  * Use together with OO.ui.ItemWidget to make disabled state inheritable.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.GroupElement
  *
  * @constructor
@@ -4978,7 +4950,6 @@ OO.inheritClass( OO.ui.GroupWidget, OO.ui.GroupElement );
  *
  * This will also update the disabled state of child widgets.
  *
- * @method
  * @param {boolean} disabled Disable widget
  * @chainable
  */
@@ -5004,8 +4975,8 @@ OO.ui.GroupWidget.prototype.setDisabled = function ( disabled ) {
  *
  * Use together with OO.ui.GroupWidget to make disabled state inheritable.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  */
@@ -5020,7 +4991,7 @@ OO.ui.ItemWidget = function OoUiItemWidget() {
  *
  * Checks parent if present, making disabled state inheritable.
  *
- * @returns {boolean} Widget is disabled
+ * @return {boolean} Widget is disabled
  */
 OO.ui.ItemWidget.prototype.isDisabled = function () {
        return this.disabled ||
@@ -5146,8 +5117,8 @@ OO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.GroupElement );
 /**
  * Button widget.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.ButtonedElement
  * @mixins OO.ui.IconedElement
@@ -5216,7 +5187,6 @@ OO.mixinClass( OO.ui.ButtonWidget, OO.ui.FlaggableElement );
 /**
  * Handles mouse click events.
  *
- * @method
  * @param {jQuery.Event} e Mouse click event
  * @fires click
  */
@@ -5233,7 +5203,6 @@ OO.ui.ButtonWidget.prototype.onClick = function () {
 /**
  * Handles keypress events.
  *
- * @method
  * @param {jQuery.Event} e Keypress event
  * @fires click
  */
@@ -5249,8 +5218,8 @@ OO.ui.ButtonWidget.prototype.onKeyPress = function ( e ) {
 /**
  * Input widget.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Widget
  *
  * @constructor
@@ -5301,9 +5270,8 @@ OO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );
 /**
  * Get input element.
  *
- * @method
  * @param {Object} [config] Configuration options
- * @returns {jQuery} Input element
+ * @return {jQuery} Input element
  */
 OO.ui.InputWidget.prototype.getInputElement = function () {
        return this.$( '<input>' );
@@ -5312,7 +5280,6 @@ OO.ui.InputWidget.prototype.getInputElement = function () {
 /**
  * Handle potentially value-changing events.
  *
- * @method
  * @param {jQuery.Event} e Key down, mouse up, cut, paste, change, input, or select event
  */
 OO.ui.InputWidget.prototype.onEdit = function () {
@@ -5327,8 +5294,7 @@ OO.ui.InputWidget.prototype.onEdit = function () {
 /**
  * Get the value of the input.
  *
- * @method
- * @returns {string} Input value
+ * @return {string} Input value
  */
 OO.ui.InputWidget.prototype.getValue = function () {
        return this.value;
@@ -5337,7 +5303,6 @@ OO.ui.InputWidget.prototype.getValue = function () {
 /**
  * Sets the direction of the current input, either RTL or LTR
  *
- * @method
  * @param {boolean} isRTL
  */
 OO.ui.InputWidget.prototype.setRTL = function ( isRTL ) {
@@ -5353,7 +5318,6 @@ OO.ui.InputWidget.prototype.setRTL = function ( isRTL ) {
 /**
  * Set the value of the input.
  *
- * @method
  * @param {string} value New value
  * @fires change
  * @chainable
@@ -5377,9 +5341,8 @@ OO.ui.InputWidget.prototype.setValue = function ( value ) {
  *
  * Ensures value is a string, and converts undefined and null to empty strings.
  *
- * @method
  * @param {string} value Original value
- * @returns {string} Sanitized value
+ * @return {string} Sanitized value
  */
 OO.ui.InputWidget.prototype.sanitizeValue = function ( value ) {
        if ( value === undefined || value === null ) {
@@ -5393,8 +5356,6 @@ OO.ui.InputWidget.prototype.sanitizeValue = function ( value ) {
 
 /**
  * Simulate the behavior of clicking on a label bound to this input.
- *
- * @method
  */
 OO.ui.InputWidget.prototype.simulateLabelClick = function () {
        if ( !this.isDisabled() ) {
@@ -5409,8 +5370,7 @@ OO.ui.InputWidget.prototype.simulateLabelClick = function () {
 /**
  * Check if the widget is read-only.
  *
- * @method
- * @param {boolean} Input is read-only
+ * @return {boolean}
  */
 OO.ui.InputWidget.prototype.isReadOnly = function () {
        return this.readOnly;
@@ -5421,7 +5381,6 @@ OO.ui.InputWidget.prototype.isReadOnly = function () {
  *
  * This should probably change the widgets's appearance and prevent it from being used.
  *
- * @method
  * @param {boolean} state Make input read-only
  * @chainable
  */
@@ -5469,7 +5428,7 @@ OO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );
 /**
  * Get input element.
  *
- * @returns {jQuery} Input element
+ * @return {jQuery} Input element
  */
 OO.ui.CheckboxInputWidget.prototype.getInputElement = function () {
        return this.$( '<input type="checkbox" />' );
@@ -5478,7 +5437,7 @@ OO.ui.CheckboxInputWidget.prototype.getInputElement = function () {
 /**
  * Get checked state of the checkbox
  *
- * @returns {boolean} If the checkbox is checked
+ * @return {boolean} If the checkbox is checked
  */
 OO.ui.CheckboxInputWidget.prototype.getValue = function () {
        return this.value;
@@ -5553,7 +5512,6 @@ OO.ui.LabelWidget.static.tagName = 'label';
 /**
  * Handles label mouse click events.
  *
- * @method
  * @param {jQuery.Event} e Mouse click event
  */
 OO.ui.LabelWidget.prototype.onClick = function () {
@@ -5611,7 +5569,6 @@ OO.ui.LookupInputWidget = function OoUiLookupInputWidget( input, config ) {
 /**
  * Handle input focus event.
  *
- * @method
  * @param {jQuery.Event} e Input focus event
  */
 OO.ui.LookupInputWidget.prototype.onLookupInputFocus = function () {
@@ -5621,7 +5578,6 @@ OO.ui.LookupInputWidget.prototype.onLookupInputFocus = function () {
 /**
  * Handle input blur event.
  *
- * @method
  * @param {jQuery.Event} e Input blur event
  */
 OO.ui.LookupInputWidget.prototype.onLookupInputBlur = function () {
@@ -5631,7 +5587,6 @@ OO.ui.LookupInputWidget.prototype.onLookupInputBlur = function () {
 /**
  * Handle input mouse down event.
  *
- * @method
  * @param {jQuery.Event} e Input mouse down event
  */
 OO.ui.LookupInputWidget.prototype.onLookupInputMouseDown = function () {
@@ -5641,7 +5596,6 @@ OO.ui.LookupInputWidget.prototype.onLookupInputMouseDown = function () {
 /**
  * Handle input change event.
  *
- * @method
  * @param {string} value New input value
  */
 OO.ui.LookupInputWidget.prototype.onLookupInputChange = function () {
@@ -5651,7 +5605,6 @@ OO.ui.LookupInputWidget.prototype.onLookupInputChange = function () {
 /**
  * Open the menu.
  *
- * @method
  * @chainable
  */
 OO.ui.LookupInputWidget.prototype.openLookupMenu = function () {
@@ -5673,7 +5626,6 @@ OO.ui.LookupInputWidget.prototype.openLookupMenu = function () {
 /**
  * Populate lookup menu with current information.
  *
- * @method
  * @chainable
  */
 OO.ui.LookupInputWidget.prototype.populateLookupMenu = function () {
@@ -5704,7 +5656,6 @@ OO.ui.LookupInputWidget.prototype.populateLookupMenu = function () {
 /**
  * Set selection in the lookup menu with current information.
  *
- * @method
  * @chainable
  */
 OO.ui.LookupInputWidget.prototype.initializeLookupMenuSelection = function () {
@@ -5717,8 +5668,7 @@ OO.ui.LookupInputWidget.prototype.initializeLookupMenuSelection = function () {
 /**
  * Get lookup menu items for the current query.
  *
- * @method
- * @returns {jQuery.Promise} Promise object which will be passed menu items as the first argument
+ * @return {jQuery.Promise} Promise object which will be passed menu items as the first argument
  * of the done event
  */
 OO.ui.LookupInputWidget.prototype.getLookupMenuItems = function () {
@@ -5760,9 +5710,8 @@ OO.ui.LookupInputWidget.prototype.getLookupMenuItems = function () {
 /**
  * Get a new request object of the current lookup query value.
  *
- * @method
  * @abstract
- * @returns {jqXHR} jQuery AJAX object, or promise object with an .abort() method
+ * @return {jqXHR} jQuery AJAX object, or promise object with an .abort() method
  */
 OO.ui.LookupInputWidget.prototype.getLookupRequest = function () {
        // Stub, implemented in subclass
@@ -5775,7 +5724,6 @@ OO.ui.LookupInputWidget.prototype.getLookupRequest = function () {
  * Overriding methods should call #populateLookupMenu when results are available and cache results
  * for future lookups in #lookupCache as an array of #OO.ui.MenuItemWidget objects.
  *
- * @method
  * @abstract
  * @param {Mixed} data Response from server
  */
@@ -5786,10 +5734,9 @@ OO.ui.LookupInputWidget.prototype.onLookupRequestDone = function () {
 /**
  * Get a list of menu item widgets from the data stored by the lookup request's done handler.
  *
- * @method
  * @abstract
  * @param {Mixed} data Cached result data, usually an array
- * @returns {OO.ui.MenuItemWidget[]} Menu items
+ * @return {OO.ui.MenuItemWidget[]} Menu items
  */
 OO.ui.LookupInputWidget.prototype.getLookupMenuItemsFromData = function () {
        // Stub, implemented in subclass
@@ -5800,8 +5747,8 @@ OO.ui.LookupInputWidget.prototype.getLookupMenuItemsFromData = function () {
  *
  * Use with OO.ui.SelectWidget.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.IconedElement
  * @mixins OO.ui.LabeledElement
@@ -5870,8 +5817,7 @@ OO.ui.OptionWidget.static.scrollIntoViewOnSelect = false;
 /**
  * Check if option can be selected.
  *
- * @method
- * @returns {boolean} Item is selectable
+ * @return {boolean} Item is selectable
  */
 OO.ui.OptionWidget.prototype.isSelectable = function () {
        return this.constructor.static.selectable && !this.disabled;
@@ -5880,8 +5826,7 @@ OO.ui.OptionWidget.prototype.isSelectable = function () {
 /**
  * Check if option can be highlighted.
  *
- * @method
- * @returns {boolean} Item is highlightable
+ * @return {boolean} Item is highlightable
  */
 OO.ui.OptionWidget.prototype.isHighlightable = function () {
        return this.constructor.static.highlightable && !this.disabled;
@@ -5890,8 +5835,7 @@ OO.ui.OptionWidget.prototype.isHighlightable = function () {
 /**
  * Check if option can be pressed.
  *
- * @method
- * @returns {boolean} Item is pressable
+ * @return {boolean} Item is pressable
  */
 OO.ui.OptionWidget.prototype.isPressable = function () {
        return this.constructor.static.pressable && !this.disabled;
@@ -5900,8 +5844,7 @@ OO.ui.OptionWidget.prototype.isPressable = function () {
 /**
  * Check if option is selected.
  *
- * @method
- * @returns {boolean} Item is selected
+ * @return {boolean} Item is selected
  */
 OO.ui.OptionWidget.prototype.isSelected = function () {
        return this.selected;
@@ -5910,8 +5853,7 @@ OO.ui.OptionWidget.prototype.isSelected = function () {
 /**
  * Check if option is highlighted.
  *
- * @method
- * @returns {boolean} Item is highlighted
+ * @return {boolean} Item is highlighted
  */
 OO.ui.OptionWidget.prototype.isHighlighted = function () {
        return this.highlighted;
@@ -5920,8 +5862,7 @@ OO.ui.OptionWidget.prototype.isHighlighted = function () {
 /**
  * Check if option is pressed.
  *
- * @method
- * @returns {boolean} Item is pressed
+ * @return {boolean} Item is pressed
  */
 OO.ui.OptionWidget.prototype.isPressed = function () {
        return this.pressed;
@@ -5930,7 +5871,6 @@ OO.ui.OptionWidget.prototype.isPressed = function () {
 /**
  * Set selected state.
  *
- * @method
  * @param {boolean} [state=false] Select option
  * @chainable
  */
@@ -5952,7 +5892,6 @@ OO.ui.OptionWidget.prototype.setSelected = function ( state ) {
 /**
  * Set highlighted state.
  *
- * @method
  * @param {boolean} [state=false] Highlight option
  * @chainable
  */
@@ -5971,7 +5910,6 @@ OO.ui.OptionWidget.prototype.setHighlighted = function ( state ) {
 /**
  * Set pressed state.
  *
- * @method
  * @param {boolean} [state=false] Press option
  * @chainable
  */
@@ -5992,7 +5930,6 @@ OO.ui.OptionWidget.prototype.setPressed = function ( state ) {
  *
  * While flashing, the visual style of the pressed state is removed if present.
  *
- * @method
  * @param {Function} [done] Callback to execute when flash effect is complete.
  */
 OO.ui.OptionWidget.prototype.flash = function ( done ) {
@@ -6016,8 +5953,7 @@ OO.ui.OptionWidget.prototype.flash = function ( done ) {
 /**
  * Get option data.
  *
- * @method
- * @returns {Mixed} Option data
+ * @return {Mixed} Option data
  */
 OO.ui.OptionWidget.prototype.getData = function () {
        return this.data;
@@ -6027,8 +5963,8 @@ OO.ui.OptionWidget.prototype.getData = function () {
  *
  * Use together with OO.ui.OptionWidget.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.GroupElement
  *
@@ -6117,7 +6053,6 @@ OO.ui.SelectWidget.static.tagName = 'ul';
 /**
  * Handle mouse down events.
  *
- * @method
  * @private
  * @param {jQuery.Event} e Mouse down event
  */
@@ -6139,7 +6074,6 @@ OO.ui.SelectWidget.prototype.onMouseDown = function ( e ) {
 /**
  * Handle mouse up events.
  *
- * @method
  * @private
  * @param {jQuery.Event} e Mouse up event
  */
@@ -6165,7 +6099,6 @@ OO.ui.SelectWidget.prototype.onMouseUp = function ( e ) {
 /**
  * Handle mouse move events.
  *
- * @method
  * @private
  * @param {jQuery.Event} e Mouse move event
  */
@@ -6185,7 +6118,6 @@ OO.ui.SelectWidget.prototype.onMouseMove = function ( e ) {
 /**
  * Handle mouse over events.
  *
- * @method
  * @private
  * @param {jQuery.Event} e Mouse over event
  */
@@ -6202,7 +6134,6 @@ OO.ui.SelectWidget.prototype.onMouseOver = function ( e ) {
 /**
  * Handle mouse leave events.
  *
- * @method
  * @private
  * @param {jQuery.Event} e Mouse over event
  */
@@ -6216,10 +6147,9 @@ OO.ui.SelectWidget.prototype.onMouseLeave = function () {
 /**
  * Get the closest item to a jQuery.Event.
  *
- * @method
  * @private
  * @param {jQuery.Event} e
- * @returns {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found
+ * @return {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found
  */
 OO.ui.SelectWidget.prototype.getTargetItem = function ( e ) {
        var $item = this.$( e.target ).closest( '.oo-ui-optionWidget' );
@@ -6232,8 +6162,7 @@ OO.ui.SelectWidget.prototype.getTargetItem = function ( e ) {
 /**
  * Get selected item.
  *
- * @method
- * @returns {OO.ui.OptionWidget|null} Selected item, `null` if no item is selected
+ * @return {OO.ui.OptionWidget|null} Selected item, `null` if no item is selected
  */
 OO.ui.SelectWidget.prototype.getSelectedItem = function () {
        var i, len;
@@ -6249,8 +6178,7 @@ OO.ui.SelectWidget.prototype.getSelectedItem = function () {
 /**
  * Get highlighted item.
  *
- * @method
- * @returns {OO.ui.OptionWidget|null} Highlighted item, `null` if no item is highlighted
+ * @return {OO.ui.OptionWidget|null} Highlighted item, `null` if no item is highlighted
  */
 OO.ui.SelectWidget.prototype.getHighlightedItem = function () {
        var i, len;
@@ -6266,9 +6194,8 @@ OO.ui.SelectWidget.prototype.getHighlightedItem = function () {
 /**
  * Get an existing item with equivilant data.
  *
- * @method
  * @param {Object} data Item data to search for
- * @returns {OO.ui.OptionWidget|null} Item with equivilent value, `null` if none exists
+ * @return {OO.ui.OptionWidget|null} Item with equivilent value, `null` if none exists
  */
 OO.ui.SelectWidget.prototype.getItemFromData = function ( data ) {
        var hash = OO.getHash( data );
@@ -6301,7 +6228,6 @@ OO.ui.SelectWidget.prototype.togglePressed = function ( pressed ) {
  *
  * Highlighting is mutually exclusive.
  *
- * @method
  * @param {OO.ui.OptionWidget} [item] Item to highlight, omit to deselect all
  * @fires highlight
  * @chainable
@@ -6327,7 +6253,6 @@ OO.ui.SelectWidget.prototype.highlightItem = function ( item ) {
 /**
  * Select an item.
  *
- * @method
  * @param {OO.ui.OptionWidget} [item] Item to select, omit to deselect all
  * @fires select
  * @chainable
@@ -6353,7 +6278,6 @@ OO.ui.SelectWidget.prototype.selectItem = function ( item ) {
 /**
  * Press an item.
  *
- * @method
  * @param {OO.ui.OptionWidget} [item] Item to press, omit to depress all
  * @fires press
  * @chainable
@@ -6382,7 +6306,6 @@ OO.ui.SelectWidget.prototype.pressItem = function ( item ) {
  * Identical to #selectItem, but may vary in subclasses that want to take additional action when
  * an item is selected using the keyboard or mouse.
  *
- * @method
  * @param {OO.ui.OptionWidget} item Item to choose
  * @fires choose
  * @chainable
@@ -6397,10 +6320,9 @@ OO.ui.SelectWidget.prototype.chooseItem = function ( item ) {
 /**
  * Get an item relative to another one.
  *
- * @method
  * @param {OO.ui.OptionWidget} item Item to start at
  * @param {number} direction Direction to move in
- * @returns {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the menu
+ * @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the menu
  */
 OO.ui.SelectWidget.prototype.getRelativeSelectableItem = function ( item, direction ) {
        var inc = direction > 0 ? 1 : -1,
@@ -6431,8 +6353,7 @@ OO.ui.SelectWidget.prototype.getRelativeSelectableItem = function ( item, direct
 /**
  * Get the next selectable item.
  *
- * @method
- * @returns {OO.ui.OptionWidget|null} Item, `null` if ther aren't any selectable items
+ * @return {OO.ui.OptionWidget|null} Item, `null` if ther aren't any selectable items
  */
 OO.ui.SelectWidget.prototype.getFirstSelectableItem = function () {
        var i, len, item;
@@ -6453,7 +6374,6 @@ OO.ui.SelectWidget.prototype.getFirstSelectableItem = function () {
  * When items are added with the same values as existing items, the existing items will be
  * automatically removed before the new items are added.
  *
- * @method
  * @param {OO.ui.OptionWidget[]} items Items to add
  * @param {number} [index] Index to insert items after
  * @fires add
@@ -6489,7 +6409,6 @@ OO.ui.SelectWidget.prototype.addItems = function ( items, index ) {
  *
  * Items will be detached, not removed, so they can be used later.
  *
- * @method
  * @param {OO.ui.OptionWidget[]} items Items to remove
  * @fires remove
  * @chainable
@@ -6520,7 +6439,6 @@ OO.ui.SelectWidget.prototype.removeItems = function ( items ) {
  *
  * Items will be detached, not removed, so they can be used later.
  *
- * @method
  * @fires remove
  * @chainable
  */
@@ -6608,7 +6526,6 @@ OO.mixinClass( OO.ui.MenuWidget, OO.ui.ClippableElement );
 /**
  * Handles key down events.
  *
- * @method
  * @param {jQuery.Event} e Key down event
  */
 OO.ui.MenuWidget.prototype.onKeyDown = function ( e ) {
@@ -6658,17 +6575,14 @@ OO.ui.MenuWidget.prototype.onKeyDown = function ( e ) {
 /**
  * Check if the menu is visible.
  *
- * @method
- * @returns {boolean} Menu is visible
+ * @return {boolean} Menu is visible
  */
 OO.ui.MenuWidget.prototype.isVisible = function () {
        return this.visible;
 };
 
 /**
- * Bind key down listener
- *
- * @method
+ * Bind key down listener.
  */
 OO.ui.MenuWidget.prototype.bindKeyDownListener = function () {
        if ( this.$input ) {
@@ -6680,9 +6594,7 @@ OO.ui.MenuWidget.prototype.bindKeyDownListener = function () {
 };
 
 /**
- * Unbind key down listener
- *
- * @method
+ * Unbind key down listener.
  */
 OO.ui.MenuWidget.prototype.unbindKeyDownListener = function () {
        if ( this.$input ) {
@@ -6697,7 +6609,6 @@ OO.ui.MenuWidget.prototype.unbindKeyDownListener = function () {
  *
  * This will close the menu when done, unlike selectItem which only changes selection.
  *
- * @method
  * @param {OO.ui.OptionWidget} item Item to choose
  * @chainable
  */
@@ -6723,7 +6634,6 @@ OO.ui.MenuWidget.prototype.chooseItem = function ( item ) {
  *
  * Adding an existing item (by value) will move it.
  *
- * @method
  * @param {OO.ui.MenuItemWidget[]} items Items to add
  * @param {number} [index] Index to insert items after
  * @chainable
@@ -6755,7 +6665,6 @@ OO.ui.MenuWidget.prototype.addItems = function ( items, index ) {
 /**
  * Show the menu.
  *
- * @method
  * @chainable
  */
 OO.ui.MenuWidget.prototype.show = function () {
@@ -6787,7 +6696,6 @@ OO.ui.MenuWidget.prototype.show = function () {
 /**
  * Hide the menu.
  *
- * @method
  * @chainable
  */
 OO.ui.MenuWidget.prototype.hide = function () {
@@ -6872,7 +6780,6 @@ OO.ui.InlineMenuWidget.prototype.getMenu = function () {
 /**
  * Handles menu select events.
  *
- * @method
  * @param {OO.ui.MenuItemWidget} item Selected menu item
  */
 OO.ui.InlineMenuWidget.prototype.onMenuSelect = function ( item ) {
@@ -6895,7 +6802,6 @@ OO.ui.InlineMenuWidget.prototype.onMenuSelect = function ( item ) {
 /**
  * Handles mouse click events.
  *
- * @method
  * @param {jQuery.Event} e Mouse click event
  */
 OO.ui.InlineMenuWidget.prototype.onClick = function ( e ) {
@@ -7051,8 +6957,6 @@ OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.IconedElement );
 
 /**
  * Handle outline change events.
- *
- * @method
  */
 OO.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {
        var i, len, firstMovable, lastMovable,
@@ -7134,7 +7038,7 @@ OO.ui.OutlineItemWidget.static.levels = 3;
  *
  * Movablilty is used by outline controls.
  *
- * @returns {boolean} Item is movable
+ * @return {boolean} Item is movable
  */
 OO.ui.OutlineItemWidget.prototype.isMovable = function () {
        return this.movable;
@@ -7145,7 +7049,7 @@ OO.ui.OutlineItemWidget.prototype.isMovable = function () {
  *
  * Removablilty is used by outline controls.
  *
- * @returns {boolean} Item is removable
+ * @return {boolean} Item is removable
  */
 OO.ui.OutlineItemWidget.prototype.isRemovable = function () {
        return this.removable;
@@ -7154,7 +7058,7 @@ OO.ui.OutlineItemWidget.prototype.isRemovable = function () {
 /**
  * Get indentation level.
  *
- * @returns {number} Indentation level
+ * @return {number} Indentation level
  */
 OO.ui.OutlineItemWidget.prototype.getLevel = function () {
        return this.level;
@@ -7189,7 +7093,6 @@ OO.ui.OutlineItemWidget.prototype.setRemovable = function ( removable ) {
 /**
  * Set indentation level.
  *
- * @method
  * @param {number} [level=0] Indentation level, in the range of [0,#maxLevel]
  * @chainable
  */
@@ -7361,7 +7264,6 @@ OO.mixinClass( OO.ui.PopupWidget, OO.ui.ClippableElement );
 /**
  * Handles mouse down events.
  *
- * @method
  * @param {jQuery.Event} e Mouse down event
  */
 OO.ui.PopupWidget.prototype.onMouseDown = function ( e ) {
@@ -7375,9 +7277,7 @@ OO.ui.PopupWidget.prototype.onMouseDown = function ( e ) {
 };
 
 /**
- * Bind mouse down listener
- *
- * @method
+ * Bind mouse down listener.
  */
 OO.ui.PopupWidget.prototype.bindMouseDownListener = function () {
        // Capture clicks outside popup
@@ -7386,8 +7286,6 @@ OO.ui.PopupWidget.prototype.bindMouseDownListener = function () {
 
 /**
  * Handles close button click events.
- *
- * @method
  */
 OO.ui.PopupWidget.prototype.onCloseButtonClick = function () {
        if ( this.visible ) {
@@ -7396,9 +7294,7 @@ OO.ui.PopupWidget.prototype.onCloseButtonClick = function () {
 };
 
 /**
- * Unbind mouse down listener
- *
- * @method
+ * Unbind mouse down listener.
  */
 OO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {
        this.getElementWindow().removeEventListener( 'mousedown', this.onMouseDownHandler, true );
@@ -7407,8 +7303,7 @@ OO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {
 /**
  * Check if the popup is visible.
  *
- * @method
- * @returns {boolean} Popup is visible
+ * @return {boolean} Popup is visible
  */
 OO.ui.PopupWidget.prototype.isVisible = function () {
        return this.visible;
@@ -7417,8 +7312,7 @@ OO.ui.PopupWidget.prototype.isVisible = function () {
 /**
  * Set whether to show a tail.
  *
- * @method
- * @returns {boolean} Make tail visible
+ * @return {boolean} Make tail visible
  */
 OO.ui.PopupWidget.prototype.useTail = function ( value ) {
        value = !!value;
@@ -7435,8 +7329,7 @@ OO.ui.PopupWidget.prototype.useTail = function ( value ) {
 /**
  * Check if showing a tail.
  *
- * @method
- * @returns {boolean} tail is visible
+ * @return {boolean} tail is visible
  */
 OO.ui.PopupWidget.prototype.hasTail = function () {
        return this.tail;
@@ -7445,7 +7338,6 @@ OO.ui.PopupWidget.prototype.hasTail = function () {
 /**
  * Show the context.
  *
- * @method
  * @fires show
  * @chainable
  */
@@ -7465,7 +7357,6 @@ OO.ui.PopupWidget.prototype.show = function () {
 /**
  * Hide the context.
  *
- * @method
  * @fires hide
  * @chainable
  */
@@ -7485,7 +7376,6 @@ OO.ui.PopupWidget.prototype.hide = function () {
 /**
  * Updates the position and size.
  *
- * @method
  * @param {number} width Width
  * @param {number} height Height
  * @param {boolean} [transition=false] Use a smooth transition
@@ -7568,7 +7458,6 @@ OO.mixinClass( OO.ui.PopupButtonWidget, OO.ui.PopuppableElement );
 /**
  * Handles mouse click events.
  *
- * @method
  * @param {jQuery.Event} e Mouse click event
  */
 OO.ui.PopupButtonWidget.prototype.onClick = function ( e ) {
@@ -7662,7 +7551,6 @@ OO.inheritClass( OO.ui.SearchWidget, OO.ui.Widget );
 /**
  * Handle query key down events.
  *
- * @method
  * @param {jQuery.Event} e Key down event
  */
 OO.ui.SearchWidget.prototype.onQueryKeydown = function ( e ) {
@@ -7685,7 +7573,6 @@ OO.ui.SearchWidget.prototype.onQueryKeydown = function ( e ) {
  *
  * Clears existing results. Subclasses should repopulate items according to new query.
  *
- * @method
  * @param {string} value New value
  */
 OO.ui.SearchWidget.prototype.onQueryChange = function () {
@@ -7698,7 +7585,6 @@ OO.ui.SearchWidget.prototype.onQueryChange = function () {
  *
  * Selects highlighted item.
  *
- * @method
  * @param {string} value New value
  */
 OO.ui.SearchWidget.prototype.onQueryEnter = function () {
@@ -7709,7 +7595,6 @@ OO.ui.SearchWidget.prototype.onQueryEnter = function () {
 /**
  * Handle select widget highlight events.
  *
- * @method
  * @param {OO.ui.OptionWidget} item Highlighted item
  * @fires highlight
  */
@@ -7720,7 +7605,6 @@ OO.ui.SearchWidget.prototype.onResultsHighlight = function ( item ) {
 /**
  * Handle select widget select events.
  *
- * @method
  * @param {OO.ui.OptionWidget} item Selected item
  * @fires select
  */
@@ -7731,8 +7615,7 @@ OO.ui.SearchWidget.prototype.onResultsSelect = function ( item ) {
 /**
  * Get the query input.
  *
- * @method
- * @returns {OO.ui.TextInputWidget} Query input
+ * @return {OO.ui.TextInputWidget} Query input
  */
 OO.ui.SearchWidget.prototype.getQuery = function () {
        return this.query;
@@ -7748,8 +7631,7 @@ OO.ui.SearchWidget.prototype.clear = function () {
 /**
  * Get the results list.
  *
- * @method
- * @returns {OO.ui.SelectWidget} Select list
+ * @return {OO.ui.SelectWidget} Select list
  */
 OO.ui.SearchWidget.prototype.getResults = function () {
        return this.results;
@@ -7819,7 +7701,7 @@ OO.inheritClass( OO.ui.TextInputWidget, OO.ui.InputWidget );
 /* Methods */
 
 /**
- * Handles key press events.
+ * Handle key press events.
  *
  * @param {jQuery.Event} e Key press event
  * @fires enter If enter key is pressed and input is not multiline
@@ -7831,7 +7713,7 @@ OO.ui.TextInputWidget.prototype.onKeyPress = function ( e ) {
 };
 
 /**
- * Handles element attach events.
+ * Handle element attach events.
  *
  * @param {jQuery.Event} e Element attach event
  */
@@ -7889,9 +7771,8 @@ OO.ui.TextInputWidget.prototype.adjustSize = function () {
 /**
  * Get input element.
  *
- * @method
  * @param {Object} [config] Configuration options
- * @returns {jQuery} Input element
+ * @return {jQuery} Input element
  */
 OO.ui.TextInputWidget.prototype.getInputElement = function ( config ) {
        return config.multiline ? this.$( '<textarea>' ) : this.$( '<input type="text" />' );
@@ -7900,39 +7781,35 @@ OO.ui.TextInputWidget.prototype.getInputElement = function ( config ) {
 /* Methods */
 
 /**
- * Checks if input supports multiple lines.
+ * Check if input supports multiple lines.
  *
- * @method
- * @returns {boolean} Input supports multiple lines
+ * @return {boolean}
  */
 OO.ui.TextInputWidget.prototype.isMultiline = function () {
        return !!this.multiline;
 };
 
 /**
- * Checks if input automatically adjusts its size.
+ * Check if input automatically adjusts its size.
  *
- * @method
- * @returns {boolean} Input automatically adjusts its size
+ * @return {boolean}
  */
 OO.ui.TextInputWidget.prototype.isAutosizing = function () {
        return !!this.autosize;
 };
 
 /**
- * Checks if input is pending.
+ * Check if input is pending.
  *
- * @method
- * @returns {boolean} Input is pending
+ * @return {boolean}
  */
 OO.ui.TextInputWidget.prototype.isPending = function () {
        return !!this.pending;
 };
 
 /**
- * Increases the pending stack.
+ * Increase the pending stack.
  *
- * @method
  * @chainable
  */
 OO.ui.TextInputWidget.prototype.pushPending = function () {
@@ -7943,11 +7820,10 @@ OO.ui.TextInputWidget.prototype.pushPending = function () {
 };
 
 /**
- * Reduces the pending stack.
+ * Reduce the pending stack.
  *
  * Clamped at zero.
  *
- * @method
  * @chainable
  */
 OO.ui.TextInputWidget.prototype.popPending = function () {
@@ -7991,7 +7867,6 @@ OO.inheritClass( OO.ui.TextInputMenuWidget, OO.ui.MenuWidget );
 /**
  * Handle window resize event.
  *
- * @method
  * @param {jQuery.Event} e Window resize event
  */
 OO.ui.TextInputMenuWidget.prototype.onWindowResize = function () {
@@ -7999,9 +7874,8 @@ OO.ui.TextInputMenuWidget.prototype.onWindowResize = function () {
 };
 
 /**
- * Shows the menu.
+ * Show the menu.
  *
- * @method
  * @chainable
  */
 OO.ui.TextInputMenuWidget.prototype.show = function () {
@@ -8014,9 +7888,8 @@ OO.ui.TextInputMenuWidget.prototype.show = function () {
 };
 
 /**
- * Hides the menu.
+ * Hide the menu.
  *
- * @method
  * @chainable
  */
 OO.ui.TextInputMenuWidget.prototype.hide = function () {
@@ -8028,9 +7901,8 @@ OO.ui.TextInputMenuWidget.prototype.hide = function () {
 };
 
 /**
- * Positions the menu.
+ * Position the menu.
  *
- * @method
  * @chainable
  */
 OO.ui.TextInputMenuWidget.prototype.position = function () {
@@ -8067,8 +7939,8 @@ OO.ui.TextInputMenuWidget.prototype.position = function () {
  *
  * Mixin for widgets with a boolean state.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -8098,8 +7970,7 @@ OO.ui.ToggleWidget = function OoUiToggleWidget( config ) {
 /**
  * Get the value of the toggle.
  *
- * @method
- * @returns {boolean} Toggle value
+ * @return {boolean}
  */
 OO.ui.ToggleWidget.prototype.getValue = function () {
        return this.value;
@@ -8108,7 +7979,6 @@ OO.ui.ToggleWidget.prototype.getValue = function () {
 /**
  * Set the value of the toggle.
  *
- * @method
  * @param {boolean} value New value
  * @fires change
  * @chainable
@@ -8184,8 +8054,8 @@ OO.ui.ToggleButtonWidget.prototype.setValue = function ( value ) {
 /**
  * Switch that slides on and off.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.ToggleWidget
  *
@@ -8226,9 +8096,8 @@ OO.mixinClass( OO.ui.ToggleSwitchWidget, OO.ui.ToggleWidget );
 /* Methods */
 
 /**
- * Handles mouse down events.
+ * Handle mouse down events.
  *
- * @method
  * @param {jQuery.Event} e Mouse down event
  */
 OO.ui.ToggleSwitchWidget.prototype.onClick = function ( e ) {
index b2ba750..7a7cffa 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (ac6848398c)
+ * OOjs UI v0.1.0-pre (eca1fc20e7)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Wed Apr 09 2014 17:58:17 GMT-0700 (PDT)
+ * Date: Fri Apr 11 2014 16:47:56 GMT-0700 (PDT)
  */
 
 /* Textures */
   background: none;
 }
 
+.oo-ui-frame-content:focus {
+  outline: none;
+}
+
 .oo-ui-toolbar {
   clear: both;
 }
diff --git a/resources/src/jquery/jquery.delayedBind.js b/resources/src/jquery/jquery.delayedBind.js
deleted file mode 100644 (file)
index 874c111..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-( function ( mw, $ ) {
-/**
- * Function that escapes spaces in event names. This is needed because
- * "_delayedBind-foo bar-1000" refers to two events
- */
-function encodeEvent( event ) {
-       return event.replace( /-/g, '--' ).replace( / /g, '-' );
-}
-
-$.fn.extend( {
-       /**
-        * Bind a callback to an event in a delayed fashion.
-        * In detail, this means that the callback will be called a certain
-        * time after the event fires, but the timer is reset every time
-        * the event fires.
-        * @param timeout Number of milliseconds to wait
-        * @param event Name of the event (string)
-        * @param data Data to pass to the event handler (optional)
-        * @param callback Function to call
-        */
-       delayedBind: function ( timeout, event, data, callback ) {
-               if ( arguments.length === 3 ) {
-                       // Shift optional parameter down
-                       callback = data;
-                       data = undefined;
-               }
-               var encEvent = encodeEvent( event );
-               return this.each( function () {
-                       var that = this;
-                       // Bind the top half
-                       // Do this only once for every (event, timeout) pair
-                       if (  !( $(this).data( '_delayedBindBound-' + encEvent + '-' + timeout ) ) ) {
-                               $(this).data( '_delayedBindBound-' + encEvent + '-' + timeout, true );
-                               $(this).bind( event, function () {
-                                       var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout );
-                                       // Cancel the running timer
-                                       if ( timerID !== null ) {
-                                               clearTimeout( timerID );
-                                       }
-                                       timerID = setTimeout( function () {
-                                               $(that).trigger( '_delayedBind-' + encEvent + '-' + timeout );
-                                       }, timeout );
-                                       $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout, timerID );
-                               } );
-                       }
-
-                       // Bottom half
-                       $(this).bind( '_delayedBind-' + encEvent + '-' + timeout, data, callback );
-               } );
-       },
-
-       /**
-        * Cancel the timers for delayed events on the selected elements.
-        */
-       delayedBindCancel: function ( timeout, event ) {
-               var encEvent = encodeEvent( event );
-               return this.each( function () {
-                       var timerID = $(this).data( '_delayedBindTimerID-' + encEvent + '-' + timeout );
-                       if ( timerID !== null ) {
-                               clearTimeout( timerID );
-                       }
-               } );
-       },
-
-       /**
-        * Unbind an event bound with delayedBind()
-        */
-       delayedBindUnbind: function ( timeout, event, callback ) {
-               var encEvent = encodeEvent( event );
-               return this.each( function () {
-                       $(this).unbind( '_delayedBind-' + encEvent + '-' + timeout, callback );
-               } );
-       }
-} );
-
-mw.log.deprecate( $.fn, 'delayedBind', $.fn.delayedBind,
-       'Use the jquery.throttle-debounce module instead' );
-mw.log.deprecate( $.fn, 'delayedBindCancel', $.fn.delayedBindCancel,
-       'Use the jquery.throttle-debounce module instead' );
-mw.log.deprecate( $.fn, 'delayedBindUnbind', $.fn.delayedBindUnbind,
-       'Use the jquery.throttle-debounce module instead' );
-
-}( mediaWiki, jQuery ) );
index 62f8e06..a575844 100644 (file)
@@ -86,7 +86,7 @@
                 *     addButtons( [ { .. }, { .. }, { .. } ] );
                 *     addButtons( { .. }, { .. } );
                 *
-                * @param {Object|Array} [buttons...] An array of button objects or the first
+                * @param {Object|Array...} [buttons] An array of button objects or the first
                 *  button object in a list of variadic arguments.
                 */
                addButtons: function ( buttons ) {
index 54d1608..f7a7eae 100644 (file)
@@ -1,6 +1,7 @@
 @import "mediawiki.mixins";
 @import "../../settings/typography";
 @import "../../mixins/effects";
+@import "../../mixins/utilities";
 
 // Buttons
 //
@@ -28,6 +29,7 @@
        display: inline-block;
        padding: .5em 1em;
        margin: 0;
+       .box-sizing(border-box);
 
        // IE6/IE7 hack
        // http://stackoverflow.com/a/5838575/365238
index 9daad74..52dbb05 100644 (file)
@@ -10,6 +10,7 @@
        &:focus {
                // The inner bottom bevel should match the active background color.
                box-shadow: 0 1px rgba(0, 0, 0, 10%), inset 0 -3px rgba(0, 0, 0, 20%);
+               border-bottom-color: mix(#000, @bgColor, 20%);
                outline: none;
                // remove outline in Firefox
                &::-moz-focus-inner {
 
 .button-colors(@bgColor) when (lightness(@bgColor) < 70%) {
        color: @colorWhite;
-       border: none;
+       // border of the same color as background so that light background and
+       // dark background buttons are the same height (only top and bottom to
+       // make box shadow on hover cover the corners too)
+       border: 1px solid @bgColor;
+       border-left: none;
+       border-right: none;
 
        &:disabled {
                background: @colorGrayLight;
+               border-color: @colorGrayLight;
 
                // make sure disabled buttons don't have hover and active states
                &:hover,
index 9b0711a..2b8f881 100644 (file)
                 * @param string tag to create
                 * @return DOMElement
                 */
-               createSvgElement: document.createElementNS.bind( document, 'http://www.w3.org/2000/svg' ),
+               createSvgElement: document.createElementNS
+                       ? document.createElementNS.bind( document, 'http://www.w3.org/2000/svg' )
+                       // throw a error for browsers which does not support document.createElementNS (IE<8)
+                       : function () { throw new Error( 'document.createElementNS not supported' ); },
 
                /**
                 * @param DOMElement|undefined
index 57f85d8..f6154ee 100644 (file)
@@ -2371,7 +2371,9 @@ var mw = ( function ( $, undefined ) {
                         * @return {mw.hook}
                         */
                        return function ( name ) {
-                               var list = lists[name] || ( lists[name] = $.Callbacks( 'memory' ) );
+                               var list = hasOwn.call( lists, name ) ?
+                                       lists[name] :
+                                       lists[name] = $.Callbacks( 'memory' );
 
                                return {
                                        /**
index 3174af1..545acad 100644 (file)
@@ -1,30 +1,32 @@
-// IE fixes javascript loaded by wikibits.js for IE <= 6.0
+/**
+ * IE fixes javascript loaded by wikibits.js for IE <= 6.0
+ */
+/*global isMSIE55:true, doneIETransform:true, doneIEAlphaFix:true */
+/*global hookit:true, fixalpha:true */
 ( function ( mw, $ ) {
 
-var doneIEAlphaFix, doneIETransform, expandedURLs, fixalpha, isMSIE55,
-       relativeforfloats, setrelative, hasClass;
+var expandedURLs, hasClass;
 
 // Also returns true for IE6, 7, 8, 9 and 10. createPopup is removed in IE11.
 // Good thing this is only loaded for IE <= 6 by wikibits.
 // Might as well set it to true.
-isMSIE55 = window.isMSIE55 = ( window.showModalDialog && window.clipboardData && window.createPopup );
-doneIETransform = window.doneIETransform = undefined;
-doneIEAlphaFix = window.doneIEAlphaFix = undefined;
+isMSIE55 = ( window.showModalDialog && window.clipboardData && window.createPopup );
+doneIETransform = false;
+doneIEAlphaFix = false;
 
-window.hookit = function () {
+hookit = function () {
        if ( !doneIETransform && document.getElementById && document.getElementById( 'bodyContent' ) ) {
                doneIETransform = true;
-               relativeforfloats();
                fixalpha();
        }
 };
 
 if ( document.attachEvent ) {
-       document.attachEvent( 'onreadystatechange', window.hookit );
+       document.attachEvent( 'onreadystatechange', hookit );
 }
 
 // png alpha transparency fixes
-fixalpha = window.fixalpha = function ( logoId ) {
+fixalpha = function ( logoId ) {
        // bg
        if ( isMSIE55 && !doneIEAlphaFix ) {
                var bg, imageUrl, linkFix, logoa, logospan, plogo;
@@ -76,31 +78,6 @@ if ( isMSIE55 ) {
        $( fixalpha );
 }
 
-// fix ie6 disappering float bug
-relativeforfloats = window.relativeforfloats = function () {
-       var bc, tables, divs;
-       bc = document.getElementById( 'bodyContent' );
-       if ( bc ) {
-               tables = bc.getElementsByTagName( 'table' );
-               divs = bc.getElementsByTagName( 'div' );
-               setrelative( tables );
-               setrelative( divs );
-       }
-};
-
-setrelative = window.setrelative = function ( nodes ) {
-       var i = 0;
-       while ( i < nodes.length ) {
-               if ( ( ( nodes[i].style['float'] && nodes[i].style['float'] !== ( 'none' ) ||
-                       ( nodes[i].align && nodes[i].align !== ( 'none' ) ) ) &&
-                       ( !nodes[i].style.position || nodes[i].style.position !== 'relative' ) ) )
-               {
-                       nodes[i].style.position = 'relative';
-               }
-               i++;
-       }
-};
-
 // Expand links for printing
 hasClass = function ( classText, classWanted ) {
        var i = 0, classArr = classText.split(/\s/);
@@ -112,8 +89,6 @@ hasClass = function ( classText, classWanted ) {
        return false;
 };
 
-expandedURLs = window.expandedURLs = undefined;
-
 window.onbeforeprint = function () {
        var allLinks, contentEl, expandedLink, expandedText, i;
 
index c4578aa..438fbcf 100644 (file)
@@ -4,7 +4,7 @@
 // FIXME: Use global variable since Echo and CentralNotice use this variable
 @content-border-color: #a7d7f9;
 // FIXME: Find an open font that works with this stack and is readable by Windows users
-@content-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+@content-font-family: sans-serif;
 @content-font-color: #252525;
 @content-font-size: 0.875em;
 @content-line-height: 1.6;
index e8e71b8..d958f92 100644 (file)
@@ -10172,8 +10172,7 @@ parsoid=wt2html,wt2wt,html2html
 # Foobar has actual size of 1941x220
 # 1. Thumbs & frameless always reduce, can't be enlarged unless it's
 #    a scalable format.
-# 2. Framed images ignore width; always render at default size.
-#    If given a height, they respect height but continue to ignore width.
+# 2. Framed images always ignore size options; always render at default size.
 # 3. "Unspecified format" and border are the only types which can be
 #    enlarged.
 
@@ -10272,7 +10271,7 @@ parsoid=wt2html,wt2wt,html2html
 !! end
 
 !! test
-Image: framed images ignore size if only width is given
+Image: framed images are always unscaled.
 !! options
 parsoid=wt2html,wt2wt,html2html
 !! wikitext
@@ -10280,25 +10279,17 @@ parsoid=wt2html,wt2wt,html2html
 
 [[File:Foobar.jpg|frame|50px]]
 
+[[File:Foobar.jpg|frame|50x50px]]
+
 [[File:Foobar.jpg|frame|2000px]]
 !! html/php
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
 <div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
 
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></figure><figure typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></figure><figure typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></figure>
-!! end
-
-!! test
-Image: framed images respect size if given a height, but ignore width.
-!! wikitext
-[[File:Foobar.jpg|frame|50x50px]]
-!! html/php
-<div class="thumb tright"><div class="thumbinner" style="width:444px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" width="442" height="50" class="thumbimage" /></a>  <div class="thumbcaption"></div></div></div>
-
-!! html/parsoid
-<figure typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="50" width="442"/></a></figure>
+<figure class="mw-default-size" typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></figure><figure typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></figure><figure typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></figure><figure typeof="mw:Image/Frame"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></figure>
 !! end
 
 ###################
index 74ea58e..a0fb918 100644 (file)
@@ -83,7 +83,6 @@ return array(
                        'jquery.client',
                        'jquery.color',
                        'jquery.colorUtil',
-                       'jquery.delayedBind',
                        'jquery.getAttrs',
                        'jquery.hidpi',
                        'jquery.highlightText',
index 7dff354..ab9aab1 100644 (file)
@@ -5,7 +5,6 @@
 
        var mwTestIgnore, mwTester,
                addons,
-               envExecCount,
                ELEMENT_NODE = 1,
                TEXT_NODE = 3;
 
         * Small test suite to confirm proper functionality of the utilities and
         * initializations defined above in this file.
         */
-       envExecCount = 0;
        QUnit.module( 'test.mediawiki.qunit.testrunner', QUnit.newMwEnvironment( {
                setup: function () {
-                       envExecCount += 1;
                        this.mwHtmlLive = mw.html;
                        mw.html = {
                                escape: function () {
-                                       return 'mocked-' + envExecCount;
+                                       return 'mocked';
                                }
                        };
                },
        } ) );
 
        QUnit.test( 'Setup', 3, function ( assert ) {
-               assert.equal( mw.html.escape( 'foo' ), 'mocked-1', 'extra setup() callback was ran.' );
+               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' );
 
                mw.messages.set( 'testMsg', 'Bar.' );
        } );
 
-       QUnit.test( 'Teardown', 3, function ( assert ) {
-               assert.equal( mw.html.escape( 'foo' ), 'mocked-2', 'extra setup() callback was re-ran.' );
+       QUnit.test( 'Teardown', 2, 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()' );
        } );
        QUnit.module( 'test.mediawiki.qunit.testrunner-after', QUnit.newMwEnvironment() );
 
        QUnit.test( 'Teardown', 3, function ( assert ) {
-               assert.equal( mw.html.escape( '<' ), '&lt;', 'extra teardown() callback was ran.' );
+               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()' );
        } );
index f20ce67..a9b2f33 100644 (file)
 
        } );
 
-       QUnit.test( 'mw.hook', 12, function ( assert ) {
+       QUnit.test( 'mw.hook', 13, function ( assert ) {
                var hook, add, fire, chars, callback;
 
                mw.hook( 'test.hook.unfired' ).add( function () {
                } );
                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)' );