* $wgCompiledFiles has been removed.
* $wgSortSpecialPages was removed, the listing on Special:SpecialPages is
now always sorted.
+* $wgSpecialPages may now use callback functions as an alternative to plain class names.
+ This allows more control over constructor parameters.
* $wgHTCPMulticastAddress, $wgHTCPMulticastRouting and $wgHTCPPort were removed.
* $wgRC2UDPAddress, $wgRC2UDPInterwikiPrefix, $wgRC2UDPOmitBots, $wgRC2UDPPort
and $wgRC2UDPPrefix have been removed.
* Added HTMLAutoCompleteSelectField.
* Added a new hook, "SkinPreloadExistence", to allow extensions to add titles to
link existence cache before the page is rendered.
+* Config::set() was moved to its own interface, MutableConfig. GlobalVarConfig::set()
+ is now deprecated, does not implement MutableConfig.
+* A MutableConfig named HashConfig was added, that stores an array of configuration
+ settings.
+* (bug 69418) A MultiConfig implementation was added that supports fallback
+ to multiple Config instances.
=== Bug fixes in 1.24 ===
* (bug 50572) MediaWiki:Blockip should support gender
deprecated in favor of cmstarthexsortkey and cmendhexsortkey.
* (bug 63326) Add blockedtimestamp field to output of blockinfo property for
the list=allusers and list=users modules.
+* prop=imageinfo no longer requires iiurlwidth to be set when using iiurlparam.
+* Added prop=linkshere, prop=fileusage, and prop=transcludedin, which are
+ roughly equivalent to list=backlinks, list=imageusage, and list=embeddedin
+ but can work on a list of titles (including titles from a generator).
+* prop=redirects can now filter returned redirects by namespace.
=== Action API internal changes in 1.24 ===
* Methods for handling continuation are added to ApiResult, so actions other
ApiTokensGetTokenTypes are deprecated, but are still called to support
backwards-compatible token access.
* ApiBase::validateLimit and ApiBase::validateTimestamp are now protected.
+* ApiQueryRedirects was removed; prop=redirects is now implemented by
+ ApiQueryBacklinksProp along with the newly-added prop modules.
* The following methods have been deprecated and may be removed in a future
release:
* ApiBase::getResultProperties
meaning that JavaScript is no longer executed in these browser versions.
* Browser support for Opera 11 lowered from Grade A to Grade C.
* Removed IEFixes module which existed purely to provide support for MSIE versions
+* Deprecated SpecialPageFactory::getList() in favor of
+ SpecialPageFactory::getNames()
below 7 (conditionally loaded only for those browsers).
* Action::checkCanExecute() no longer has a return value.
* Removed cleanupForIRC(), loadFromCurRow(), newFromCurRow(), notifyRC2UDP()
and "jquery" modules. In the past, this behavior was undefined, now it will
throw an error.
* Removed BagOStuff::replace(). (deprecated since 1.23)
+* In Linker.php, link(), linkText() and makeBrokenImageLinkObj() now display
+ warnings if their first parameter is not a Title object. Also makeImageLink()
+ now requires a Parser as its first parameter.
==== Renamed classes ====
* CLDRPluralRuleConverter_Expression to CLDRPluralRuleConverterExpression
== Compatibility ==
-MediaWiki 1.24 requires PHP 5.3.2 or later.
+MediaWiki 1.24 requires PHP 5.3.2 or later. There is experimental support for
+HHVM 3.3.0.
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
+++ /dev/null
-The icons used here are derived from the crystalsvg icons in the the
-pics/crystalsvg/ directory of kdelibs-3.4.0 they were modified on 2005-05-15
-by Ævar Arnfjörð Bjarmason for use in MediaWiki.
-
-What follows is the contents of the LICENSE.crystalsvg file found in the pics/
-subdirectory of kdelibs-3.4.0:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-This copyright and license notice covers all CrystalSVG images.
-Note the license notice contains an add-on.
-********************************************************************************
-KDE Crystal theme icons.
-Copyright (C) 2002 and following years KDE Artists
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation,
-version 2.1 of the License.
-This library 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
-Lesser General Public License for more details.
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- **** NOTE THIS ADD-ON ****
-The GNU Lesser General Public License or LGPL is written for software libraries
-in the first place. We expressly want the LGPL to be valid for this artwork
-library too.
-KDE Crystal theme icons is a special kind of software library, it is an
-artwork library, it's elements can be used in a Graphical User Interface, or
-GUI.
-Source code, for this library means:
- - for vectors svg;
- - for pixels, if applicable, the multi-layered formats xcf or psd, or
-otherwise png.
-The LGPL in some sections obliges you to make the files carry
-notices. With images this is in some cases impossible or hardly useful.
-With this library a notice is placed at a prominent place in the directory
-containing the elements. You may follow this practice.
-The exception in section 6 of the GNU Lesser General Public License covers
-the use of elements of this art library in a GUI.
-kde-artists [at] kde.org
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
&$titleArray: set this to an object to override the default object returned
$res: database result used to create the object
+'TitleExists': Called when determining whether a page exists at a given title.
+$title: The title being tested.
+&$exists: Whether the title exists.
+
'TitleQuickPermissions': Called from Title::checkQuickPermissions to add to
or override the quick permissions check.
$title: The Title object being accessed
display: block;
margin: 0;
margin-left: 20px;
+
+ div {
+ margin-bottom: 5px;
+ }
}
}
}
'ApiQueryAllPages' => 'includes/api/ApiQueryAllPages.php',
'ApiQueryAllUsers' => 'includes/api/ApiQueryAllUsers.php',
'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
+ 'ApiQueryBacklinksprop' => 'includes/api/ApiQueryBacklinksprop.php',
'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
'ApiQueryBlocks' => 'includes/api/ApiQueryBlocks.php',
'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php',
'ApiQueryRandom' => 'includes/api/ApiQueryRandom.php',
'ApiQueryRecentChanges' => 'includes/api/ApiQueryRecentChanges.php',
'ApiQueryFileRepoInfo' => 'includes/api/ApiQueryFileRepoInfo.php',
- 'ApiQueryRedirects' => 'includes/api/ApiQueryRedirects.php',
'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
'ApiQuerySearch' => 'includes/api/ApiQuerySearch.php',
'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
'ConfigException' => 'includes/config/ConfigException.php',
'ConfigFactory' => 'includes/config/ConfigFactory.php',
'GlobalVarConfig' => 'includes/config/GlobalVarConfig.php',
+ 'HashConfig' => 'includes/config/HashConfig.php',
+ 'MultiConfig' => 'includes/config/MultiConfig.php',
'MutableConfig' => 'includes/config/MutableConfig.php',
# includes/content
),
"poweredby" => array(
"mediawiki" => array(
- "src" => null, // Defaults to "$wgScriptPath/assets/poweredby_mediawiki_88x31.png"
+ "src" => null, // Defaults to "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png"
"url" => "//www.mediawiki.org/",
"alt" => "Powered by MediaWiki",
)
$wgValidSkinNames = array();
/**
- * Special page list.
- * See the top of SpecialPage.php for documentation.
+ * Special page list. This is an associative array mapping the (canonical) names of
+ * special pages to either a class name to be instantiated, or a callback to use for
+ * creating the special page object. In both cases, the result must be an instance of
+ * SpecialPage.
*/
$wgSpecialPages = array();
*
* This function replaces all old wfMsg* functions.
*
- * @param string $key Message key
+ * @param string|string[] $key Message key, or array of keys
* @param mixed $params,... Normal message parameters
* @return Message
*
public static function link(
$target, $html = null, $customAttribs = array(), $query = array(), $options = array()
) {
- wfProfileIn( __METHOD__ );
if ( !$target instanceof Title ) {
- wfProfileOut( __METHOD__ );
+ wfWarn( __METHOD__ . ': Requires $target to be a Title object.' );
return "<!-- ERROR -->$html";
}
+ wfProfileIn( __METHOD__ );
if ( is_string( $query ) ) {
// some functions withing core using this still hand over query strings
* @return string
*/
private static function linkText( $target ) {
- // We might be passed a non-Title by make*LinkObj(). Fail gracefully.
if ( !$target instanceof Title ) {
+ wfWarn( __METHOD__ . ': Requires $target to be a Title object.' );
return '';
}
-
// If the target is just a fragment, with no title, we return the fragment
// text. Otherwise, we return the title text itself.
if ( $target->getPrefixedText() === '' && $target->hasFragment() ) {
* @since 1.20
* @return string HTML for an image, with links, wrappers, etc.
*/
- public static function makeImageLink( /*Parser*/ $parser, Title $title,
+ public static function makeImageLink( Parser $parser, Title $title,
$file, $frameParams = array(), $handlerParams = array(), $time = false,
$query = "", $widthOption = null
) {
# If a thumbnail width has not been provided, it is set
# to the default user option as specified in Language*.php
if ( $fp['align'] == '' ) {
- if ( $parser instanceof Parser ) {
- $fp['align'] = $parser->getTargetLanguage()->alignEnd();
- } else {
- # backwards compatibility, remove with makeImageLink2()
- global $wgContLang;
- $fp['align'] = $wgContLang->alignEnd();
- }
+ $fp['align'] = $parser->getTargetLanguage()->alignEnd();
}
return $prefix . self::makeThumbLink2( $title, $file, $fp, $hp, $time, $query ) . $postfix;
}
public static function makeBrokenImageLinkObj( $title, $label = '',
$query = '', $unused1 = '', $unused2 = '', $time = false
) {
- global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
if ( !$title instanceof Title ) {
+ wfWarn( __METHOD__ . ': Requires $title to be a Title object.' );
return "<!-- ERROR -->" . htmlspecialchars( $label );
}
+
+ global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
wfProfileIn( __METHOD__ );
if ( $label == '' ) {
$label = $title->getPrefixedText();
}
$encLogo = htmlspecialchars(
str_replace( '//', '/', $dirname . '/' ) .
- 'assets/mediawiki.png'
+ 'resources/assets/mediawiki.png'
);
header( "$protocol 500 MediaWiki configuration Error" );
* @return string
*/
function getButtons() {
+ global $wgUseMediaWikiUIEverywhere;
+ $attrs = $wgUseMediaWikiUIEverywhere ? array( 'class' => 'mw-ui-button mw-ui-quiet' ) : array();
+
if ( !$this->getModifiedUser()->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) {
return '';
}
if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) {
$t = SpecialPage::getTitleFor( 'Preferences', 'reset' );
- $html .= "\n" . Linker::link( $t, $this->msg( 'restoreprefs' )->escaped() );
+ $html .= "\n" . Linker::link( $t, $this->msg( 'restoreprefs' )->escaped(),
+ $attrs );
$html = Xml::tags( 'div', array( 'class' => 'mw-prefs-buttons' ), $html );
}
// Unlike SpecialPage itself, we want the canonical forms of both
// canonical and alias title forms...
$keys = array();
- foreach ( SpecialPageFactory::getList() as $page => $class ) {
+ foreach ( SpecialPageFactory::getNames() as $page ) {
$keys[$wgContLang->caseFold( $page )] = $page;
}
foreach ( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
- if ( !array_key_exists( $page, SpecialPageFactory::getList() ) ) {# bug 20885
+ if ( !in_array( $page, SpecialPageFactory::getNames() ) ) {# bug 20885
continue;
}
);
$expiryFormOptions = '';
- if ( $this->mExistingExpiry[$action] && $this->mExistingExpiry[$action] != 'infinity' ) {
- $timestamp = $lang->timeanddate( $this->mExistingExpiry[$action], true );
- $d = $lang->date( $this->mExistingExpiry[$action], true );
- $t = $lang->time( $this->mExistingExpiry[$action], true );
+ if ( $this->mExistingExpiry[$action] ) {
+ if ( $this->mExistingExpiry[$action] == 'infinity' ) {
+ $existingExpiryMessage = wfMessage( 'protect-existing-expiry-infinity' );
+ } else {
+ $timestamp = $lang->timeanddate( $this->mExistingExpiry[$action], true );
+ $d = $lang->date( $this->mExistingExpiry[$action], true );
+ $t = $lang->time( $this->mExistingExpiry[$action], true );
+ $existingExpiryMessage = wfMessage( 'protect-existing-expiry', $timestamp, $d, $t );
+ }
$expiryFormOptions .=
Xml::option(
- wfMessage( 'protect-existing-expiry', $timestamp, $d, $t )->text(),
+ $existingExpiryMessage->text(),
'existing',
$this->mExpirySelection[$action] == 'existing'
) . "\n";
if ( $wgExtensionAssetsPath === false ) {
$wgExtensionAssetsPath = "$wgScriptPath/extensions";
}
+if ( $wgResourceBasePath === null ) {
+ $wgResourceBasePath = $wgScriptPath;
+}
if ( $wgLogo === false ) {
$wgLogo = "$wgStylePath/common/images/wiki.png";
if ( $wgRightsIcon ) {
$wgRightsIcon = str_replace(
"{$wgStylePath}/common/images/",
- "{$wgScriptPath}/assets/licenses/",
+ "{$wgResourceBasePath}/resources/assets/licenses/",
$wgRightsIcon
);
}
&& $wgFooterIcons['poweredby']['mediawiki']['src'] === null
) {
$wgFooterIcons['poweredby']['mediawiki']['src'] =
- "$wgScriptPath/assets/poweredby_mediawiki_88x31.png";
+ "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png";
}
/**
* @return bool
*/
public function exists() {
- return $this->getArticleID() != 0;
+ $exists = $this->getArticleID() != 0;
+ wfRunHooks( 'TitleExists', array( $this, &$exists ) );
+ return $exists;
}
/**
$this->dieUsageMsg( array( 'missingparam', 'token' ) );
}
- if ( array_key_exists(
- $module->encodeParamName( 'token' ),
- $this->getRequest()->getQueryValues()
- ) ) {
+ if ( !$this->getConfig()->get( 'DebugAPI' ) &&
+ array_key_exists(
+ $module->encodeParamName( 'token' ),
+ $this->getRequest()->getQueryValues()
+ )
+ ) {
$this->dieUsage(
"The '{$module->encodeParamName( 'token' )}' parameter was found in the query string, but must be in the POST body",
'mustposttoken'
'contributors' => 'ApiQueryContributors',
'duplicatefiles' => 'ApiQueryDuplicateFiles',
'extlinks' => 'ApiQueryExternalLinks',
+ 'fileusage' => 'ApiQueryBacklinksprop',
'images' => 'ApiQueryImages',
'imageinfo' => 'ApiQueryImageInfo',
'info' => 'ApiQueryInfo',
'links' => 'ApiQueryLinks',
+ 'linkshere' => 'ApiQueryBacklinksprop',
'iwlinks' => 'ApiQueryIWLinks',
'langlinks' => 'ApiQueryLangLinks',
'pageprops' => 'ApiQueryPageProps',
- 'redirects' => 'ApiQueryRedirects',
+ 'redirects' => 'ApiQueryBacklinksprop',
'revisions' => 'ApiQueryRevisions',
'stashimageinfo' => 'ApiQueryStashImageInfo',
'templates' => 'ApiQueryLinks',
+ 'transcludedin' => 'ApiQueryBacklinksprop',
);
/**
--- /dev/null
+<?php
+/**
+ * API module to handle links table back-queries
+ *
+ * Created on Aug 19, 2014
+ *
+ * Copyright © 2014 Brad Jorsch <bjorsch@wikimedia.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.24
+ */
+
+/**
+ * This implements prop=redirects, prop=linkshere, prop=catmembers,
+ * prop=transcludedin, and prop=fileusage
+ *
+ * @ingroup API
+ * @since 1.24
+ */
+class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
+
+ // Data for the various modules implemented by this class
+ private static $settings = array(
+ 'redirects' => array(
+ 'code' => 'rd',
+ 'prefix' => 'rd',
+ 'linktable' => 'redirect',
+ 'what' => 'redirects to',
+ 'description' => 'Returns all redirects to the given pages.',
+ 'props' => array(
+ 'fragment' => 'Fragment of each redirect, if any',
+ ),
+ 'showredirects' => false,
+ 'show' => array(
+ 'fragment' => 'Only show redirects with a fragment',
+ '!fragment' => 'Only show redirects without a fragment',
+ ),
+ ),
+ 'linkshere' => array(
+ 'code' => 'lh',
+ 'prefix' => 'pl',
+ 'linktable' => 'pagelinks',
+ 'from_namespace' => true,
+ 'what' => 'pages linking to',
+ 'description' => 'Find all pages that link to the given pages.',
+ 'showredirects' => true,
+ ),
+ 'transcludedin' => array(
+ 'code' => 'ti',
+ 'prefix' => 'tl',
+ 'linktable' => 'templatelinks',
+ 'from_namespace' => true,
+ 'what' => 'pages transcluding',
+ 'description' => 'Find all pages that transclude the given pages.',
+ 'showredirects' => true,
+ ),
+ 'fileusage' => array(
+ 'code' => 'fu',
+ 'prefix' => 'il',
+ 'linktable' => 'imagelinks',
+ 'from_namespace' => true,
+ 'to_namespace' => NS_FILE,
+ 'what' => 'pages using',
+ 'exampletitle' => 'File:Example.jpg',
+ 'description' => 'Find all pages that use the given files.',
+ 'showredirects' => true,
+ ),
+ );
+
+ public function __construct( ApiQuery $query, $moduleName ) {
+ parent::__construct( $query, $moduleName, self::$settings[$moduleName]['code'] );
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
+ }
+
+ /**
+ * @param ApiPageSet $resultPageSet
+ */
+ private function run( ApiPageSet $resultPageSet = null ) {
+ $settings = self::$settings[$this->getModuleName()];
+
+ $db = $this->getDB();
+ $params = $this->extractRequestParams();
+ $prop = array_flip( $params['prop'] );
+ $emptyString = $db->addQuotes( '' );
+
+ $pageSet = $this->getPageSet();
+ $titles = $pageSet->getGoodTitles() + $pageSet->getMissingTitles();
+ $map = $pageSet->getAllTitlesByNamespace();
+
+ // Determine our fields to query on
+ $p = $settings['prefix'];
+ $hasNS = !isset( $settings['to_namespace'] );
+ if ( $hasNS ) {
+ $bl_namespace = "{$p}_namespace";
+ $bl_title = "{$p}_title";
+ } else {
+ $bl_namespace = $settings['to_namespace'];
+ $bl_title = "{$p}_to";
+
+ $titles = array_filter( $titles, function ( $t ) use ( $bl_namespace ) {
+ return $t->getNamespace() === $bl_namespace;
+ } );
+ $map = array_intersect_key( $map, array( $bl_namespace => true ) );
+ }
+ $bl_from = "{$p}_from";
+
+ if ( !$titles ) {
+ return; // nothing to do
+ }
+
+ // Figure out what we're sorting by, and add associated WHERE clauses.
+ // MySQL's query planner screws up if we include a field in ORDER BY
+ // when it's constant in WHERE, so we have to test that for each field.
+ $sortby = array();
+ if ( $hasNS && count( $map ) > 1 ) {
+ $sortby[$bl_namespace] = 'ns';
+ }
+ $theTitle = null;
+ foreach ( $map as $nsTitles ) {
+ reset( $nsTitles );
+ $key = key( $nsTitles );
+ if ( $theTitle === null ) {
+ $theTitle = $key;
+ }
+ if ( count( $nsTitles ) > 1 || $key !== $theTitle ) {
+ $sortby[$bl_title] = 'title';
+ break;
+ }
+ }
+ $miser_ns = null;
+ if ( $params['namespace'] !== null ) {
+ if ( empty( $settings['from_namespace'] ) && $this->getConfig()->get( 'MiserMode' ) ) {
+ $miser_ns = $params['namespace'];
+ } else {
+ $this->addWhereFld( "{$p}_from_namespace", $params['namespace'] );
+ if ( !empty( $settings['from_namespace'] ) && count( $params['namespace'] ) > 1 ) {
+ $sortby["{$p}_from_namespace"] = 'int';
+ }
+ }
+ }
+ $sortby[$bl_from] = 'int';
+
+ // Now use the $sortby to figure out the continuation
+ if ( !is_null( $params['continue'] ) ) {
+ $cont = explode( '|', $params['continue'] );
+ $this->dieContinueUsageIf( count( $cont ) != count( $sortby ) );
+ $where = '';
+ $i = count( $sortby ) - 1;
+ $cont_ns = 0;
+ $cont_title = '';
+ foreach ( array_reverse( $sortby, true ) as $field => $type ) {
+ $v = $cont[$i];
+ switch ( $type ) {
+ case 'ns':
+ $cont_ns = (int)$v;
+ /* fall through */
+ case 'int':
+ $v = (int)$v;
+ $this->dieContinueUsageIf( $v != $cont[$i] );
+ break;
+
+ case 'title':
+ $cont_title = $v;
+ /* fall through */
+ default:
+ $v = $db->addQuotes( $v );
+ break;
+ }
+
+ if ( $where === '' ) {
+ $where = "$field >= $v";
+ } else {
+ $where = "$field > $v OR ($field = $v AND ($where))";
+ }
+
+ $i--;
+ }
+ $this->addWhere( $where );
+ }
+
+ // Populate the rest of the query
+ $this->addTables( array( $settings['linktable'], 'page' ) );
+ $this->addWhere( "$bl_from = page_id" );
+
+ if ( $this->getModuleName() === 'redirects' ) {
+ $this->addWhere( "rd_interwiki = $emptyString OR rd_interwiki IS NULL" );
+ }
+
+ $this->addFields( array_keys( $sortby ) );
+ $this->addFields( array( 'bl_namespace' => $bl_namespace, 'bl_title' => $bl_title ) );
+ if ( is_null( $resultPageSet ) ) {
+ $fld_pageid = isset( $prop['pageid'] );
+ $fld_title = isset( $prop['title'] );
+ $fld_redirect = isset( $prop['redirect'] );
+
+ $this->addFieldsIf( 'page_id', $fld_pageid );
+ $this->addFieldsIf( array( 'page_title', 'page_namespace' ), $fld_title );
+ $this->addFieldsIf( 'page_is_redirect', $fld_redirect );
+
+ // prop=redirects
+ $fld_fragment = isset( $prop['fragment'] );
+ $this->addFieldsIf( 'rd_fragment', $fld_fragment );
+ } else {
+ $this->addFields( $resultPageSet->getPageTableFields() );
+ }
+
+ $this->addFieldsIf( 'page_namespace', $miser_ns !== null );
+
+ if ( $hasNS ) {
+ $lb = new LinkBatch( $titles );
+ $this->addWhere( $lb->constructSet( $p, $db ) );
+ } else {
+ $where = array();
+ foreach ( $titles as $t ) {
+ if ( $t->getNamespace() == $bl_namespace ) {
+ $where[] = "$bl_title = " . $db->addQuotes( $t->getDBkey() );
+ }
+ }
+ $this->addWhere( $db->makeList( $where, LIST_OR ) );
+ }
+
+ if ( $params['show'] !== null ) {
+ // prop=redirects only
+ $show = array_flip( $params['show'] );
+ if ( isset( $show['fragment'] ) && isset( $show['!fragment'] ) ||
+ isset( $show['redirect'] ) && isset( $show['!redirect'] )
+ ) {
+ $this->dieUsageMsg( 'show' );
+ }
+ $this->addWhereIf( "rd_fragment != $emptyString", isset( $show['fragment'] ) );
+ $this->addWhereIf(
+ "rd_fragment = $emptyString OR rd_fragment IS NULL",
+ isset( $show['!fragment'] )
+ );
+ $this->addWhereIf( array( 'page_is_redirect' => 1 ), isset( $show['redirect'] ) );
+ $this->addWhereIf( array( 'page_is_redirect' => 0 ), isset( $show['!redirect'] ) );
+ }
+
+ // Override any ORDER BY from above with what we calculated earlier.
+ $this->addOption( 'ORDER BY', array_keys( $sortby ) );
+
+ $this->addOption( 'LIMIT', $params['limit'] + 1 );
+
+ $res = $this->select( __METHOD__ );
+
+ if ( is_null( $resultPageSet ) ) {
+ $count = 0;
+ foreach ( $res as $row ) {
+ if ( ++$count > $params['limit'] ) {
+ // We've reached the one extra which shows that
+ // there are additional pages to be had. Stop here...
+ $this->setContinue( $row, $sortby );
+ break;
+ }
+
+ if ( $miser_ns !== null && !in_array( $row->page_namespace, $miser_ns ) ) {
+ // Miser mode namespace check
+ continue;
+ }
+
+ // Get the ID of the current page
+ $id = $map[$row->bl_namespace][$row->bl_title];
+
+ $vals = array();
+ if ( $fld_pageid ) {
+ $vals['pageid'] = $row->page_id;
+ }
+ if ( $fld_title ) {
+ ApiQueryBase::addTitleInfo( $vals,
+ Title::makeTitle( $row->page_namespace, $row->page_title )
+ );
+ }
+ if ( $fld_fragment && $row->rd_fragment !== null && $row->rd_fragment !== '' ) {
+ $vals['fragment'] = $row->rd_fragment;
+ }
+ if ( $fld_redirect && $row->page_is_redirect ) {
+ $vals['redirect'] = '';
+ }
+ $fit = $this->addPageSubItem( $id, $vals );
+ if ( !$fit ) {
+ $this->setContinue( $row, $sortby );
+ break;
+ }
+ }
+ } else {
+ $titles = array();
+ $count = 0;
+ foreach ( $res as $row ) {
+ if ( ++$count > $params['limit'] ) {
+ // We've reached the one extra which shows that
+ // there are additional pages to be had. Stop here...
+ $this->setContinue( $row, $sortby );
+ break;
+ }
+ $titles[] = Title::makeTitle( $row->page_namespace, $row->page_title );
+ }
+ $resultPageSet->populateFromTitles( $titles );
+ }
+ }
+
+ private function setContinue( $row, $sortby ) {
+ $cont = array();
+ foreach ( $sortby as $field => $v ) {
+ $cont[] = $row->$field;
+ }
+ $this->setContinueEnumParameter( 'continue', join( '|', $cont ) );
+ }
+
+ public function getCacheMode( $params ) {
+ return 'public';
+ }
+
+ public function getAllowedParams() {
+ $settings = self::$settings[$this->getModuleName()];
+
+ $ret = array(
+ 'prop' => array(
+ ApiBase::PARAM_TYPE => array(
+ 'pageid',
+ 'title',
+ ),
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_DFLT => 'pageid|title',
+ ),
+ 'namespace' => array(
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_TYPE => 'namespace',
+ ),
+ 'limit' => array(
+ ApiBase::PARAM_DFLT => 10,
+ ApiBase::PARAM_TYPE => 'limit',
+ ApiBase::PARAM_MIN => 1,
+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+ ),
+ 'continue' => null,
+ );
+
+ if ( !empty( $settings['showredirects'] ) ) {
+ $ret['prop'][ApiBase::PARAM_TYPE][] = 'redirect';
+ $ret['prop'][ApiBase::PARAM_DFLT] .= '|redirect';
+ }
+ if ( isset( $settings['props'] ) ) {
+ $ret['prop'][ApiBase::PARAM_TYPE] = array_merge(
+ $ret['prop'][ApiBase::PARAM_TYPE], array_keys( $settings['props'] )
+ );
+ }
+
+ $show = array();
+ if ( !empty( $settings['showredirects'] ) ) {
+ $show[] = 'redirect';
+ $show[] = '!redirect';
+ }
+ if ( isset( $settings['show'] ) ) {
+ $show = array_merge( $show, array_keys( $settings['show'] ) );
+ }
+ if ( $show ) {
+ $ret['show'] = array(
+ ApiBase::PARAM_TYPE => $show,
+ ApiBase::PARAM_ISMULTI => true,
+ );
+ }
+
+ return $ret;
+ }
+
+ public function getParamDescription() {
+ $settings = self::$settings[$this->getModuleName()];
+ $p = $this->getModulePrefix();
+
+ $ret = array(
+ 'prop' => array(
+ 'Which properties to get:',
+ ),
+ 'show' => array(
+ 'Show only items that meet this criteria.',
+ ),
+ 'namespace' => 'Only include pages in these namespaces',
+ 'limit' => 'How many to return',
+ 'continue' => 'When more results are available, use this to continue',
+ );
+
+ if ( empty( $settings['from_namespace'] ) && $this->getConfig()->get( 'MiserMode' ) ) {
+ $ret['namespace'] = array(
+ $ret['namespace'],
+ "NOTE: Due to \$wgMiserMode, using this may result in fewer than \"{$p}limit\" results",
+ 'returned before continuing; in extreme cases, zero results may be returned.',
+ );
+ if ( isset( $ret['type'] ) ) {
+ $ret['namespace'][] = "Note that you can use {$p}type=subcat or {$p}type=file " .
+ "instead of {$p}namespace=14 or 6.";
+ }
+ }
+
+ $props = array(
+ 'pageid' => 'Adds the ID of page',
+ 'title' => 'Adds the title and namespace ID of the page',
+ );
+ if ( !empty( $settings['showredirects'] ) ) {
+ $props['redirect'] = 'Indicate if the page is a redirect';
+ }
+ if ( isset( $settings['props'] ) ) {
+ $props += $settings['props'];
+ }
+ foreach ( $props as $k => $v ) {
+ $ret['props'][] = sprintf( "%-9s - %s", $k, $v );
+ }
+
+ $show = array();
+ if ( !empty( $settings['showredirects'] ) ) {
+ $show += array(
+ 'redirect' => 'Only show redirects',
+ '!redirect' => 'Only show non-redirects',
+ );
+ }
+ if ( isset( $settings['show'] ) ) {
+ $show += $settings['show'];
+ }
+ foreach ( $show as $k => $v ) {
+ $ret['show'][] = sprintf( "%-9s - %s", $k, $v );
+ }
+
+ return $ret;
+ }
+
+ public function getDescription() {
+ return self::$settings[$this->getModuleName()]['description'];
+ }
+
+ public function getExamples() {
+ $settings = self::$settings[$this->getModuleName()];
+ $name = $this->getModuleName();
+ $what = $settings['what'];
+ $title = isset( $settings['exampletitle'] ) ? $settings['exampletitle'] : 'Main Page';
+ $etitle = rawurlencode( $title );
+
+ return array(
+ "api.php?action=query&prop={$name}&titles={$etitle}"
+ => "Get a list of $what [[$title]]",
+ "api.php?action=query&generator={$name}&titles={$etitle}&prop=info"
+ => "Get information about $what [[$title]]",
+ );
+ }
+
+ public function getHelpUrls() {
+ $name = $this->getModuleName();
+ $prefix = $this->getModulePrefix();
+ return "https://www.mediawiki.org/wiki/API:Properties#{$name}_.2F_{$prefix}";
+ }
+}
$scale = array();
$scale['height'] = $params['urlheight'];
} else {
- $scale = null;
if ( $params['urlparam'] ) {
- $this->dieUsage( "{$p}urlparam requires {$p}urlwidth", "urlparam_no_width" );
+ // Audio files might not have a width/height.
+ $scale = array();
+ } else {
+ $scale = null;
}
}
* @return array Array of parameters for transform.
*/
protected function mergeThumbParams( $image, $thumbParams, $otherParams ) {
+ if ( $thumbParams === null ) {
+ // No scaling requested
+ return null;
+ }
if ( !isset( $thumbParams['width'] ) && isset( $thumbParams['height'] ) ) {
// We want to limit only by height in this situation, so pass the
// image's full width as the limiting width. But some file types
}
if ( !$otherParams ) {
+ $this->checkParameterNormalise( $image, $thumbParams );
return $thumbParams;
}
$p = $this->getModulePrefix();
// handlers.
$this->setWarning( "Could not parse {$p}urlparam for " . $image->getName()
. '. Using only width and height' );
-
+ $this->checkParameterNormalise( $image, $thumbParams );
return $thumbParams;
}
- if ( isset( $paramList['width'] ) ) {
+ if ( isset( $paramList['width'] ) && isset( $thumbParams['width'] ) ) {
if ( intval( $paramList['width'] ) != intval( $thumbParams['width'] ) ) {
$this->setWarning( "Ignoring width value set in {$p}urlparam ({$paramList['width']}) "
. "in favor of width value derived from {$p}urlwidth/{$p}urlheight "
}
}
- return $thumbParams + $paramList;
+ $finalParams = $thumbParams + $paramList;
+ $this->checkParameterNormalise( $image, $finalParams );
+ return $finalParams;
+ }
+
+ /**
+ * Verify that the final image parameters can be normalised.
+ *
+ * This doesn't use the normalised parameters, since $file->transform
+ * expects the pre-normalised parameters, but doing the normalisation
+ * allows us to catch certain error conditions early (such as missing
+ * required parameter).
+ *
+ * @param $image File
+ * @param $finalParams array List of parameters to transform image with
+ */
+ protected function checkParameterNormalise( $image, $finalParams ) {
+ $h = $image->getHandler();
+ if ( !$h ) {
+ return;
+ }
+ // Note: normaliseParams modifies the array in place, but we aren't interested
+ // in the actual normalised version, only if we can actually normalise them,
+ // so we use the functions scope to throw away the normalisations.
+ if ( !$h->normaliseParams( $image, $finalParams ) ) {
+ $this->dieUsage( "Could not normalise image parameters for " . $image->getName(), "urlparamnormal" );
+ }
}
/**
if ( $pageCount !== false ) {
$vals['pagecount'] = $pageCount;
}
+
+ // length as in how many seconds long a video is.
+ $length = $file->getLength();
+ if ( $length ) {
+ // Call it duration, because "length" can be ambiguous.
+ $vals['duration'] = (float)$length;
+ }
}
$pcomment = isset( $prop['parsedcomment'] );
'parsedcomment' => ' parsedcomment - Parse the comment on the version',
'canonicaltitle' => ' canonicaltitle - Adds the canonical title of the image file',
'url' => ' url - Gives URL to the image and the description page',
- 'size' => ' size - Adds the size of the image in bytes ' .
- 'and the height, width and page count (if applicable)',
+ 'size' => ' size - Adds the size of the image in bytes, ' .
+ 'its height and its width. Page count and duration are added if applicable',
'dimensions' => ' dimensions - Alias for size', // B/C with Allimages
'sha1' => ' sha1 - Adds SHA-1 hash for the image',
'mime' => ' mime - Adds MIME type of the image',
'no more than ' . self::TRANSFORM_LIMIT . ' scaled images will be returned.'
),
'urlheight' => "Similar to {$p}urlwidth.",
- 'urlparam' => array( "A handler specific parameter string. For example, pdf's ",
- "might use 'page15-100px'. {$p}urlwidth must be used and be consistent with {$p}urlparam" ),
+ 'urlparam' => array(
+ "A handler specific parameter string. For example, pdf's ",
+ "might use 'page15-100px'."
+ ),
'limit' => 'How many image revisions to return per image',
'start' => 'Timestamp to start listing from',
'end' => 'Timestamp to stop listing at',
+++ /dev/null
-<?php
-/**
- * API module to return redirects to a page
- *
- * Created on Dec 30, 2013
- *
- * Copyright © 2013 Brad Jorsch <bjorsch@wikimedia.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.23
- */
-
-/**
- * This query lists redirects to the given pages.
- *
- * @ingroup API
- */
-class ApiQueryRedirects extends ApiQueryGeneratorBase {
-
- public function __construct( ApiQuery $query, $moduleName ) {
- parent::__construct( $query, $moduleName, 'rd' );
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator( $resultPageSet ) {
- $this->run( $resultPageSet );
- }
-
- /**
- * @param ApiPageSet $resultPageSet
- */
- private function run( ApiPageSet $resultPageSet = null ) {
- $db = $this->getDB();
- $params = $this->extractRequestParams();
- $emptyString = $db->addQuotes( '' );
-
- $pageSet = $this->getPageSet();
- $titles = $pageSet->getGoodTitles() + $pageSet->getMissingTitles();
-
- if ( !is_null( $params['continue'] ) ) {
- $cont = explode( '|', $params['continue'] );
- $this->dieContinueUsageIf( count( $cont ) != 3 );
- $rd_namespace = (int)$cont[0];
- $this->dieContinueUsageIf( $rd_namespace != $cont[0] );
- $rd_title = $db->addQuotes( $cont[1] );
- $rd_from = (int)$cont[2];
- $this->dieContinueUsageIf( $rd_from != $cont[2] );
- $this->addWhere(
- "rd_namespace > $rd_namespace OR " .
- "(rd_namespace = $rd_namespace AND " .
- "(rd_title > $rd_title OR " .
- "(rd_title = $rd_title AND " .
- "rd_from >= $rd_from)))"
- );
-
- // Remove titles that we're past already
- $titles = array_filter( $titles, function ( $t ) use ( $rd_namespace, $rd_title ) {
- $ns = $t->getNamespace();
- return ( $ns > $rd_namespace ||
- $ns == $rd_namespace && $t->getDBKey() >= $rd_title
- );
- } );
- }
-
- if ( !$titles ) {
- return; // nothing to do
- }
-
- $this->addTables( array( 'redirect', 'page' ) );
- $this->addFields( array(
- 'rd_from',
- 'rd_namespace',
- 'rd_title',
- ) );
-
- if ( is_null( $resultPageSet ) ) {
- $prop = array_flip( $params['prop'] );
- $fld_pageid = isset( $prop['pageid'] );
- $fld_title = isset( $prop['title'] );
- $fld_fragment = isset( $prop['fragment'] );
-
- $this->addFieldsIf( 'rd_fragment', $fld_fragment );
- $this->addFieldsIf( array( 'page_namespace', 'page_title' ), $fld_title );
- } else {
- $this->addFields( array( 'page_namespace', 'page_title' ) );
- }
-
- $lb = new LinkBatch( $titles );
- $this->addWhere( array(
- 'rd_from = page_id',
- "rd_interwiki = $emptyString OR rd_interwiki IS NULL",
- $lb->constructSet( 'rd', $db ),
- ) );
-
- if ( $params['show'] !== null ) {
- $show = array_flip( $params['show'] );
- if ( isset( $show['fragment'] ) && isset( $show['!fragment'] ) ) {
- $this->dieUsageMsg( 'show' );
- }
- $this->addWhereIf( "rd_fragment != $emptyString", isset( $show['fragment'] ) );
- $this->addWhereIf(
- "rd_fragment = $emptyString OR rd_fragment IS NULL",
- isset( $show['!fragment'] )
- );
- }
-
- $map = $pageSet->getAllTitlesByNamespace();
-
- // Why, MySQL? Why do you do this to us?
- $sortby = array();
- if ( count( $map ) > 1 ) {
- $sortby[] = 'rd_namespace';
- }
- $theTitle = null;
- foreach ( $map as $nsTitles ) {
- reset( $nsTitles );
- $key = key( $nsTitles );
- if ( $theTitle === null ) {
- $theTitle = $key;
- }
- if ( count( $nsTitles ) > 1 || $key !== $theTitle ) {
- $sortby[] = 'rd_title';
- break;
- }
- }
- $sortby[] = 'rd_from';
- $this->addOption( 'ORDER BY', $sortby );
-
- $this->addOption( 'LIMIT', $params['limit'] + 1 );
-
- $res = $this->select( __METHOD__ );
-
- if ( is_null( $resultPageSet ) ) {
- $count = 0;
- foreach ( $res as $row ) {
- 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',
- "$row->rd_namespace|$row->rd_title|$row->rd_from"
- );
- break;
- }
-
- # Get the ID of the current page
- $id = $map[$row->rd_namespace][$row->rd_title];
-
- $vals = array();
- if ( $fld_pageid ) {
- $vals['pageid'] = $row->rd_from;
- }
- if ( $fld_title ) {
- ApiQueryBase::addTitleInfo( $vals,
- Title::makeTitle( $row->page_namespace, $row->page_title )
- );
- }
- if ( $fld_fragment && $row->rd_fragment !== null && $row->rd_fragment !== '' ) {
- $vals['fragment'] = $row->rd_fragment;
- }
- $fit = $this->addPageSubItem( $id, $vals );
- if ( !$fit ) {
- $this->setContinueEnumParameter( 'continue',
- "$row->rd_namespace|$row->rd_title|$row->rd_from"
- );
- break;
- }
- }
- } else {
- $titles = array();
- $count = 0;
- foreach ( $res as $row ) {
- 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',
- "$row->rd_namespace|$row->rd_title|$row->rd_from"
- );
- break;
- }
- $titles[] = Title::makeTitle( $row->page_namespace, $row->page_title );
- }
- $resultPageSet->populateFromTitles( $titles );
- }
- }
-
- public function getCacheMode( $params ) {
- return 'public';
- }
-
- public function getAllowedParams() {
- return array(
- 'prop' => array(
- ApiBase::PARAM_TYPE => array(
- 'pageid',
- 'title',
- 'fragment',
- ),
- ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_DFLT => 'pageid|title',
- ),
- 'show' => array(
- ApiBase::PARAM_TYPE => array(
- 'fragment', '!fragment',
- ),
- ApiBase::PARAM_ISMULTI => true,
- ),
- 'limit' => array(
- ApiBase::PARAM_DFLT => 10,
- ApiBase::PARAM_TYPE => 'limit',
- ApiBase::PARAM_MIN => 1,
- ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
- ),
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- return array(
- 'prop' => array(
- 'Which properties to get:',
- ' pageid - Page id of each redirect',
- ' title - Title of each redirect',
- ' fragment - Fragment of each redirect, if any',
- ),
- 'show' => array(
- 'Show only items that meet this criteria.',
- ' fragment - Only show redirects with a fragment',
- ' !fragment - Only show redirects without a fragment',
- ),
- 'limit' => 'How many redirects to return',
- 'continue' => 'When more results are available, use this to continue',
- );
- }
-
- public function getDescription() {
- return 'Returns all redirects to the given page(s).';
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=query&prop=redirects&titles=Main%20Page'
- => 'Get a list of redirects to the [[Main Page]]',
- 'api.php?action=query&generator=redirects&titles=Main%20Page&prop=info'
- => 'Get information about all redirects to the [[Main Page]]',
- );
- }
-
- public function getHelpUrls() {
- return 'https://www.mediawiki.org/wiki/API:Properties#redirects_.2F_rd';
- }
-}
global $wgContLang;
$data = array();
$aliases = $wgContLang->getSpecialPageAliases();
- foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
+ foreach ( SpecialPageFactory::getNames() as $specialpage ) {
if ( isset( $aliases[$specialpage] ) ) {
$arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
$this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
*/
/**
- * Bloom filter implented using Redis
+ * Bloom filter implemented using Redis
*
* The Redis server must be >= 2.6 and should have volatile-lru or volatile-ttl
* if there is any eviction policy. It should not be allkeys-* in any case. Also,
- * this can be used in a simple master/slave setup or with Redis Sentinal preferably.
+ * this can be used in a simple master/slave setup or with Redis Sentinel preferably.
*
* Some bits are based on https://github.com/ErikDubbelboer/redis-lua-scaling-bloom-filter
* but are simplified to use a single filter instead of up to 32 filters.
* @throws ConfigException
*/
public function get( $name );
+
+ /**
+ * Check whether a configuration option is set for the given name
+ *
+ * @param string $name Name of configuration option
+ * @return bool
+ * @since 1.24
+ */
+ public function has( $name );
}
* @see Config::get
*/
public function get( $name ) {
+ if ( !$this->has( $name ) ) {
+ throw new ConfigException( __METHOD__ . ": undefined option: '$name'" );
+ }
return $this->getWithPrefix( $this->prefix, $name );
}
+ /**
+ * @see Config::has
+ */
+ public function has( $name ) {
+ return $this->hasWithPrefix( $this->prefix, $name );
+ }
+
/**
* @see MutableConfig::set
* @deprecated since 1.24
*
* @param string $prefix Prefix to use on the variable, if one.
* @param string $name Variable name without prefix
- * @throws ConfigException
* @return mixed
*/
protected function getWithPrefix( $prefix, $name ) {
+ return $GLOBALS[$prefix . $name];
+ }
+
+ /**
+ * Check if a variable with a given prefix is set
+ *
+ * @param string $prefix Prefix to use on the variable
+ * @param string $name Variable name without prefix
+ * @return bool
+ */
+ protected function hasWithPrefix( $prefix, $name ) {
$var = $prefix . $name;
- if ( !array_key_exists( $var, $GLOBALS ) ) {
- throw new ConfigException( __METHOD__ . ": undefined variable: '$var'" );
- }
- return $GLOBALS[$var];
+ return array_key_exists( $var, $GLOBALS );
}
/**
--- /dev/null
+<?php
+/**
+ * Copyright 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * A Config instance which stores all settings as a member variable
+ *
+ * @since 1.24
+ */
+class HashConfig implements Config, MutableConfig {
+
+ /**
+ * Array of config settings
+ *
+ * @var array
+ */
+ private $settings;
+
+ /**
+ * @return HashConfig
+ */
+ public static function newInstance() {
+ return new HashConfig;
+ }
+
+ /**
+ * @param array $settings Any current settings to pre-load
+ */
+ public function __construct( array $settings = array() ) {
+ $this->settings = $settings;
+ }
+
+ /**
+ * @see Config::get
+ */
+ public function get( $name ) {
+ if ( !$this->has( $name ) ) {
+ throw new ConfigException( __METHOD__ . ": undefined option: '$name'" );
+ }
+
+ return $this->settings[$name];
+ }
+
+ /**
+ * @see Config::has
+ */
+ public function has( $name ) {
+ return array_key_exists( $name, $this->settings );
+ }
+
+ /**
+ * @see Config::set
+ */
+ public function set( $name, $value ) {
+ $this->settings[$name] = $value;
+ }
+}
--- /dev/null
+<?php
+/**
+ * Copyright 2014
+ *
+ * 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
+ */
+
+/**
+ * Provides a fallback sequence for Config objects
+ *
+ * @since 1.24
+ */
+class MultiConfig implements Config {
+
+ /**
+ * Array of Config objects to use
+ * Order matters, the Config objects
+ * will be checked in order to see
+ * whether they have the requested setting
+ *
+ * @var Config[]
+ */
+ private $configs;
+
+ /**
+ * @param Config[] $configs
+ */
+ public function __construct( array $configs ) {
+ $this->configs = $configs;
+ }
+
+ /**
+ * @see Config::get
+ */
+ public function get( $name ) {
+ foreach ( $this->configs as $config ) {
+ if ( $config->has( $name ) ) {
+ return $config->get( $name );
+ }
+ }
+
+ throw new ConfigException( __METHOD__ . ": undefined option: '$name'" );
+ }
+
+ /**
+ * @see Config::has
+ */
+ public function has( $name ) {
+ foreach ( $this->configs as $config ) {
+ if ( $config->has( $name ) ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
if ( wfRunHooks( 'ContentGetParserOutput',
array( $this, $title, $revId, $options, $generateHtml, &$po ) ) ) {
+ // Save and restore the old value, just in case something is reusing
+ // the ParserOptions object in some weird way.
+ $oldRedir = $options->getRedirectTarget();
+ $options->setRedirectTarget( $this->getRedirectTarget() );
$this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
+ $options->setRedirectTarget( $oldRedir );
}
return $po;
* @ingroup Content
*/
class WikitextContent extends TextContent {
+ private $redirectTargetAndText = null;
public function __construct( $text ) {
parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
*/
protected function getRedirectTargetAndText() {
global $wgMaxRedirects;
+
+ if ( $this->redirectTargetAndText !== null ) {
+ return $this->redirectTargetAndText;
+ }
+
if ( $wgMaxRedirects < 1 ) {
// redirects are disabled, so quit early
- return array( null, $this->getNativeData() );
+ $this->redirectTargetAndText = array( null, $this->getNativeData() );
+ return $this->redirectTargetAndText;
}
+
$redir = MagicWord::get( 'redirect' );
$text = ltrim( $this->getNativeData() );
if ( $redir->matchStartAndRemove( $text ) ) {
$title = Title::newFromText( $m[1] );
// If the title is a redirect to bad special pages or is invalid, return null
if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) {
- return array( null, $this->getNativeData() );
+ $this->redirectTargetAndText = array( null, $this->getNativeData() );
+ return $this->redirectTargetAndText;
}
- return array( $title, substr( $text, strlen( $m[0] ) ) );
+ $this->redirectTargetAndText = array( $title, substr( $text, strlen( $m[0] ) ) );
+ return $this->redirectTargetAndText;
}
}
- return array( null, $this->getNativeData() );
+ $this->redirectTargetAndText = array( null, $this->getNativeData() );
+ return $this->redirectTargetAndText;
}
/**
* @return ThumbnailImage
*/
function iconThumb() {
- global $wgScriptPath, $IP;
- $assetsPath = "$wgScriptPath/assets/file-type-icons/";
- $assetsDirectory = "$IP/assets/file-type-icons/";
+ global $wgResourceBasePath, $IP;
+ $assetsPath = "$wgResourceBasePath/resources/assets/file-type-icons/";
+ $assetsDirectory = "$IP/resources/assets/file-type-icons/";
$try = array( 'fileicon-' . $this->getExtension() . '.png', 'fileicon.png' );
foreach ( $try as $icon ) {
protected $mFieldTree;
protected $mShowReset = false;
protected $mShowSubmit = true;
+ protected $mSubmitModifierClass = 'mw-ui-constructive';
protected $mSubmitCallback;
protected $mValidationErrorMessage;
$attribs['class'] = array( 'mw-htmlform-submit' );
if ( $this->isVForm() || $useMediaWikiUIEverywhere ) {
- array_push( $attribs['class'], 'mw-ui-button', 'mw-ui-constructive' );
+ array_push( $attribs['class'], 'mw-ui-button', $this->mSubmitModifierClass );
}
if ( $this->isVForm() ) {
return $this;
}
+ /**
+ * Identify that the submit button in the form has a destructive action
+ *
+ */
+ public function setSubmitDestructive() {
+ $this->mSubmitModifierClass = 'mw-ui-destructive';
+ }
+
/**
* Set the text for the submit button to a message
* @since 1.19
if ( isset( $option['pass'] ) ) {
$this->setVar( '_AdminPassword', $option['pass'] );
}
+
+ // Set up the default skins
+ $skins = $this->findExtensions( 'skins' );
+ $this->setVar( '_Skins', $skins );
+
+ if ( $skins ) {
+ $skinNames = array_map( 'strtolower', $skins );
+ $this->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
+ }
}
/**
public $licenses = array(
'cc-by' => array(
'url' => 'http://creativecommons.org/licenses/by/3.0/',
- 'icon' => '{$wgScriptPath}/assets/licenses/cc-by.png',
+ 'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-by.png',
),
'cc-by-sa' => array(
'url' => 'http://creativecommons.org/licenses/by-sa/3.0/',
- 'icon' => '{$wgScriptPath}/assets/licenses/cc-by-sa.png',
+ 'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-by-sa.png',
),
'cc-by-nc-sa' => array(
'url' => 'http://creativecommons.org/licenses/by-nc-sa/3.0/',
- 'icon' => '{$wgScriptPath}/assets/licenses/cc-by-nc-sa.png',
+ 'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-by-nc-sa.png',
),
'cc-0' => array(
'url' => 'https://creativecommons.org/publicdomain/zero/1.0/',
- 'icon' => '{$wgScriptPath}/assets/licenses/cc-0.png',
+ 'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-0.png',
),
'pd' => array(
'url' => '',
- 'icon' => '{$wgScriptPath}/assets/licenses/public-domain.png',
+ 'icon' => '{$wgResourceBasePath}/resources/assets/licenses/public-domain.png',
),
'gfdl' => array(
'url' => 'http://www.gnu.org/copyleft/fdl.html',
- 'icon' => '{$wgScriptPath}/assets/licenses/gnu-fdl.png',
+ 'icon' => '{$wgResourceBasePath}/resources/assets/licenses/gnu-fdl.png',
),
'none' => array(
'url' => '',
return $exts;
}
+ /**
+ * Returns a default value to be used for $wgDefaultSkin: the preferred skin, if available among
+ * the installed skins, or any other one otherwise.
+ *
+ * @param string[] $skinNames Names of installed skins.
+ * @return string
+ */
+ public function getDefaultSkin( array $skinNames ) {
+ $defaultSkin = $GLOBALS['wgDefaultSkin'];
+ if ( in_array( $defaultSkin, $skinNames ) ) {
+ return $defaultSkin;
+ } else {
+ return $skinNames[0];
+ }
+ }
+
/**
* Installs the auto-detected extensions.
*
'var' => 'wgDefaultSkin',
'itemLabels' => array_fill_keys( $skinNames, 'config-skins-use-as-default' ),
'values' => $skinNames,
- 'value' => $this->getVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) ),
+ 'value' => $this->getVar( 'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) ),
) );
foreach ( $skins as $skin ) {
$this->addHTML( $this->getCCDoneBox() );
}
- /**
- * Returns a default value to be used for $wgDefaultSkin: the preferred skin, if available among
- * the installed skins, or any other one otherwise.
- *
- * @param string[] $skinNames Names of installed skins.
- * @return string
- */
- public function getDefaultSkin( array $skinNames ) {
- $defaultSkin = $GLOBALS['wgDefaultSkin'];
- if ( in_array( $defaultSkin, $skinNames ) ) {
- return $defaultSkin;
- } else {
- return $skinNames[0];
- }
- }
-
/**
* If the user skips this installer page, we still need to set up the default skins, but ignore
* everything else.
if ( $skins ) {
$skinNames = array_map( 'strtolower', $skins );
- $this->parent->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
+ $this->parent->setVar( 'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
}
return true;
{
- "@metadata": [],
+ "@metadata": {
+ "authors": [
+ "Чаховіч Уладзіслаў"
+ ]
+ },
+ "config-desc": "Інсталятар MediaWiki",
+ "config-information": "Інфармацыя",
+ "config-localsettings-key": "Ключ абнаўлення:",
+ "config-your-language": "Ваша мова:",
+ "config-wiki-language": "Мова Вікі:",
+ "config-back": "← Назад",
+ "config-page-language": "Мова",
+ "config-page-welcome": "Сардэчна запрашаем у MediaWiki!",
+ "config-page-name": "Назва",
+ "config-page-options": "Настройкі",
+ "config-upload-settings": "Загрузка выяў і файлаў",
"mainpagetext": "'''MediaWiki паспяхова ўсталяваная.'''",
"mainpagedocfooter": "Гл. [//meta.wikimedia.org/wiki/Help:Contents Дапаможнік карыстальніка (англ.)] па далейшыя звесткі аб карыстанні вікі-праграмамі.\n\n== З чаго пачаць ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Пералік параметраў канфігурацыі (англ.)]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ЧАПЫ MediaWiki (англ.)]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Ліставанне аб выпусках MediaWiki (англ.)]"
}
"아라",
"Elseweyr",
"Lliehu",
- "Syreeni"
+ "Syreeni",
+ "Stryn"
]
},
"config-desc": "MediaWiki-asennin",
"config-env-good": "Asennusympäristö on tarkastettu.\nVoit asentaa MediaWikin.",
"config-env-bad": "Asennusympäristö on tarkastettu.\nEt voi asentaa MediaWikiä.",
"config-env-php": "PHP $1 on asennettu.",
+ "config-env-hhvm": "HHVM $1 on asennettu.",
"config-no-db": "Sopivaa tietokanta-ajuria ei löytynyt! Sinun täytyy asentaa tietokanta-ajurit PHP:lle.\nSeuraavat tietokantatyypit ovat tuettuja: $1.",
"config-outdated-sqlite": "<strong>Varoitus:</strong> sinulla on käytössä SQLite $1, joke on vanhempi kuin vähintään vaadittava versio $2. SQLite ei ole saatavilla.",
"config-safe-mode": "'''Varoitus:''' PHP:n [http://www.php.net/features.safe-mode safe mode] -tila on aktiivinen.\nSe voi aiheuttaa ongelmia erityisesti tiedostojen tallentamisen ja matemaattisten kaavojen kanssa.",
*/
protected $editor;
+ /**
+ * @param User $editor The editor that triggered the update. Their notification
+ * timestamp will not be updated(they have already seen it)
+ * @param Title $title The title to update timestamps for
+ * @param string $timestamp Set the upate timestamp to this value
+ * @return int[]
+ */
+ public static function updateWatchlistTimestamp( User $editor, Title $title, $timestamp ) {
+ global $wgEnotifWatchlist, $wgShowUpdatedMarker;
+
+ if ( !$wgEnotifWatchlist && !$wgShowUpdatedMarker ) {
+ return array();
+ }
+
+ $dbw = wfGetDB( DB_MASTER );
+ $res = $dbw->select( array( 'watchlist' ),
+ array( 'wl_user' ),
+ array(
+ 'wl_user != ' . intval( $editor->getID() ),
+ 'wl_namespace' => $title->getNamespace(),
+ 'wl_title' => $title->getDBkey(),
+ 'wl_notificationtimestamp IS NULL',
+ ), __METHOD__
+ );
+
+ $watchers = array();
+ foreach ( $res as $row ) {
+ $watchers[] = intval( $row->wl_user );
+ }
+
+ if ( $watchers ) {
+ // Update wl_notificationtimestamp for all watching users except the editor
+ $fname = __METHOD__;
+ $dbw->onTransactionIdle(
+ function () use ( $dbw, $timestamp, $watchers, $title, $fname ) {
+ $dbw->update( 'watchlist',
+ array( /* SET */
+ 'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
+ ), array( /* WHERE */
+ 'wl_user' => $watchers,
+ 'wl_namespace' => $title->getNamespace(),
+ 'wl_title' => $title->getDBkey(),
+ ), $fname
+ );
+ }
+ );
+ }
+
+ return $watchers;
+ }
+
/**
* Send emails corresponding to the user $editor editing the page $title.
* Also updates wl_notificationtimestamp.
public function notifyOnPageChange( $editor, $title, $timestamp, $summary,
$minorEdit, $oldid = false, $pageStatus = 'changed'
) {
- global $wgEnotifUseJobQ, $wgEnotifWatchlist, $wgShowUpdatedMarker, $wgEnotifMinorEdits,
- $wgUsersNotifiedOnAllChanges, $wgEnotifUserTalk;
+ global $wgEnotifUseJobQ, $wgEnotifMinorEdits, $wgUsersNotifiedOnAllChanges, $wgEnotifUserTalk;
if ( $title->getNamespace() < 0 ) {
return;
}
- // Build a list of users to notify
- $watchers = array();
- if ( $wgEnotifWatchlist || $wgShowUpdatedMarker ) {
- $dbw = wfGetDB( DB_MASTER );
- $res = $dbw->select( array( 'watchlist' ),
- array( 'wl_user' ),
- array(
- 'wl_user != ' . intval( $editor->getID() ),
- 'wl_namespace' => $title->getNamespace(),
- 'wl_title' => $title->getDBkey(),
- 'wl_notificationtimestamp IS NULL',
- ), __METHOD__
- );
- foreach ( $res as $row ) {
- $watchers[] = intval( $row->wl_user );
- }
- if ( $watchers ) {
- // Update wl_notificationtimestamp for all watching users except the editor
- $fname = __METHOD__;
- $dbw->onTransactionIdle(
- function () use ( $dbw, $timestamp, $watchers, $title, $fname ) {
- $dbw->update( 'watchlist',
- array( /* SET */
- 'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
- ), array( /* WHERE */
- 'wl_user' => $watchers,
- 'wl_namespace' => $title->getNamespace(),
- 'wl_title' => $title->getDBkey(),
- ), $fname
- );
- }
- );
- }
- }
+ // update wl_notificationtimestamp for watchers
+ $watchers = self::updateWatchlistTimestamp( $editor, $title, $timestamp );
$sendEmail = true;
// If nobody is watching the page, and there are no users notified on all changes
# Determine scaler type
$scaler = $this->getScalerType( $dstPath );
+ if ( is_array( $scaler ) ) {
+ $scalerName = get_class( $scaler[0] );
+ } else {
+ $scalerName = $scaler;
+ }
+
wfDebug( __METHOD__ . ": creating {$scalerParams['physicalDimensions']} " .
- "thumbnail at $dstPath using scaler $scaler\n" );
+ "thumbnail at $dstPath using scaler $scalerName\n" );
if ( !$image->mustRender() &&
$scalerParams['physicalWidth'] == $scalerParams['srcWidth']
*/
public function rotate( $file, $params ) {
return new MediaTransformError( 'thumbnail_error', 0, 0,
- "$scaler rotation not implemented" );
+ get_class( $this ) . ' rotation not implemented' );
}
/**
*/
protected $onAccessCallback = null;
+ /**
+ * If the page being parsed is a redirect, this should hold the redirect
+ * target.
+ * @var Title|null
+ */
+ private $redirectTarget = null;
+
public function getInterwikiMagic() {
return $this->mInterwikiMagic;
}
return wfSetVar( $this->mIsPrintable, $x );
}
+ /**
+ * Set the redirect target.
+ *
+ * Note that setting or changing this does not *make* the page a redirect
+ * or change its target, it merely records the information for reference
+ * during the parse.
+ *
+ * @since 1.24
+ * @param Title|null $title
+ */
+ function setRedirectTarget( $title ) {
+ $this->redirectTarget = $title;
+ }
+
+ /**
+ * Get the previously-set redirect target.
+ *
+ * @since 1.24
+ * @return Title|null
+ */
+ function getRedirectTarget() {
+ return $this->redirectTarget;
+ }
+
/**
* Extra key that should be present in the parser cache key.
* @param string $key
$dbw = wfGetDB( DB_MASTER );
$useTrx = ( $dbw->getType() === 'sqlite' ); // much faster
if ( $useTrx ) {
- $dbw->begin();
+ $dbw->startAtomic( __METHOD__ );
}
foreach ( $this->mCollated as $name => $data ) {
$eventCount = $data['count'];
// "pf_time=pf_time + VALUES(pf_time)";
}
if ( $useTrx ) {
- $dbw->commit();
+ $dbw->endAtomic( __METHOD__ );
}
} catch ( DBError $e ) {
}
* @param string $localBasePath Base path to prepend to all local paths in $options. Defaults
* to $IP
* @param string $remoteBasePath Base path to prepend to all remote paths in $options. Defaults
- * to $wgScriptPath
+ * to $wgResourceBasePath
*
* Below is a description for the $options array:
* @throws MWException
* array(
* // Base path to prepend to all local paths in $options. Defaults to $IP
* 'localBasePath' => [base path],
- * // Base path to prepend to all remote paths in $options. Defaults to $wgScriptPath
+ * // Base path to prepend to all remote paths in $options. Defaults to $wgResourceBasePath
* 'remoteBasePath' => [base path],
* // Equivalent of remoteBasePath, but relative to $wgExtensionAssetsPath
* 'remoteExtPath' => [base path],
* @param string $localBasePath Path to use if not provided in module definition. Defaults
* to $IP
* @param string $remoteBasePath Path to use if not provided in module definition. Defaults
- * to $wgScriptPath
+ * to $wgResourceBasePath
* @return array Array( localBasePath, remoteBasePath )
*/
public static function extractBasePaths(
$localBasePath = null,
$remoteBasePath = null
) {
- global $IP, $wgScriptPath, $wgResourceBasePath;
+ global $IP, $wgResourceBasePath;
// The different ways these checks are done, and their ordering, look very silly,
// but were preserved for backwards-compatibility just in case. Tread lightly.
$localBasePath = $localBasePath === null ? $IP : $localBasePath;
if ( $remoteBasePath === null ) {
- $remoteBasePath = $wgResourceBasePath === null ? $wgScriptPath : $wgResourceBasePath;
+ $remoteBasePath = $wgResourceBasePath;
}
if ( isset( $options['remoteExtPath'] ) ) {
wfProfileIn( __METHOD__ );
$dbw = $this->sitesTable->getWriteDbConnection();
- $trx = $dbw->trxLevel();
-
- if ( $trx == 0 ) {
- $dbw->begin( __METHOD__ );
- }
-
+ $dbw->startAtomic( __METHOD__ );
$ok = $dbw->delete( 'sites', '*', __METHOD__ );
$ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
-
- if ( $trx == 0 ) {
- $dbw->commit( __METHOD__ );
- }
+ $dbw->endAtomic( __METHOD__);
$this->reset();
* @return string
*/
function getPoweredBy() {
- global $wgScriptPath;
+ global $wgResourceBasePath;
- $url = htmlspecialchars( "$wgScriptPath/assets/poweredby_mediawiki_88x31.png" );
+ $url = htmlspecialchars( "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png" );
$text = '<a href="//www.mediawiki.org/"><img src="' . $url
. '" height="31" width="88" alt="Powered by MediaWiki" /></a>';
wfRunHooks( 'SkinGetPoweredBy', array( &$text, $this ) );
private static $aliases;
/**
- * Get the special page list
+ * Reset the internal list of special pages. Useful when changing $wgSpecialPages after
+ * the internal list has already been initialized, e.g. during testing.
+ */
+ public static function resetList() {
+ self::$list = null;
+ self::$aliases = null;
+ }
+
+ /**
+ * Returns a list of canonical special page names.
+ * May be used to iterate over all registered special pages.
+ *
+ * @return string[]
+ */
+ public static function getNames() {
+ return array_keys( get_object_vars( self::getListObject() ) );
+ }
+
+ /**
+ * Get the special page list as an object, with each special page represented by a member
+ * field in the object.
*
- * @return array
+ * @deprecated since 1.24, use getNames() instead.
+ * @return object
*/
- static function getList() {
+ public static function getList() {
+ wfDeprecated( __FUNCTION__, '1.24' );
+ return self::getListObject();
+ }
+
+ /**
+ * Get the special page list as an object, with each special page represented by a member
+ * field in the object.
+ *
+ * @return object
+ */
+ private static function getListObject() {
global $wgSpecialPages;
global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
global $wgEnableEmail, $wgEnableJavaScriptTest;
// This hook can be used to remove undesired built-in special pages
wfRunHooks( 'SpecialPage_initList', array( &self::$list ) );
+ self::$list = (object)self::$list;
+
wfProfileOut( __METHOD__ );
}
* contain at least one entry (English fallbacks will be added if necessary).
* @return object
*/
- static function getAliasList() {
+ private static function getAliasListObject() {
if ( !is_object( self::$aliases ) ) {
global $wgContLang;
$aliases = $wgContLang->getSpecialPageAliases();
- $missingPages = self::getList();
+ // Objects are passed by reference by default, need to create a copy
+ $missingPages = clone self::getListObject();
self::$aliases = array();
// Check for $aliases being an array since Language::getSpecialPageAliases can return null
$caseFoldedAlias = $wgContLang->caseFold( $bits[0] );
$caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
- if ( isset( self::getAliasList()->$caseFoldedAlias ) ) {
- $name = self::getAliasList()->$caseFoldedAlias;
+ if ( isset( self::getAliasListObject()->$caseFoldedAlias ) ) {
+ $name = self::getAliasListObject()->$caseFoldedAlias;
} else {
return array( null, null );
}
public static function exists( $name ) {
list( $title, /*...*/ ) = self::resolveAlias( $name );
- $specialPageList = self::getList();
- return isset( $specialPageList[$title] );
+ return property_exists( self::getListObject(), $title );
}
/**
*/
public static function getPage( $name ) {
list( $realName, /*...*/ ) = self::resolveAlias( $name );
- $specialPageList = self::getList();
- if ( isset( $specialPageList[$realName] ) ) {
- $rec = $specialPageList[$realName];
+ if ( property_exists( self::getListObject(), $realName ) ) {
+ $rec = self::getListObject()->$realName;
+
if ( is_string( $rec ) ) {
$className = $rec;
-
- return new $className;
+ $page = new $className;
+ } elseif ( is_callable( $rec ) ) {
+ // Use callback to instantiate the special page
+ $page = call_user_func( $rec );
} elseif ( is_array( $rec ) ) {
$className = array_shift( $rec );
// @deprecated, officially since 1.18, unofficially since forever
wfDeprecated( "Array syntax for \$wgSpecialPages is deprecated ($className), " .
"define a subclass of SpecialPage instead.", '1.18' );
- $specialPageList[$realName] = MWFunction::newObj( $className, $rec );
+ $page = MWFunction::newObj( $className, $rec );
+ } elseif ( $rec instanceof SpecialPage ) {
+ $page = $rec; //XXX: we should deep clone here
+ } else {
+ $page = null;
+ }
+
+ if ( $page instanceof SpecialPage ) {
+ return $page;
+ } else {
+ // It's not a classname, nor a callback, nor a legacy constructor array,
+ // nor a special page object. Give up.
+ wfLogWarning( "Cannot instantiate special page $realName: bad spec!" );
+ return null;
}
- return $specialPageList[$realName];
} else {
return null;
}
global $wgUser;
$user = $wgUser;
}
- foreach ( self::getList() as $name => $rec ) {
+ foreach ( self::getListObject() as $name => $rec ) {
$page = self::getPage( $name );
if ( $page ) { // not null
$page->setContext( RequestContext::getMain() );
*/
public static function getRegularPages() {
$pages = array();
- foreach ( self::getList() as $name => $rec ) {
+ foreach ( self::getListObject() as $name => $rec ) {
$page = self::getPage( $name );
if ( $page->isListed() && !$page->isRestricted() ) {
$pages[$name] = $page;
global $wgUser;
$user = $wgUser;
}
- foreach ( self::getList() as $name => $rec ) {
+ foreach ( self::getListObject() as $name => $rec ) {
$page = self::getPage( $name );
if (
$page->isListed()
* @param IContextSource $context
* @return string HTML fragment
*/
- static function capturePath( Title $title, IContextSource $context ) {
+ public static function capturePath( Title $title, IContextSource $context ) {
global $wgOut, $wgTitle, $wgRequest, $wgUser, $wgLang;
// Save current globals
* @param string|bool $subpage
* @return string
*/
- static function getLocalNameFor( $name, $subpage = false ) {
+ public static function getLocalNameFor( $name, $subpage = false ) {
global $wgContLang;
$aliases = $wgContLang->getSpecialPageAliases();
* @param string $alias
* @return Title|null Title or null if there is no such alias
*/
- static function getTitleForAlias( $alias ) {
+ public static function getTitleForAlias( $alias ) {
list( $name, $subpage ) = self::resolveAlias( $alias );
if ( $name != null ) {
return SpecialPage::getTitleFor( $name, $subpage );
}
protected function alterForm( HTMLForm $form ) {
+ $form->setDisplayFormat( 'vform' );
$form->setId( 'mw-changeemail-form' );
$form->setTableId( 'mw-changeemail-table' );
- $form->setWrapperLegendMsg( 'changeemail-header' );
+ $form->setWrapperLegend( false );
$form->setSubmitTextMsg( 'changeemail-submit' );
- $form->addButton( 'wpCancel', $this->msg( 'changeemail-cancel' )->text(),
- null, array( 'formnovalidate')
- );
$form->addHiddenField( 'returnto', $this->getRequest()->getVal( 'returnto' ) );
}
$htmlForm = new HTMLForm( array(), $context, 'prefs-restore' );
$htmlForm->setSubmitTextMsg( 'restoreprefs' );
+ $htmlForm->setSubmitDestructive();
$htmlForm->setSubmitCallback( array( $this, 'submitReset' ) );
$htmlForm->suppressReset();
$link = $this->makeOptionsLink( $linkMessage->text(),
array( $key => 1 - $options[$key] ), $nondefaults );
- $links[] = $this->msg( $msg )->rawParams( $link )->escaped();
+ $links[] = "<span class=\"$msg rcshowhideoption\">" . $this->msg( $msg )->rawParams( $link )->escaped() . '</span>';
}
// show from this onward link
$now = $lang->userTimeAndDate( $timestamp, $user );
$timenow = $lang->userTime( $timestamp, $user );
$datenow = $lang->userDate( $timestamp, $user );
- $rclinks = $this->msg( 'rclinks' )->rawParams( $cl, $dl, $lang->pipeList( $links ) )
- ->parse();
- $rclistfrom = $this->makeOptionsLink(
+ $pipedLinks = '<span class="rcshowhide">' . $lang->pipeList( $links ) . '</span>';
+
+ $rclinks = '<span class="rclinks">' . $this->msg( 'rclinks' )->rawParams( $cl, $dl, $pipedLinks )
+ ->parse() . '</span>';
+
+ $rclistfrom = '<span class="rclistfrom">' . $this->makeOptionsLink(
$this->msg( 'rclistfrom' )->rawParams( $now, $timenow, $datenow )->parse(),
array( 'from' => $timestamp ),
$nondefaults
- );
+ ) . '</span>';
return "{$note}$rclinks<br />$rclistfrom";
}
</style>
</head>
<body>
- <img src="<?php echo htmlspecialchars( $path ) ?>assets/mediawiki.png" alt='The MediaWiki logo' />
+ <img src="<?php echo htmlspecialchars( $path ) ?>resources/assets/mediawiki.png" alt='The MediaWiki logo' />
<h1>MediaWiki <?php echo htmlspecialchars( $wgVersion ) ?></h1>
<div class='error'>
"protect-othertime": "Іншы тэрмін:",
"protect-othertime-op": "іншы тэрмін",
"protect-existing-expiry": "Наяўны час сканчэньня: $3, $2",
+ "protect-existing-expiry-infinity": "Наяўны тэрмін сканчэньня: бясконца",
"protect-otherreason": "Іншая/дадатковая прычына:",
"protect-otherreason-op": "Іншая прычына",
"protect-dropdown": "*Звычайныя прычыны абароны\n** Часты вандалізм\n** Празьмерны спам\n** Непрадуктыўная вайна рэдагаваньняў\n** Папулярная старонка",
"otherlanguages": "На іншых мовах",
"redirectedfrom": "(Пасля перасылкі з $1)",
"redirectpagesub": "Старонка-перасылка",
+ "redirectto": "Перасылае да",
"lastmodifiedat": "Апошняе змяненне старонкі адбылося $2, $1.",
"viewcount": "Гэту старонку адкрывалі {{PLURAL:$1|адзін раз|$1 разы|$1 разоў}}.",
"protectedpage": "Старонка пад аховай",
"searchall": "усе",
"showingresults": "Ніжэй паказаны да {{PLURAL:$1|'''$1''' выніку|'''$1''' вынікаў}}, пачынаючы з нумару '''$2'''.",
"showingresultsinrange": "Ніжэй паказаны да {{PLURAL:$1|<strong>1</strong> выніку|<strong>$1</strong> вынікаў}} у дыяпазоне ад #<strong>$2</strong> да #<strong>$3</strong>.",
- "showingresultsheader": "{{PLURAL:$5|Вынік '''$1''' из '''$3'''|Вынікі '''$1 — $2''' из '''$3'''}} для '''$4'''",
"search-nonefound": "Нічога не было знойдзена.",
"powersearch-legend": "Падрабязны пошук",
"powersearch-ns": "Шукаць у прасторах назваў:",
"viewtalkpage": "Хьажа дийцаре",
"otherlanguages": "Кхечу маттахь дерш",
"redirectedfrom": "(ДӀасахьажийна кху $1)",
- "redirectpagesub": "Ð\90гÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажайаÑ\80",
+ "redirectpagesub": "Ð\90гÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажоÑ\80г",
"redirectto": "ДӀасахьажор тӀе:",
"lastmodifiedat": "ХӀокху агӀон тӀаьххьаралера хийцам: $2, $1.",
"viewcount": "ХӀокху агӀонг хьовсийна $1 {{PLURAL:$1|за}}.",
"right-createtalk": "Дийцаре агӀонаш кхоллар",
"right-createaccount": "декъашхошна керла дӀаяздарш кхоллар",
"right-minoredit": "«къезиг хийцам» аьлла билгало хӀоттор",
- "right-move": "Ð\90гÓ\80онаÑ\88ан цӀераш хийцар",
+ "right-move": "Ð\90гÓ\80онийн цӀераш хийцар",
"right-move-subpages": "АгӀонашан цӀераш хийцар цера бухара агӀонашцан",
"right-move-rootuserpages": "декъашхочун ораман агӀонийн цӀераш хийцар",
"right-move-categorypages": "Категорийн агӀонийн цӀераш хийцар",
"right-movefile": "Файлийн цӀе хийцар",
- "right-suppressredirect": "агÓ\80она Ñ\86Ó\80е Ñ\85Ñ\83Ñ\8cйÑ\86Ñ\83Ñ\88 Ñ\88иÑ\80Ñ\87Ñ\83 Ñ\86Ó\80аÑ\80аÑ\85 ма кÑ\85олла дÓ\80аÑ\81аÑ\85Ñ\8cажаÑ\8fÑ\80",
+ "right-suppressredirect": "агÓ\80она Ñ\86Ó\80е Ñ\85Ñ\83Ñ\8cйÑ\86Ñ\83Ñ\88 Ñ\88иÑ\80Ñ\87Ñ\83 Ñ\86Ó\80аÑ\80аÑ\85 ма кÑ\85олла дÓ\80аÑ\81аÑ\85Ñ\8cажоÑ\80г",
"right-upload": "Файлаш чуйаьхар",
"right-reupload": "йолуш йолу чера тӀехула файлаш дӀаязъяр",
"right-reupload-own": "тохарлеррачу декъашхочо файлаш юху дӀаязъяр",
"deletecomment": "Бахьна:",
"deleteotherreason": "Кхин бахьна/тӀетохар:",
"deletereasonotherlist": "Кхин бахьна",
- "deletereason-dropdown": "* Даржина долу дӀаяккхаран баьхьанаш \n** зулма \n** авторан лаамца\n** авторан бакъонаш талхор",
+ "deletereason-dropdown": "* Даржина долу дӀаяккхаран баьхьанаш \n** спам\n** зулма \n** авторан лаамца\n** авторан бакъонаш талхор\n** болх цабо дӀасхьажорг",
"delete-edit-reasonlist": "Бахьанин могӀам нисбар",
"deleting-backlinks-warning": "'''ДӀахьедар:''' Ахьа дӀайоккхуш йолчун тӀе товжийна [[Special:WhatLinksHere/{{FULLPAGENAME}}|кхин агӀонаш]] ю.",
"rollback": "Юхабаккха хийцам",
"linkshere": "ТӀаьхьайогӀу агӀонаш оцу '''[[:$1]]''': хьажорагца ю",
"nolinkshere": "ХӀокху '''[[:$1]]''' агӀона тӀе кхечу агӀонашкахь хьажоргаш яц.",
"nolinkshere-ns": "Хаьржинчу анахь яц '''[[:$1]]''' цӀе йолу агӀонаш",
- "isredirect": "агÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажайаÑ\80",
+ "isredirect": "агÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажоÑ\80г",
"istemplate": "юкъаялийнарш",
"isimage": "Файлан хьажораг",
"whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайодарг|хьалхайодарш}} $1",
"movepagetext": "Бухахь йолу форманца агӀон цӀе хийцало. Цул совнах цуьна хийцаман тептар кхоьчу метте доккха. Хьалхалера цӀарахь хиръю керла кхоьллина агӀонан хьажораг.\n\nХьовсалаш [[Special:DoubleRedirects|шалха]] а [[Special:BrokenRedirects|йохна хьажоргаш]] юй техь аьлла.\n\nШу жоьпехь ду хьажоргаш нийса некъ гойтуш хиларан.\n\nТидам бе хьалхалера агӀон цӀе ‘’’хийцалур яц’’’ иштта цӀе йолу агӀо йолуш елахь. Юкъардаккхар: йолуш йолу агӀо кхоьчухьа хьажораг елахь, я еса елахь а, цуьна хийцаме истори яцахь а.\n\nИ бохург ду шун агӀонан цӀе юха а хьалха хилларгчунтӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
"movepagetext-noredirectfixer": "Бухахь йолу форманца агӀон цӀе хийцало. Цул совнах цуьна хийцаман тептар кхоьчу метте доккха. Хьалхалера цӀарахь хиръю керла кхоьллина агӀонан хьажораг.\n\nХьовсалаш [[Special:DoubleRedirects|шалха]] а [[Special:BrokenRedirects|йохна хьажоргаш]] юй техь аьлла.\n\nШу жоьпехь ду хьажоргаш нийса некъ гойтуш хиларан.\n\nТидам бе хьалхалера агӀон цӀе ‘’’хийцалур яц’’’ иштта цӀе йолу агӀо йолуш елахь. Юкъардаккхар: йолуш йолу агӀо кхоьчухьа хьажораг елахь, я еса елахь а, цуьна хийцаме истори яцахь а.\n\nИ бохург ду шун агӀонан цӀе юха а хьалха хилларгчунтӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
"movepagetalktext": "ТӀе хӀоьттина йолу дийцаре агӀо ишта цӀе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''\n\n*Йаьсса йоцу дийцаре агӀо йолуш ю оцу цӀарца йа\n*Ахьа къастаман харжам цабиняхь а къастам хӀотточехь.\n\nИшта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хӀоттайар, нагахь иза хьашт йалахь.",
- "movearticle": "Цle хийца хlокху агlон",
+ "movearticle": "ЦӀе хийца хӀокху агӀон",
"moveuserpage-warning": "'''Тергам бе.''' Хьо декъашхочун агӀона цӀе хийца гӀерта. Дехар до, тергам бе, декъашхочун агӀона цӀе бен хийца лур яц, декъашхочун дӀаяздаран цӀе хийца лур яц.",
"movecategorypage-warning": "<strong>ДӀахьедар:</strong> Хьо категорин агӀон цӀе хийца гӀерта. Дехар до, терго йе, хӀокху агӀона бен цӀе хуьйцур яц, шира чу категори чура массо агӀонаш керла категори чу йохур <em>яц</em>.",
"movenologintext": "АгӀона цӀе хийца [[Special:UserLogin|системин чугӀо]].",
"movepage-moved-noredirect": "ДӀасхьажорг кхоллар дохина.",
"articleexists": "ХӀарасанна цӀе йолу агӀо йолуш ю йа ахьа гойтуш йолу цӀе магош яц.\nДехар до, харжа кхин цӀе.",
"movetalk": "Цуьнца йогӀуш йолу дийцаре агӀон цӀе хийцар",
- "move-subpages": "ЦӀeрш хийцае бухара агӀонаши ($1 кхаччалц)",
+ "move-subpages": "ЦӀераш хийца бухара агӀонийн ($1 кхаччалц)",
"move-talk-subpages": "ЦӀе хийца бухара агӀонаши а агӀонашан дийцаре а ($1 кхаччалц)",
"movepage-page-exists": "Агӏо $1 йолуш ю цундела и ша юху дӏаязъян йиш яц.",
"movepage-page-moved": "АгӀона $1 цӀе хийцина → $2.",
"resetpass-submit-cancel": "ھەڵوەشاندنەوە",
"resetpass-wrong-oldpass": "تێپەڕوشەی ھەنووکەیی یان تێپەڕوشەی کاتی ھەڵەیە.\nوا دیارە تێپەڕوشەکەت بە سەرکەوتوویی گۆڕدراوە یان داوای تێپەڕوشەیەکی نوێت کردووە.",
"resetpass-temp-password": "تێپەڕوشەی کاتی:",
- "passwordreset": "دووبارە ڕێکخستنەوەی تێپەڕوشە",
+ "passwordreset": "ڕێکخستنەوەی تێپەڕوشە",
"passwordreset-legend": "دووبارە ڕێکخستنەوەی تێپەڕوشە",
"passwordreset-username": "ناوی بەکارھێنەری:",
"passwordreset-domain": "پاوان:",
"passwordreset-emailsent": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا.",
"passwordreset-emailsent-capture": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا، کە لە ژێرەوە نیشان دراوە.",
"passwordreset-emailerror-capture": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا، کە لە ژێرەوە نیشان دراوە، بەڵام ناردنەکەی بۆ {{GENDER:$2|بەکارھێنەر}} سەرکەوتوو نەبوو: $1",
- "changeemail": "ناونیشانی ئیمەیل بگۆڕە",
+ "changeemail": "گۆڕینی ناونیشانی ئیمەیل",
"changeemail-header": "ناونیشانی ئیمەیلی ھەژمار بگۆڕە",
"changeemail-no-info": "بۆ گەیشتنی راستەوخۆ بەم پەڕە دەبێت بچیتە ژوورەوە.",
"changeemail-oldemail": "ئەدرەسی ئیمەیڵی ئێستا:",
"mimesearch-summary": "ئەم لاپەڕە پاڵێوتنی هەیە بۆ جۆرەکانی MIME.\nناودراو: جۆرەی ناوەڕۆک\\ژێرجۆرە، وەک <code>image/jpeg</code>.",
"mimetype": "جۆرەی MIME:",
"download": "داگرتن",
- "unwatchedpages": "پەڕە چاودێرینەکراوەکان",
+ "unwatchedpages": "پەڕە چاودێری نەکراوەکان",
"listredirects": "پێرستی ڕەوانەکەرەکان",
- "unusedtemplates": "داڕێژە بەکارنەھێنراوەکان",
+ "unusedtemplates": "داڕێژە بەکارنەھاتووەکان",
"unusedtemplatestext": "ئەم پەڕە هەموو پەڕەکانی بۆشاییی ناوی {{ns:template}} بە لیست دەکات کە لە پەڕەی تردا بەکارنەھێنراون.\nلە بیری نەکەی پێش سڕینەوەیان پشکنینی بەستەرەکانی تر بۆ داڕێژەکان بکەی.",
"unusedtemplateswlh": "بەستەرەکانی تر",
"randompage": "پەڕەی ھەڕەمەکی",
"withoutinterwiki-summary": "ئەم پەڕانە بەستەریان بۆ وەشانەکانی زمانەکانی تر نیە.",
"withoutinterwiki-legend": "پێشگر",
"withoutinterwiki-submit": "پیشاندان",
- "fewestrevisions": "پەڕەکان بە کەمترین پێداچوونەوەکان",
+ "fewestrevisions": "پەڕەکان بە کەمترین پێداچوونەوە",
"nbytes": "$1 {{PLURAL:$1|بایت|بایت}}",
"ncategories": "$1 {{PLURAL:$1|ھاوپۆل|ھاوپۆل}}",
"ninterwikis": "$1 {{PLURAL:$1|نێوانویکی}}",
"uncategorizedimages": "پەڕگە پۆلێن نەکراوەکان",
"uncategorizedtemplates": "داڕێژە پۆلێن نەکراوەکان",
"unusedcategories": "پۆلە بەکارنەھێنراوەکان",
- "unusedimages": "پەڕگە بەکارنەھێنراوەکان",
+ "unusedimages": "پەڕگە بەکارنەھاتووەکان",
"popularpages": "پەڕە مەحبووبەکان",
"wantedcategories": "پۆلە داواکراوەکان",
"wantedpages": "پەڕە داواکراوەکان",
"protectedpages-page": "پەڕە",
"protectedpages-params": "پارامەترەکانی پاراستن",
"protectedpages-reason": "ھۆکار",
- "protectedtitles": "سەرناوە پارێزراوەکان",
+ "protectedtitles": "سەردێڕە پارێزراوەکان",
"protectedtitlesempty": "ھیچ سەرناوێک بەم سنوورانەوە ئێستا نەپارێزراوە.",
"listusers": "پێرستی بەکارھێنەران",
"listusers-editsonly": "تەنیا ئەو بەکارھێنەرانە نیشان بدە کە دەستکارییان کردووە",
"listusers-submit": "نیشانیبدە",
"listusers-noresult": "ھیچ بەکارھێنەرێک نەدۆزرایەوە.",
"listusers-blocked": "(بەربەست کراوە)",
- "activeusers": "پێرستی بەکارھێنەرە چالاکەکان",
+ "activeusers": "پێرستی بەکارھێنەرانی چالاک",
"activeusers-intro": "ئەمە لیستێکی ئەو بەکارھێنەرانەیە کە لە $1 {{PLURAL:$1|ڕۆژ|ڕۆژ}}ی ڕابردوودا بە جۆرێک چالاکییەکیان ھەبووە.",
"activeusers-count": "$1 {{PLURAL:$1|کردەوە}} لە دوایین {{PLURAL:$3|ڕۆژ|$3 ڕۆژ}}دا",
"activeusers-from": "نیشاندانی بەکارھێنەران بە دەستپێکردن لە:",
"listgrouprights-namespaceprotection-header": "سنوورداریی بۆشایی ناو",
"listgrouprights-namespaceprotection-namespace": "بۆشایی ناو",
"listgrouprights-namespaceprotection-restrictedto": "مافی رێپێدراوی بەکارھێنەر بۆ دەستکاری",
+ "trackingcategories": "پۆلەکانی شوێنکەوتن",
"trackingcategories-name": "ناوی پەیام",
"mailnologin": "ناونیشان بۆ ناردن نییه",
"mailnologintext": "دهبێ له [[Special:UserLogin|ژوورهوه]] بیت و ناونیشانێکی بڕواپێکراوی ئیمهیلت له ناو [[Special:Preferences|ههڵبژاردهکان]] دیاری کردبێت تا بتوانی ئیمهیل بنێریت بۆ بهکارهێنهرانی دیکه.",
"whatlinkshere-hidelinks": "$1 بەستەر",
"whatlinkshere-hideimages": "$1 بەستەرەکانی پەڕگە",
"whatlinkshere-filters": "پاڵێوکەکان",
- "block": "بەربەستکردنی بەکارھێنەر",
+ "block": "بەربەستنی بەکارھێنەر",
"unblock": "لە بەربەستدەرهێنانی بەکارهێنەر",
"blockip": "بەربەستنی بەکارھێنەر",
"blockip-legend": "بەربەستکردنی بەکارهێنەر",
"ipusubmit": "لابردنی ئەم بەربەستە",
"unblocked": "[[User:$1|$1]] لە بەربەست دەرهێنرا",
"unblocked-id": "بەربەستی $1 لابرا",
- "blocklist": "بەکارھێنەر بەربەستکراوەکان",
+ "blocklist": "بەکارھێنەرانی بەربەسراو",
"ipblocklist": "بەکارھێنەرە بەربەستکراوەکان",
"ipblocklist-legend": "دۆزینەوەی بەکارهێنەرێکی بەربەستکراو",
"blocklist-userblocks": "ھەژمارە بەربەستکراوەکان بشارەوە",
"version-software-version": "وەشان",
"version-entrypoints-header-url": "ناونیشانی ئینتەرنێتی",
"redirect": "ڕەوانەکەر بە پێی پەڕگە، بەکارھێنەر، پەڕە یان پێناسەی پێداچوونەوە",
+ "redirect-legend": "ڕەوانەکەر بۆ پەڕگە یان پەڕەیەک",
+ "redirect-summary": "ئەم پەڕە تایبەتە ڕەوانە دەکرێ بۆ پەڕگەیەک (ناوی پەڕگەکە)، پەڕەیەک (پێناسەی پێداچوونەوەیەک یان پێناسەی پەڕە) یان پەڕەیەکی بەکارھێنەر (پێناسەیەکی ژمارەیی بەکارھێنەر). بەکارھێنان: [[{{#Special:Redirect}}/file/Example.jpg]]، [[{{#Special:Redirect}}/page/64308]]، [[{{#Special:Redirect}}/revision/328429]] یان [[{{#Special:Redirect}}/user/101]].",
"redirect-submit": "بڕۆ",
+ "redirect-lookup": "گەڕان لە:",
+ "redirect-value": "نرخ:",
+ "redirect-user": "پێناسەی بەکارھێنەر",
+ "redirect-page": "پێناسەی پەڕە",
+ "redirect-revision": "پێداچوونەوەی پەڕە",
+ "redirect-file": "ناوی پەڕگە",
"fileduplicatesearch": "گەڕان بۆ پەڕگە دووپات کراوەکان",
"fileduplicatesearch-summary": "گەڕان بۆ پەڕگە دووبارەکراوەکان لەسەر بنەمای نرخی hash.",
"fileduplicatesearch-legend": "گەڕان بۆ دووبارەکردنێک",
"fileduplicatesearch-noresults": "پەڕگەیەک بە ناوی «$1» نەدۆزرایەوە.",
"specialpages": "پەڕە تایبەتەکان",
"specialpages-note": "* پەڕە تایبەتە ئاسایییەکان.\n* <span class=\"mw-specialpagerestricted\">پەڕە تایبەتە بەرگریلێکراوەکان.</span>",
- "specialpages-group-maintenance": "Ú\95اپÛ\86رتÛ\95کاÙ\86Û\8c Ú\86اکسازÛ\8c",
+ "specialpages-group-maintenance": "Ú\95اپÛ\86رتÛ\95کاÙ\86Û\8c Ú\95اگرتÙ\86",
"specialpages-group-other": "پەڕە تایبەتەکانی دیکە",
"specialpages-group-login": "چوونەژوورەوە / دروستکردنی ھەژمار",
"specialpages-group-changes": "دوایین گۆڕانکارییەکان و لۆگەکان",
"blankpage": "پەڕەی واڵا",
"intentionallyblankpage": "ئەم پەڕەیە لەقەست واڵا ھێڵراوەتەوە.",
"external_image_whitelist": " #ئەم دێڕ ھەر بەم جۆرە کە ھەیە بەجێبێڵە<pre>\n#کەرتەکانی regular expression (تەنیا ئە بەشە کە لە نێوان // دا دێت) لە خوارەوە دابنێ\n#These will be matched with the URLs of external (hotlinked) images\n#Those that match will be displayed as images, otherwise only a link to the image will be shown\n#ئەو دێڕانە بە # دەست پێدەکەن وەک شرۆڤە (comments) مامەڵەیان لەگەڵ دەکرێ\n#بە گەورە و بچووکی پیتەکان ھەستیارە (case-insensitive)\n\n#گشت کەرتەکانی regex لە سەرەوەی ئەم دێرەدا دابنێ. ئەم دێڕ ھەر بەم جۆرە کە ھەیە بەجێبێڵە</pre>",
- "tags": "گۆڕانکاری گونجاوی تاگەکان",
+ "tags": "تاگەکانی گۆڕانکاریی گونجاو",
"tag-filter": "پاڵێوی [[Special:Tags|تاگ]]:",
"tag-filter-submit": "پاڵاوتن",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|تاگ|تاگەکان}}]]: $2)",
"feedback-message": "پەیام:",
"feedback-cancel": "ھەڵیوەشێنەوە",
"feedback-submit": "تێبینییەکان بنێرە",
- "feedback-close": "ئەنجام درا",
+ "feedback-close": "کرا",
"searchsuggest-search": "گەڕان",
"searchsuggest-containing": "بە لەبەرگرتنەوەی ...",
"api-error-empty-file": "ئەو پەڕگەیە کە ناردووتە واڵا بوو.",
"protect-othertime": "Jiný čas vypršení:",
"protect-othertime-op": "jiný čas",
"protect-existing-expiry": "Současný čas vypršení: $2, $3",
+ "protect-existing-expiry-infinity": "Současný čas vypršení: do odvolání",
"protect-otherreason": "Jiný/další důvod:",
"protect-otherreason-op": "Jiný důvod",
"protect-dropdown": "*Obvyklé důvody zamčení\n** Opakovaný vandalismus\n** Vkládání reklamních externích odkazů\n** Editační válka\n** Často používaná stránka",
"tooltip-pt-anonuserpage": "Uživatelská stránka pro IP adresu, ze které editujete",
"tooltip-pt-mytalk": "Vaše diskusní stránka",
"tooltip-pt-anontalk": "Diskuse o editacích provedených z této IP adresy",
- "tooltip-pt-preferences": "Moje nastavení",
- "tooltip-pt-watchlist": "Seznam stránek, jejichž změny sleduji",
+ "tooltip-pt-preferences": "Vaše nastavení",
+ "tooltip-pt-watchlist": "Seznam stránek, jejichž změny sledujete",
"tooltip-pt-mycontris": "Seznam vašich příspěvků",
"tooltip-pt-login": "Doporučujeme vám přihlásit se, ovšem není to povinné.",
"tooltip-pt-logout": "Odhlásit se",
"protect-othertime": "Andere Sperrdauer:",
"protect-othertime-op": "andere Sperrdauer",
"protect-existing-expiry": "Aktuelles Seitenschutzende: $2, $3 Uhr",
+ "protect-existing-expiry-infinity": "Vorhandene Ablaufzeit: unbeschränkt",
"protect-otherreason": "Anderer/ergänzender Grund:",
"protect-otherreason-op": "Anderer Grund",
"protect-dropdown": "* Allgemeine Schutzgründe\n** Edit-War\n** Wiederkehrender Vandalismus\n** Wiederholtes Einstellen von Werbung\n** Häufig eingebundene Vorlage\n** Seite mit hoher Besucherzahl",
"prefs-help-email-others": "Ét pō ânca sernîr ed lasêr che chiêter a 's mèten in cuntât tēgh cun la pôsta eletrônica cun al colegamèint da la tó pàgina utèint o da còla 'd discusiòun. Al tó indirés al vîn mìa fât savèir a quî ch'ét 's mèten in cuntât tēgh.",
"prefs-help-email-required": "L'indirés ed pôsta eletrônica l'é ubligatôri.",
"prefs-info": "Infurmasiòun necesâri",
+ "prefs-i18n": "Internalişasiòun",
"prefs-signature": "Fîrma",
"prefs-dateformat": "Fōrma 'd la dâta",
"prefs-timeoffset": "Ōri 'd diferèinsa",
"saveusergroups": "Sêlva gróp utèint",
"userrights-groupsmember": "Al fà pêrt {{PLURAL:$1|al gróp|ai gróp}}:",
"userrights-groupsmember-auto": "Al fà pêrt ed sicûr a:",
+ "userrights-groups-help": "L'é pusébil mudifichêr i gróp in dó fà pêrt l'utèint. \n*'Na caşèla sernîda la sègna a che gróp al fà pêrt l'utèint. \n*'Na caşèla mìa serrnîda la sègna che l'utèin al fà mìa pêrt al gróp. \n*Al sègn * al sègna ch' an n'é m'a pusébil scanşlêr che l'utèin al fà pêrt al gróp dōp avèirel sgnê (o invicivêrsa).",
"userrights-reason": "Mutîv:",
+ "userrights-no-interwiki": "An es gh'à mìa i permès necesâri per cambiêr i dirét ed j utèint in sém a êter sît.",
+ "userrights-nodatabase": "Al databēş $1 al gh'é mìa o an n' mìa un databêş lochêl.",
+ "userrights-nologin": "Per dêr i dirét a j utèint l'é necesâri [[Special:UserLogin|fêr l'ingrès]] cme aministardōr.",
+ "userrights-notallowed": "An 't gh'ê mìa al permès per zuntêr o tōr via i permès utèint.",
+ "userrights-changeable-col": "Gróp ch'es pōlen mudifichêr.",
+ "userrights-unchangeable-col": "Gróp ch'an 's pōlen mìa mudifichêr.",
+ "userrights-conflict": "Cuntrâst ed mudéfica di dirét utèint! Cuntròla e cunfērma al tó mudéfichi.",
+ "userrights-removed-self": "T'é tôt via cun sucès i tō dirét. E dòunca, an 't prê pió andêr dèinter a cla pàgina ché.",
"group": "Gróp:",
"group-user": "Utèint",
"group-autoconfirmed": "Utèint cunvalidê da per ló",
"grouppage-suppress": "{{ns:project}}:Oversight",
"right-read": "Al lēş al pàgini",
"right-edit": "Mudéfica pàgini",
+ "right-createpage": "Ét pō fêr al pàgini (fōra che 'l pàgini 'd discusiòun).",
+ "right-createtalk": "Fà 'l pàgini 'd discusiòun.",
+ "right-createaccount": "Fà dal j utèinsi nōvi.",
+ "right-minoredit": "Sègna 'l mudéfichi cme céchi.",
+ "right-move": "Spôsta 'l pàgini",
+ "right-move-subpages": "Spôsta 'l pàgini insèm al relatîvi sòt pàgini",
+ "right-move-rootuserpages": "Spôsta 'l pàgini principêli 'd j utèint",
+ "right-move-categorypages": "Spôsta 'l categoréi",
+ "right-movefile": "Spôsta i file",
+ "right-suppressredirect": "An fà mìa un indirés nōv in atvomâtich quând a se spôsta 'na pàgina",
+ "right-upload": "Cârga un file",
+ "right-reupload": "Al scré in sém a 'n file ch' al gh'é bèle",
+ "right-reupload-own": "Al scré in sém a 'n file ch' al gh'é bèle carghê da l'istès utèint",
"newuserlogpage": "Utèint nōv",
"action-read": "lēzer cla pàgina ché",
"action-edit": "Mudifichêr cla pàgina ché",
"preferences-summary": "",
"mypreferences": "Preferences",
"prefs-edits": "Number of edits:",
- "prefsnologintext2": "Please login to change your preferences.",
+ "prefsnologintext2": "Please log in to change your preferences.",
"prefs-skin": "Skin",
"skin-preview": "Preview",
"datedefault": "No preference",
"mywatchlist": "Watchlist",
"watchlistfor2": "For $1 $2",
"nowatchlist": "You have no items on your watchlist.",
- "watchlistanontext": "Please login to view or edit items on your watchlist.",
+ "watchlistanontext": "Please log in to view or edit items on your watchlist.",
"watchnologin": "Not logged in",
"addwatch": "Add to watchlist",
"addedwatchtext": "The page \"[[:$1]]\" has been added to your [[Special:Watchlist|watchlist]].\nFuture changes to this page and its associated talk page will be listed there.",
"protect-othertime": "Other time:",
"protect-othertime-op": "other time",
"protect-existing-expiry": "Existing expiry time: $3, $2",
+ "protect-existing-expiry-infinity": "Existing expiry time: infinite",
"protect-otherreason": "Other/additional reason:",
"protect-otherreason-op": "Other reason",
"protect-dropdown": "*Common protection reasons\n** Excessive vandalism\n** Excessive spamming\n** Counter-productive edit warring\n** High traffic page",
"category-file-count": "{{PLURAL:$2|Selles kategoorias on ainult järgmine fail.|{{PLURAL:$1|Järgmine fail |Järgmised $1 faili}} on selles kategoorias (kokku $2).}}",
"category-file-count-limited": "{{PLURAL:$1|Järgmine fail|Järgmised $1 faili}} on selles kategoorias.",
"listingcontinuesabbrev": "jätk",
- "index-category": "Indeksiga leheküljed",
+ "index-category": "Indekseeritud leheküljed",
"noindex-category": "Indekseerimata leheküljed",
"broken-file-category": "Katkiste pildilinkidega leheküljed",
"about": "Tiitelandmed",
"searchall": "kõik",
"showingresults": "Allpool näidatakse '''{{PLURAL:$1|ühte|$1}}''' tulemust alates '''$2'''. tulemusest.",
"showingresultsinrange": "Allpool näidatakse {{PLURAL:$1|<strong>üht</strong>|<strong>$1</strong>}} tulemust vahemikus <strong>$2</strong>–<strong>$3</strong>.",
+ "search-showingresults": "{{PLURAL:$4|<strong>$1</strong>. tulemus <strong>$3</strong>-st|Tulemused <strong>$1–$2</strong> <strong>$3</strong>-st}}",
"search-nonefound": "Päringule ei leitud vasteid.",
"powersearch-legend": "Täpsem otsing",
"powersearch-ns": "Otsing nimeruumidest:",
"unblocked": "Kasutaja [[User:$1|$1]] blokeering on eemaldatud",
"unblocked-range": "Vahemiku $1 blokeering on eemaldatud",
"unblocked-id": "Blokeerimine $1 on lõpetatud",
+ "unblocked-ip": "IP-aadressi [[Special:Contributions/$1|$1]] blokeering on eemaldatud.",
"blocklist": "Blokeeritud kasutajad",
"ipblocklist": "Blokeeritud kasutajad",
"ipblocklist-legend": "Leia blokeeritud kasutaja",
"log-name-pagelang": "Keele muutmise logi",
"log-description-pagelang": "Siia on logitud lehekülgede keele muutmised.",
"logentry-pagelang-pagelang": "$1 {{GENDER:$2|muutis}} lehekülje \"$3\" keelt: $4 → $5.",
- "default-skin-not-found": "Oih! Sinu viki vaikekujundus (<code>$wgDefaultSkin</code>) <code>$1</code> pole saadaval.\n\nPaistab, et sinu install sisaldab järgmisi kujundusi. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas neid lubada ja kuidas valida vaikekujundus.\n\n$2\n\n; Kui oled MediaWiki just paigaldanud:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code>skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja.\n\n; Kui oled MediaWikit just täiendanud:\n: MediaWiki 1.24-s ja uuemates versioonides pole paigaldatud kujundused enam automaatselt lubatud (vaata juhendist [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery kujunduste automaatse leidmise] kohta). Saad kleepida järgmised read leheküljele <code>LocalSettings.php</code>, et lubada kõik praegu paigaldatud kujundused:\n\n<pre>$3</pre>\n\n; Kui oled lehekülge <code>LocalSettings.php</code> just muutnud:\n: Kontrolli üle, ega kujunduste nimedes pole trükivigu.",
- "default-skin-not-found-no-skins": "Oih! Sinu viki vaikekujundus (<code>$wgDefaultSkin</code>) <code>$1</code> pole saadaval.\n\nÜhtegi kujundust pole paigaldatud.\n\n; Kui oled MediaWiki just paigaldanud või täiendasid seda:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. MediaWiki 1.24 ja uuemad versioonid ei sisalda peahoidlas ühtegi kujundust. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code>skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas kujundusi lubada ja kuidas valida vaikekujundus.",
+ "default-skin-not-found": "Oih! Sinu viki vaikekujundus, milleks muutuja <code dir=\"ltr\">$wgDefaultSkin</code> järgi on <code>$1</code>, pole saadaval.\n\nPaistab, et sinu install sisaldab järgmisi kujundusi. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas neid lubada ja kuidas valida vaikekujundus.\n\n$2\n\n; Kui oled MediaWiki just paigaldanud:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code dir=\"ltr\">skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja.\n\n; Kui oled MediaWikit just täiendanud:\n: MediaWiki 1.24-s ja uuemates versioonides pole paigaldatud kujundused enam automaatselt lubatud (vaata juhendist [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery kujunduste automaatse leidmise] kohta). Saad kleepida järgmised read leheküljele <code>LocalSettings.php</code>, et lubada kõik praegu paigaldatud kujundused:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Kui oled lehekülge <code>LocalSettings.php</code> just muutnud:\n: Kontrolli üle, ega kujunduste nimedes pole trükivigu.",
+ "default-skin-not-found-no-skins": "Oih! Sinu viki vaikekujundus, milleks muutuja <code dir=\"ltr\">$wgDefaultSkin</code> järgi on <code>$1</code>, pole saadaval.\n\nÜhtegi kujundust pole paigaldatud.\n\n; Kui oled MediaWiki just paigaldanud või täiendasid seda:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. MediaWiki 1.24 ja uuemad versioonid ei sisalda peahoidlas ühtegi kujundust. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code dir=\"ltr\">skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas kujundusi lubada ja kuidas valida vaikekujundus.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (lubatud)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''keelatud''')"
}
"protect-othertime": "זמן אחר:",
"protect-othertime-op": "זמן אחר",
"protect-existing-expiry": "זמן פקיעה נוכחי: $3, $2",
+ "protect-existing-expiry-infinity": "זמן תפוגה נוכחי: אינסופי",
"protect-otherreason": "סיבה אחרת/נוספת:",
"protect-otherreason-op": "סיבה אחרת",
"protect-dropdown": "* סיבות הגנה נפוצות\n** השחתה רבה\n** ספאם רב\n** מלחמת עריכה בלתי מועילה\n** דף בשימוש רב",
"hidetoc": "sakrij",
"collapsible-collapse": "sklopi stablo",
"collapsible-expand": "raširi stablo",
+ "confirmable-confirm": "Jeste li sigurni?",
+ "confirmable-yes": "Da",
+ "confirmable-no": "Ne",
"thisisdeleted": "Vidi ili vrati $1?",
"viewdeleted": "Vidi $1?",
"restorelink": "{{PLURAL:$1|$1 pobrisanu izmjenu|$1 pobrisane izmjene|$1 pobrisanih izmjena}}",
"protect-othertime": "Durata non in elenco:",
"protect-othertime-op": "durata non in elenco",
"protect-existing-expiry": "Scadenza attuale: $2, $3",
+ "protect-existing-expiry-infinity": "Scadenza attuale: infinito",
"protect-otherreason": "Altri motivi/dettagli:",
"protect-otherreason-op": "Altra motivazione",
"protect-dropdown": "*Motivi comuni di protezione\n** Reiterati vandalismi\n** Reiterati inserimenti di spam\n** Edit war\n** Pagina molto usata",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|トーク]])",
"unknown_extension_tag": "不明な拡張機能タグ「$1」です",
"duplicate-defaultsort": "<strong>警告:</strong> 既定のソートキー「$2」が、その前に書かれている既定のソートキー「$1」を上書きしています。",
- "duplicate-displaytitle": "<strong>警告:</strong> 既定のDISPLAYTITLE「$2」が、その前に書かれている既定のDISPLAYTITLE「$1」を上書きしています。",
+ "duplicate-displaytitle": "<strong>警告:</strong> DISPLAYTITLE「$2」が、その前に書かれているDISPLAYTITLE「$1」を上書きしています。",
"version": "バージョン情報",
"version-extensions": "インストール済み拡張機能",
"version-skins": "インストール済み外装",
"protectedarticle": "حفاظت بيه [[$1]]",
"modifiedarticleprotection": "ریتراز حفاظت د \"[[$1]]\" آلشت بیه",
"protect-title": "ریتراز حفاظت د \"$1\" آلشت بیه",
+ "protect-title-notallowed": "دیئن ریتراز پر و پیم \"$1\"",
"prot_1movedto2": "[[$1]] د [[$2]] جا وه جا بی",
+ "protect-badnamespace-title": "نوم جا بی پر و پیم",
"protect-norestrictiontypes-title": "بلگه بی حامین گر",
"protect-legend": "پشت راس کردن حامین گری",
"protectcomment": "دلیل:",
"protect_expiry_invalid": "گات تموم بیین نامعتوره.",
"protect_expiry_old": "گات تموم بیین مال دماتره.",
"protect-default": "همه کاروریا اجازه دارن",
+ "protect-level-sysop": "فقط دیوونداریا",
"protect-summary-desc": "[$1=$2] ($3)",
"protect-summary-cascade": "د حال و بال تافنمایی",
"protect-expiring": "گات تموم بیین $1 (یو تی سی)",
"badipaddress": "تیرنشون نامعتور آی پی",
"blockipsuccesssub": "قلف کردن د خوئی انجوم بی",
"ipb-edit-dropdown": "ویرایشت دلیلیا نهاگرتن",
+ "ipb-unblock-addr": "وا کردن قلف $1",
"unblockip": "کارور منع نبیه",
"ipusubmit": "ای قلف نه ؤردار",
"blocklist": "كاروريا منع بيه",
"ipblocklist": "كاروريا منع بيه",
"ipblocklist-legend": "یه گل کارور منع بیه بجوریت",
"blocklist-timestamp": "چسب ون وخت",
+ "blocklist-expiry": "تموم بين",
"blocklist-reason": "دلیل",
"ipblocklist-submit": "پی جوری",
"ipblocklist-localblock": "نهاگری ولات نشینی",
"import": "وامین اوردن بلگه یا",
"import-interwiki-sourcewiki": "سرچشمه ویکی:",
"import-interwiki-sourcepage": "بلگه سرچشمه:",
+ "import-interwiki-templates": "همه چوئه یا",
"import-interwiki-submit": "وامین اوردن",
"import-interwiki-namespace": "نومجا مقصد:",
"import-upload-filename": "نوم جانیا:",
"mywatchlist": "Uzraugāmie raksti",
"watchlistfor2": "Priekš $1 ($2)",
"nowatchlist": "Tavā uzraugāmo rakstu sarakstā nav neviena raksta.",
- "watchlistanontext": "Lūdzu $1, lai apskatītu vai labotu savu uzraugāmo rakstu saraksta saturu.",
+ "watchlistanontext": "Lūdzu pieslēdzies, lai apskatītu vai labotu savu uzraugāmo rakstu saraksta saturu.",
"watchnologin": "Neesi iegājis",
"addwatch": "Pievienot uzraugāmo lapu sarakstam",
"addedwatchtext": "Lapa \"[[:$1]]\" ir pievienota [[Special:Watchlist|tevis uzraudzītajām lapām]], kur tiks parādītas izmaiņas, kas izdarītas šajā lapā vai šīs lapas diskusiju lapā, kā arī šī lapa tiks iezīmēta '''pustrekna''' [[Special:RecentChanges|pēdējo izmaiņu lapā]], lai to būtu vieglāk pamanīt.\n\nJa vēlāk pārdomāsi un nevēlēsies vairs uzraudzīt šo lapu, klikšķini uz saites '''neuzraudzīt''' rīku joslā.",
"allpagesbadtitle": "Дадениот наслов е неважечки или има меѓујазичен или меѓувики-претставка. Може да содржи повеќе знаци кои не смеат да се користат во наслови.",
"allpages-bad-ns": "Википедија не содржи именски простор „$1“.",
"allpages-hide-redirects": "Скриј пренасочувања",
- "cachedspecial-viewing-cached-ttl": "Ð\93ледаÑ\82е кеÑ\88ирана верзија на оваа страница, која може да е стара $1.",
- "cachedspecial-viewing-cached-ts": "Ð\93ледаÑ\82е кеÑ\88ирана верзија на оваа страница, која може да се разликува од тековната.",
+ "cachedspecial-viewing-cached-ttl": "Ð\93ледаÑ\82е меÑ\93Ñ\83Ñ\81кладирана верзија на оваа страница, која може да е стара $1.",
+ "cachedspecial-viewing-cached-ts": "Ð\93ледаÑ\82е меÑ\93Ñ\83Ñ\81кладирана верзија на оваа страница, која може да се разликува од тековната.",
"cachedspecial-refresh-now": "Погл. најновата.",
"categories": "Категории",
"categoriespagetext": "{{PLURAL:$1|Следната категорија содржи|Следните категории содржат}} страници или мултимедијални податотеки.\n[[Special:UnusedCategories|Неискористените категории]] не се прикажани овде.\nПогледајте ги и [[Special:WantedCategories|потребните категории]].",
"protect-othertime": "Друго време:",
"protect-othertime-op": "друго време",
"protect-existing-expiry": "Постоечки рок на истекување: $3, $2",
+ "protect-existing-expiry-infinity": "Постоечки рок: бесконечен",
"protect-otherreason": "Друга/дополнителна причина:",
"protect-otherreason-op": "Друга причина",
"protect-dropdown": "*Вообичаени причини за заштита\n** Зачестен вандализам\n** Зачестен спам\n** Непродуктивна уредувачка војна\n** Страница со зачестена посета\n** Сеприсутност на шаблонот/превметнувањето\n** Административна постапка",
"dberr-info-hidden": "(Не може да се добие опслужувачот на базата на податоци)",
"dberr-usegoogle": "Во меѓувреме можете да се обидете да пребарувате со Google.",
"dberr-outofdate": "Да напоменеме дека нивните индекси на нашата содржина можат да бидат застарени.",
- "dberr-cachederror": "Следнава Ñ\81одÑ\80жина е кеÑ\88иÑ\80ана копиÑ\98а на баÑ\80анаÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а, коÑ\98а може да е заÑ\81Ñ\82аÑ\80ена.",
+ "dberr-cachederror": "Следнава Ñ\81одÑ\80жина е меÑ\93Ñ\83Ñ\81кладиÑ\80ан пÑ\80имеÑ\80ок на баÑ\80анаÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а, коÑ\98 може да е заÑ\81Ñ\82аÑ\80ен.",
"htmlform-invalid-input": "Има проблеми со дел од вашиот внос",
"htmlform-select-badoption": "Укажаната вредност е неважечка како можност.",
"htmlform-int-invalid": "Вредноста која ја наведовте не е цел број.",
"otherlanguages": "ഇതരഭാഷകളിൽ",
"redirectedfrom": "($1 എന്ന താളിൽ നിന്നും തിരിച്ചുവിട്ടതു പ്രകാരം)",
"redirectpagesub": "തിരിച്ചുവിടൽ താൾ",
+ "redirectto": "തിരിച്ചുവിടുന്നു:",
"lastmodifiedat": "ഈ താൾ അവസാനം തിരുത്തപ്പെട്ടത്: $2, $1.",
"viewcount": "ഈ താൾ {{PLURAL:$1|ഒരു തവണ|$1 തവണ}} സന്ദർശിക്കപ്പെട്ടിട്ടുണ്ട്.",
"protectedpage": "സംരക്ഷിത താൾ",
"createaccount-text": "{{SITENAME}} സംരംഭത്തിൽ ($4) താങ്കളുടെ ഇമെയിൽ വിലാസത്തിൽ ആരോ ഒരു അംഗത്വം \"$2\" എന്ന ഉപയോക്തൃനാമത്തിൽ ഉണ്ടാക്കിയിരിക്കുന്നു (രഹസ്യവാക്ക്: \"$3\"). താങ്കൾ ഇപ്പോൾ ലോഗിൻ ചെയ്തു രഹസ്യവാക്ക് മാറ്റേണ്ടതാകുന്നു.\n\nഅംഗത്വം അബദ്ധവശാൽ ഉണ്ടാക്കിയതാണെങ്കിൽ താങ്കൾക്ക് ഈ സന്ദേശം നിരാകരിക്കാവുന്നതാണ്.",
"login-throttled": "താങ്കൾ നിരവധി പ്രാവശ്യം ലോഗിൻ ചെയ്യാൻ ശ്രമിച്ചിരിക്കുന്നു.\nപുതിയതായി ശ്രമിക്കുന്നതിനു മുമ്പ് $1 ദയവായി കാത്തിരിക്കുക.",
"login-abort-generic": "താങ്കളുടെ പ്രവേശിക്കൽ പരാജയപ്പെട്ടു - റദ്ദാക്കപ്പെട്ടിരിക്കുന്നു",
+ "login-migrated-generic": "താങ്കളുടെ അംഗത്വം പ്രവാസത്തിലാണ്, ഉപയോക്തൃനാമം ഈ വിക്കിയിൽ നിലവിലില്ല.",
"loginlanguagelabel": "ഭാഷ: $1",
"suspicious-userlogout": "ലോഗൗട്ട് ചെയ്യാനുള്ള താങ്കളുടെ അഭ്യർത്ഥന നിരസിച്ചിരിക്കുന്നു, കാരണം അത് കേടായ ബ്രൗസറിൽ നിന്നോ കാഷിങ് പ്രോക്സിയിൽ നിന്നോ ഉണ്ടായതുപോലെ അനുഭവപ്പെടുന്നു.",
"createacct-another-realname-tip": "താങ്കളുടെ യഥാർത്ഥ പേര് നൽകണമെന്നു നിർബന്ധമില്ല.\n\nഎങ്കിലും അങ്ങനെ ചെയ്താൽ, ഉപയോക്താക്കൾക്ക് അവരരവരുടെ പേരിൽ തന്നെ തങ്ങളുടെ സൃഷ്ടിക്ക് കടപ്പാട് ലഭിക്കുന്നതാണ്.",
"searchall": "എല്ലാം",
"showingresults": "'''$2''' മുതലുള്ള {{PLURAL:$1|'''ഒരു''' ഫലം|'''$1''' ഫലങ്ങൾ}} താഴെ പ്രദർശിപ്പിക്കുന്നു.",
"showingresultsinrange": "#<strong>$2</strong> മുതൽ #<strong>$3</strong> വരെയുള്ള പരിധിയിലെ {{PLURAL:$1|<strong>ഒരു</strong> ഫലം|<strong>$1</strong> ഫലങ്ങൾ}} താഴെ പ്രദർശിപിക്കുന്നു.",
- "showingresultsheader": "'''$4''' എന്ന പദത്തിനു ആകെ ലഭിച്ച {{PLURAL:$5| '''$3''' ഫലത്തിൽ '''$1''' എണ്ണം|'''$3''' ഫലത്തിൽ '''$1 മുതൽ $2''' വരെയുള്ളവ}}",
+ "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> ഫലത്തിൽ<strong>$1</strong>|<strong>$3</strong> ഫലത്തിൽ <strong>$1 മുതൽ $2</strong> വരെയുള്ളവ}}",
"search-nonefound": "താങ്കൾ തിരഞ്ഞ പദത്തിനു യോജിച്ച ഫലങ്ങളൊന്നും ലഭിച്ചില്ല.",
"powersearch-legend": "വിപുലീകൃത തിരച്ചിൽ",
"powersearch-ns": "തിരയേണ്ട നാമമേഖലകൾ",
"unblockiptext": "മുൻപ് തടയപ്പെട്ട ഐ.പി.യുടേയും ഉപയോക്താവിന്റേയും തിരുത്തൽ അവകാശം പുനഃസ്ഥാപിക്കാൻ താഴെയുള്ള ഫോം ഉപയോഗിക്കുക.",
"ipusubmit": "ഈ വിലക്ക് ഒഴിവാക്കുക",
"unblocked": "[[User:$1|$1]] എന്ന ഉപയോക്താവിനുണ്ടായിരുന്ന തടയൽ നീക്കിയിരിക്കുന്നു",
- "unblocked-range": "$1 എന്ന പരിധിയുടെ തടയൽ നീക്കപ്പെട്ടിരിക്കുന്നു",
- "unblocked-id": "$1 എന്ന തടയൽ നീക്കം ചെയ്തിരിക്കുന്നു",
+ "unblocked-range": "$1 എന്ന പരിധിയുടെ തടയൽ നീക്കിയിരിക്കുന്നു.",
+ "unblocked-id": "$1 എന്ന തടയൽ നീക്കിയിരിക്കുന്നു.",
+ "unblocked-ip": "[[Special:Contributions/$1|$1]] എന്ന വിലാസത്തിനുണ്ടായിരുന്ന തടയൽ നീക്കിയിരിക്കുന്നു.",
"blocklist": "തടയപ്പെട്ട ഉപയോക്താക്കൾ",
"ipblocklist": "തടയപ്പെട്ട ഉപയോക്താക്കൾ",
"ipblocklist-legend": "തടഞ്ഞ ഒരു ഉപയോക്താവിനെ തിരയുക",
"log-name-pagelang": "ഭാഷ മാറ്റലിന്റെ രേഖ",
"log-description-pagelang": "താളുകളുടെ ഭാഷകൾ മാറ്റിയതിന്റെ രേഖകൾ ഇവിടെക്കാണാം.",
"logentry-pagelang-pagelang": "$3 എന്ന താളിന്റെ ഭാഷയായിരുന്ന $4, $1 $5 ആയി {{GENDER:$2|മാറ്റി}}.",
- "default-skin-not-found": "അയ്യോ! താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ (<code>$wgDefaultSkin</code>), <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കളുടെ ഇൻസ്റ്റലേഷനിൽ താഴെക്കൊടുക്കുന്ന ദൃശ്യരൂപങ്ങൾ ഉണ്ടാകേണ്ടതാണ്. അവ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.\n\n$2\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code>skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല.\n\n; മീഡിയവിക്കി താങ്കൾ അപ്ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: മീഡിയവിക്കി 1.24 ഒപ്പം അതിനു ശേഷമുള്ളവയും ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സ്വതേ സജ്ജമാക്കുന്നില്ല ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery ദൃശ്യരൂപം ഓട്ടോഡിസ്കവറി സഹായം] കാണുക). ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സജ്ജമാക്കുന്നതിനായി ഇനിക്കൊടുക്കുന്ന വരികൾ <code>LocalSettings.php</code> എന്നതിലോട്ട് പകർത്തുക:\n\n<pre>$3</pre>\n\n; <code>LocalSettings.php</code> താളിൽ മാറ്റം വരുത്തിയതേയുള്ളുവെങ്കിൽ:\n: ദൃശ്യരൂപങ്ങളുടെ പേരിൽ അക്ഷരപിശകുകളുണ്ടോയെന്ന് ആവർത്തിച്ച് പരിശോധിക്കുക.",
- "default-skin-not-found-no-skins": "അയ്യോ! താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ (<code>$wgDefaultSkin</code>), <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കൾ ദൃശ്യരൂപങ്ങളൊന്നും ഇൻസ്റ്റോൾ ചെയ്തിട്ടില്ല.\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ അല്ലെങ്കിൽ അപ്ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code>skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല. ദൃശ്യരൂപങ്ങൾ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.",
+ "default-skin-not-found": "അയ്യോ! <code dir=\"ltr\"> $wgDefaultSkin</code> നിർവചിക്കപ്പെട്ടതുപ്രകാരമുള്ള താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കളുടെ ഇൻസ്റ്റലേഷനിൽ താഴെക്കൊടുക്കുന്ന ദൃശ്യരൂപങ്ങൾ ഉണ്ടാകേണ്ടതാണ്. അവ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.\n\n$2\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code dir=\"ltr\">skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല.\n\n; മീഡിയവിക്കി താങ്കൾ അപ്ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: മീഡിയവിക്കി 1.24 ഒപ്പം അതിനു ശേഷമുള്ളവയും ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സ്വതേ സജ്ജമാക്കുന്നില്ല ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery ദൃശ്യരൂപം ഓട്ടോഡിസ്കവറി സഹായം] കാണുക). ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സജ്ജമാക്കുന്നതിനായി ഇനിക്കൊടുക്കുന്ന വരികൾ <code>LocalSettings.php</code> എന്നതിലോട്ട് പകർത്തുക:\n\n<pre dir=\"ltr\">$3</pre>\n\n; <code>LocalSettings.php</code> താളിൽ മാറ്റം വരുത്തിയതേയുള്ളുവെങ്കിൽ:\n: ദൃശ്യരൂപങ്ങളുടെ പേരിൽ അക്ഷരപിശകുകളുണ്ടോയെന്ന് ആവർത്തിച്ച് പരിശോധിക്കുക.",
+ "default-skin-not-found-no-skins": "അയ്യോ! <code dir=\"ltr\"> $wgDefaultSkin</code> നിർവചിക്കപ്പെട്ടതുപ്രകാരമുള്ള താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കൾ ദൃശ്യരൂപങ്ങളൊന്നും ഇൻസ്റ്റോൾ ചെയ്തിട്ടില്ല.\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ അല്ലെങ്കിൽ അപ്ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code dir=\"ltr\">skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല. ദൃശ്യരൂപങ്ങൾ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (സജ്ജം)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''സജ്ജമല്ല''')"
}
"protect-othertime": "Inny okres",
"protect-othertime-op": "inny okres",
"protect-existing-expiry": "Obecny czas wygaśnięcia: $2 o $3",
+ "protect-existing-expiry-infinity": "Obecny czas wygaśnięcia: nieskończony",
"protect-otherreason": "Inny lub dodatkowy powód",
"protect-otherreason-op": "Inny powód",
"protect-dropdown": "*Najczęstsze powody zabezpieczenia\n** Częste wandalizmy\n** Częste spamowanie\n** Wojna edycyjna\n** Wygłupy",
"movepagetalktext": "La pàgina ëd discussion tacà a costa pàgina d'artìcol, se a-i é, a sarà tramudà n'automatich ansema a l'artìcol, '''gavà costi cas-sì''':\n*quand as tramuda la pàgina tra diferent spassi nominaj,\n*quand na pàgina ëd discussion nen veujda a-i é già për ël nòm neuv, ò pura\n*a l'ha desselessionà ël quadrèt ëd conferma ambelessì-sota.\n\nAnt costi cas-sì, se a chërd dë felo, a-j farà da manca dë tramudesse la pàgina ëd discussion daspërchiel, a man.",
"movearticle": "Cangeje nòm a l'artìcol:",
"moveuserpage-warning": "'''Atension:''' A sta për tramudé na pàgina d'utent. Për piasì ch'a nòta che a sarà tramudà mach la pàgina e che l'utent a sarà ''pa'' arbatjà.",
+ "movecategorypage-warning": "<strong>Atension:</strong> A l'é a brus ëd tramudé na pàgina ëd categorìa. Për piasì, ch'a ten-a da ment che mach la pàgina a sarà tramudà e che tute le pàgine ant la veja categorìa a saran <em>nen</em> tramudà an cola neuva.",
"movenologintext": "A venta esse n'Utent registrà e esse [[Special:UserLogin|rintrà ant ël sistema]]\npër podèj tramudé na pàgina.",
"movenotallowed": "A l'ha pa ij përmess dont a fa da manca për tramudé le pàgine.",
"movenotallowedfile": "A l'ha pa ij përmess për tramudé j'archivi.",
"cant-move-user-page": "A l'ha pa ij përmess për tramudé le pàgine d'utent (gavà le sot-pàgine).",
"cant-move-to-user-page": "A l'ha pa ël përmess për tramudé na pàgina a na pàgina utent (gavà a na sot-pàgina utent).",
+ "cant-move-category-page": "A l'ha nen ël përmess ëd tramudé le pàgine ëd categorìa.",
+ "cant-move-to-category-page": "A l'ha nen ël përmess ëd tramudé na pàgina a na pàgina ëd categorìa.",
"newtitle": "Neuv tìtol ëd",
"move-watch": "Ten-e sot-euj la pàgina sorgiss e la pàgina selessionà",
"movepagebtn": "Tramudé la pàgina",
"import": "Amportassion ëd pàgine",
"importinterwiki": "Amportassion da wiki diferente",
"import-interwiki-text": "Che a selession-a na wiki e ël tìtol dla pàgina da amporté.\nDate dle revision e stranòm dj'editor a resteran piàjit sù 'cò lor.\nTute j'amportassion antra wiki diferente a resto marcà ant ël [[Special:Log/import|Registr dj'amportassion]].",
+ "import-interwiki-sourcewiki": "Wiki sorgiss:",
+ "import-interwiki-sourcepage": "Pàgina sorgiss:",
"import-interwiki-history": "Copié tute le revision ëd la stòria ëd costa pàgina",
"import-interwiki-templates": "Anserì tùit jë stamp",
"import-interwiki-submit": "Amporté",
"import-upload": "Cariament ëd dat XML",
"import-token-mismatch": "Pèrdita dij dat ëd session.\nPër piasì, ch'a preuva torna.",
"import-invalid-interwiki": "As peul pa amportesse da la wiki spessificà.",
- "import-error-edit": "La pàgina «$1» a l'é pa stàita amportà përchè chiel a peul pa modifichela.",
+ "import-error-edit": "La pàgina «$1» a l'era pa stàita amportà përchè chiel a peul pa modifichela.",
"import-error-create": "La pàgina «$1» a l'é pa stàita amportà përchè chiel a peul pa creela.",
"import-error-interwiki": "La pàgina «$1» a l'é pa amportà përchè sò nòm a l'é arzervà për na liura esterna (antërwiki).",
"import-error-special": "La pàgina «$1» a l'é pa amportà përchè a ponta a në spassi nominal ch'a përmët pa dle pàgine.",
"protect-cantedit": "Used as error message when changing the protection levels of the page.",
"protect-othertime": "Used on the page protection form as label for the following input field (text)\n{{Identical|Other time}}",
"protect-othertime-op": "Used on the page protection form in the drop down menu\n{{Identical|Other time}}",
- "protect-existing-expiry": "Shows the existing expiry time in the drop down menu of the protection form ([{{canonicalurl:User:Raymond/test|action=unprotect}} example])\n\nParameters:\n* $1 - (Unused) date and time of the existing expiry time (kept for backward compatibility purposes)\n* $2 - date of the existing expiry time\n* $3 - time of the existing expiry time",
+ "protect-existing-expiry": "Shows the existing expiry time in the drop down menu of the protection form ([{{canonicalurl:User:Raymond/test|action=unprotect}} example])\n\nParameters:\n* $1 - (Unused) date and time of the existing expiry time (kept for backward compatibility purposes)\n* $2 - date of the existing expiry time\n* $3 - time of the existing expiry time\n\nSee also:\n* {{msg-mw|protect-existing-expiry-infinity}}",
+ "protect-existing-expiry-infinity": "Shows the existing expiry time in the drop down menu of the protection form, in the special case that it is infinity\n\nSee also:\n* {{msg-mw|protect-existing-expiry}}",
"protect-otherreason": "Shown on the page protection form as label for the following input field (text)\n{{Identical|Other/additional reason}}",
"protect-otherreason-op": "Shown on the page protection form in the drop down menu\n{{Identical|Other reason}}",
"protect-dropdown": "Shown on the page protection form as drop down menu for protection reasons.\n\n* <code><nowiki>* Groupname</nowiki></code> - defines a new group\n* <code><nowiki>** Reason</nowiki></code> - defines a reason in this group",
"protect-othertime": "Другое время:",
"protect-othertime-op": "другое время",
"protect-existing-expiry": "Текущее время окончания: $2, $3",
+ "protect-existing-expiry-infinity": "Текущее время окончания: бесконечно",
"protect-otherreason": "Другая причина/дополнение:",
"protect-otherreason-op": "Другая причина",
"protect-dropdown": "* Типовые причины защиты\n** частый вандализм\n** чрезмерный спам\n** непродуктивная война правок\n** популярная страница",
"revdelete-hide-text": "Testu de sa versione",
"revdelete-hide-image": "Cua su cuntènnidu de su documentu",
"revdelete-hide-comment": "Modìfica s'ogetu",
+ "revdelete-radio-same": "(non cambiare)",
"revdelete-radio-set": "Cua",
"revdelete-radio-unset": "Ammustra",
"revdelete-log": "Motivu:",
"prefs-watchlist-edits-max": "Cantidade màssima: 1000",
"prefs-misc": "Àteras preferèntzias",
"prefs-resetpass": "Càmbia password",
+ "prefs-changeemail": "Càmbia indiritzu email",
"prefs-email": "Sèberos pro sa email",
"prefs-rendering": "Aparèntzia",
"saveprefs": "Sarva preferèntzias",
"sourceurl": "Diretzione originària:",
"destfilename": "Nùmene de su file de destinatzione:",
"upload-description": "Descritzione de su file",
+ "watchthisupload": "Annota custu documentu",
"upload-success-subj": "Carrigamentu acabau",
"upload-failure-subj": "Problema de carrimentu",
"upload-file-error": "Faddina a intru",
"listfiles_size": "Mannesa in byte",
"listfiles_description": "Descritzione",
"listfiles_count": "Versiones",
+ "listfiles-latestversion": "Versione atuale",
"listfiles-latestversion-yes": "Eja",
"listfiles-latestversion-no": "No",
"file-anchor-link": "File",
"filedelete-success": "Su file '''$1''' est istadu fuliau.",
"filedelete-otherreason": "Motivu diversu o agiuntivu:",
"filedelete-reason-otherlist": "Àteru motivu",
+ "filedelete-edit-reasonlist": "Càmbia is motivos de sa burradura",
"mimesearch": "Chirca MIME",
"mimetype": "Genia MIME:",
"download": "scàrriga",
+ "unwatchedpages": "Pàginas no annotadas",
"listredirects": "Lista de totu is redirects",
+ "listduplicatedfiles": "Lista de documentos dopios",
+ "unusedtemplates": "Templates no impreados",
"unusedtemplateswlh": "àteros ligòngios",
"randompage": "Pàgina a sa tzurpa",
"randomincategory-category": "Categoria:",
"statistics": "Statìsticas",
"statistics-header-pages": "Statìsticas subra is pàginas",
+ "statistics-header-edits": "Càmbia is statìsticas",
+ "statistics-header-views": "Càstia is statìsticas",
"statistics-header-users": "Statìsticas subra is usuàrios",
+ "statistics-header-hooks": "Àteras statìsticas",
+ "statistics-articles": "Pàginas de càbidos",
"statistics-pages": "Pàginas",
+ "statistics-files": "Documentos carrigados",
"pageswithprop-submit": "Bae",
"doubleredirects": "Redirects dòpios",
"doubleredirectstext": "Custa pàgina cuntenet una lista de pàginas ki re-indiritzant a àteras pàginas de re-indiritzamentu.\nOgni lìnia cuntenet ligàmines a su primu e a su de duos re-indiritzamentu, aici comente sa prima lìnia de sa de duos re-indiritzamentos, chi de sòlitu adòbiat s'artìculu \"beru\", a sa cale fintzas su primu re-indiritzamentu dia depet puntare.\nIs re-indiritzamentos <del>cantzellados</del> sunt stados curretos.",
"withoutinterwiki-submit": "Ammustra",
"nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
"ncategories": "$1 {{PLURAL:$1|categoria|categorias}}",
+ "ninterwikis": "$1 {{PLURAL:$1|interwiki|interwikis}}",
"nlinks": "$1 {{PLURAL:$1|ligàmene|ligàmenes}}",
"nmembers": "$1 {{PLURAL:$1|cumponente|cumponentes}}",
"nrevisions": "$1 {{PLURAL:$1|revisione|revisiones}}",
"protect-othertime": "Drugačen čas:",
"protect-othertime-op": "drugačen čas",
"protect-existing-expiry": "Obstoječ čas izteka: $3, $2",
+ "protect-existing-expiry-infinity": "Obstoječ čas izteka: neskončno",
"protect-otherreason": "Drug/dodaten razlog:",
"protect-otherreason-op": "Drug razlog",
"protect-dropdown": "*Pogosti razlogi za zaščito\n** Prekomeren vandalizem\n** Vztrajno dodajanje reklamnih povezav\n** Neproduktivne urejevalske vojne\n** Zelo obiskana stran",
"undeleteinvert": "Обрни избор",
"undeletecomment": "Разлог:",
"undeletedrevisions": "{{PLURAL:$1|Измена је враћена|$1 измене су враћене|$1 измена је враћено}}",
- "undeletedrevisions-files": "$1 {{PLURAL:$1|измена|измене|измена}} и $2 {{PLURAL:$2|датотека|датотеке|датотека}} је враћено",
+ "undeletedrevisions-files": "$1 {{PLURAL:$1|1 измена|измене|измена}} и $2 {{PLURAL:$2|1 датотека је враћена|датотеке су враћене|датотека је враћено}}",
"undeletedfiles": "{{PLURAL:$1|Датотека је враћена|$1 датотеке су враћене|$1 датотека је враћено}}",
"cannotundelete": "Враћање није успело:\n$1",
"undeletedpage": "'''Страница $1 је враћена'''\n\nПогледајте [[Special:Log/delete|историју брисања]] за записе о скорашњим брисањима и враћањима.",
"watchlistedit-clear-titles": "Наслови:",
"watchlistedit-clear-submit": "Испразни списак надгледања (Ово је трајно!)",
"watchlistedit-clear-done": "Ваш списак надгледања је испражњен.",
- "watchlistedit-clear-removed": "{{PLURAL:$1|1 наслов је уклоњен|$1 наслова је уклоњено}}:",
+ "watchlistedit-clear-removed": "{{PLURAL:$1|1 наÑ\81лов Ñ\98е Ñ\83клоÑ\9aен|$1 наÑ\81лова Ñ\81Ñ\83 Ñ\83клоÑ\9aена|$1 наÑ\81лова Ñ\98е Ñ\83клоÑ\9aено}}:",
"watchlistedit-too-many": "Има превише страница за приказ овде.",
"watchlisttools-clear": "испразни списак надгледања",
"watchlisttools-view": "прикажи сродне измене",
"undeleteinvert": "Obrni izbor",
"undeletecomment": "Razlog:",
"undeletedrevisions": "{{PLURAL:$1|Izmena je vraćena|$1 izmene su vraćene|$1 izmena je vraćeno}}",
- "undeletedrevisions-files": "$1 {{PLURAL:$1|izmena|izmene|izmena}} i $2 {{PLURAL:$2|datoteka|datoteke|datoteka}} je vraćeno",
+ "undeletedrevisions-files": "$1 {{PLURAL:$1|1 izmena|izmene|izmena}} i $2 {{PLURAL:$2|1 datoteka je vraćena|datoteke su vraćene|datoteka je vraćeno}}",
"undeletedfiles": "{{PLURAL:$1|Datoteka je vraćena|$1 datoteke su vraćene|$1 datoteka je vraćeno}}",
"cannotundelete": "Vraćanje nije uspelo:\n$1",
"undeletedpage": "'''Stranica $1 je vraćena'''\n\nPogledajte [[Special:Log/delete|istoriju brisanja]] za zapise o skorašnjim brisanjima i vraćanjima.",
"watchlistedit-clear-titles": "Naslovi:",
"watchlistedit-clear-submit": "Isprazni spisak nadgledanja (Ovo je trajno!)",
"watchlistedit-clear-done": "Vaš spisak nadgledanja je ispražnjen.",
- "watchlistedit-clear-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova je uklonjeno}}:",
+ "watchlistedit-clear-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova su uklonjena|$1 naslova je uklonjeno}}:",
"watchlisttools-clear": "isprazni spisak nadgledanja",
"watchlisttools-view": "prikaži srodne izmene",
"watchlisttools-edit": "prikaži i uredi spisak nadgledanja",
"tog-extendwatchlist": "Legaan béréndélan ngarah sakabéh parobahanana kaawaskeun",
"tog-usenewrc": "Parobahan grup dumasar kaca dina béréndélan anyar robah jeung awaskeuneun (maké JavaScript)",
"tog-numberheadings": "Nomeran lulugu sacara otomatis",
- "tog-showtoolbar": "Témbongkeun ''toolbar'' édit (JavaScript)",
- "tog-editondblclick": "Édit kaca ku klik ganda (JavaScript)",
- "tog-editsectiononrightclick": "Fungsikeun ngédit sub-bagean kalawan klik-katuhu dina judul bagean (JavaScript)",
+ "tog-showtoolbar": "Témbongkeun tulbar édit",
+ "tog-editondblclick": "Édit kaca ku klik ganda",
+ "tog-editsectiononrightclick": "Fungsikeun ngédit sub-bagean kalawan klik-katuhu dina judul bagéan",
"tog-watchcreations": "Tambahkeun kaca-kaca jieunan kuring jeung berkas muatan kuring kana awaskeuneun",
"tog-watchdefault": "Tambahkeun kaca jeung berkas anu diédit ku kuring kana awaskeuneun",
"tog-watchmoves": "Tambahkeun kaca jeung berkas anu dipindahkeun ka awaskeuneun",
"tog-shownumberswatching": "Témbongkeun jumlah nu ngawaskeun",
"tog-oldsig": "Paraf nu geus aya:",
"tog-fancysig": "Témbongkeun paraf salaku wikitext (tanpa tumbu otomatis)",
- "tog-uselivepreview": "Paké pramidang saharita (JavaScript) (ujicoba)",
+ "tog-uselivepreview": "Paké pramidang saharita (ujicoba)",
"tog-forceeditsummary": "Mun kotak ringkesan éditan masih kosong, béjaan!",
"tog-watchlisthideown": "Sumputkeun éditan kuring dina daptar awaskeuneun",
"tog-watchlisthidebots": "Sumputkeun éditan bot dina daptar awaskeuneun",
"tog-showhiddencats": "Témbongkeun kategori nyumput",
"tog-norollbackdiff": "Liwat béda sanggeus malikkeun révisi",
"tog-useeditwarning": "Béjaan kuring lamun ninggalkeun kaca édit anu parobahanana can disimpen",
+ "tog-prefershttps": "Salawasna paké sambungan aman nalika asup log",
"underline-always": "Salawasna",
"underline-never": "Ulah",
"underline-default": "Luyu jeung buhunna panyungsi",
"thursday": "Kemis",
"friday": "Jumaah",
"saturday": "Saptu",
- "sun": "Min",
+ "sun": "Ming",
"mon": "Sen",
"tue": "Sal",
"wed": "Reb",
"oct": "Okt",
"nov": "Nop",
"dec": "Dés",
+ "january-date": "$1 Januari",
+ "february-date": "$1 Pébruari",
+ "march-date": "$1 Maret",
+ "april-date": "$1 April",
+ "may-date": "$1 Méi",
+ "june-date": "$1 Juni",
+ "july-date": "$1 Juli",
+ "august-date": "$1 Agustus",
+ "september-date": "$1 Séptémber",
+ "october-date": "$1 Oktober",
+ "november-date": "$1 Nopémber",
+ "december-date": "$1 Désémber",
"pagecategories": "{{PLURAL:$1|Kategori|Kategori}}",
"category_header": "Artikel-artikel na kategori \"$1\"",
"subcategories": "Subkategori",
"newwindow": "(buka na jandéla anyar)",
"cancel": "Bolay",
"moredotdotdot": "Deui...",
- "mypage": "Kaca kuring",
+ "morenotlisted": "Ieu béréndélan tacan lengkep.",
+ "mypage": "Kaca",
"mytalk": "Obrolan",
"anontalk": "Obrolan pikeun IP ieu",
"navigation": "Pituduh",
"actions": "Peta",
"namespaces": "Spasi ngaran",
"variants": "Varian",
+ "navigation-heading": "Ménu navigasi",
"errorpagetitle": "Kasalahan",
"returnto": "Balik deui ka $1.",
"tagline": "Ti {{SITENAME}}",
"permalink": "Tutumbu permanén",
"print": "Citak",
"view": "Tempo",
+ "view-foreign": "Tempo di $1",
"edit": "Édit",
+ "edit-local": "Edit déskripsi lokal",
"create": "Jieun",
+ "create-local": "Tambah déskripsi lokal",
"editthispage": "Édit kaca ieu",
"create-this-page": "Jieun kaca ieu",
"delete": "Hapus",
"deletethispage": "Hapus kaca ieu",
+ "undeletethispage": "Bolaykeun ngahapus ieu kaca",
"undelete_short": "Bolaykeun ngahapus {{PLURAL:$1|hiji éditan|$1 éditan}}",
"viewdeleted_short": "Témbongkeun {{PLURAL:$1|hiji éditan nu dihapus|$1 éditan nu dihapus}}",
"protect": "Konci",
"articlepage": "Témbongkeun kaca eusi",
"talk": "Sawala",
"views": "Témbongan",
- "toolbox": "Kotak parabot",
+ "toolbox": "Parabot",
"userpage": "Témbongkeun kaca pamaké",
"projectpage": "Témbongkeun kaca proyék",
"imagepage": "Tempo kaca gambar",
"otherlanguages": "Dina séjén basa",
"redirectedfrom": "(dipindahkeun ti $1)",
"redirectpagesub": "Kaca alihan",
+ "redirectto": "Alihkeun ka:",
"lastmodifiedat": "Kaca ieu panungtungan dirobah $2, $1.",
"viewcount": "Kaca ieu geus dibuka {{PLURAL:$1|sakali|$1 kali}}.<br />",
"protectedpage": "Kaca nu dikonci",
"ok": "Heug",
"retrievedfrom": "Disalin ti \"$1\"",
"youhavenewmessages": "Anjeun boga $1 ($2).",
+ "youhavenewmessagesfromusers": "{{PLURAL:$4|Anjeun boga}} $1 ti {{PLURAL:$3|pamaké séjén|$3 pamaké}} ($2).",
+ "youhavenewmessagesmanyusers": "Anjeun boga $1 ti pamaké lian ($2).",
+ "newmessageslinkplural": "{{PLURAL:$1|obrolan anyar|obrolan anyar}}",
+ "newmessagesdifflinkplural": "{{PLURAL:$1|parobahan|999=parobahan}} panungtung",
"youhavenewmessagesmulti": "Anjeun boga talatah anyar di $1",
"editsection": "édit",
"editold": "édit",
"hidetoc": "sumputkeun",
"collapsible-collapse": "Tilepkeun",
"collapsible-expand": "Amparkeun",
+ "confirmable-confirm": "{{GENDER:$1|Anjeun}} geus yakin?",
+ "confirmable-yes": "Enya",
+ "confirmable-no": "Henteu",
"thisisdeleted": "Témbongkeun atawa simpen deui $1?",
"viewdeleted": "Témbongkeun $1?",
"restorelink": "$1 {{PLURAL:$1|éditan|éditan}} dihapus",
"nospecialpagetext": "<strong>Anjeun ménta kaca husus nu teu dipikawanoh.</strong>\nKaca husus anu bener bisa ditempo béréndélanana dina [[Special:SpecialPages|{{int:specialpages}}]].",
"error": "Kasalahan",
"databaseerror": "Kasalahan gudang data",
+ "databaseerror-query": "Kueri: $1",
+ "databaseerror-function": "Fungsi: $1",
+ "databaseerror-error": "Eror: $1",
"laggedslavemode": "Awas: kandungan kaca bisa baé teu mutahir.",
"readonly": "pangkalan data dikonci",
"enterlockreason": "Asupkeun alesan pikeun ngonci, kaasup kira-kira iraha konci ieu rék dibuka",
"viewsource-title": "Témbongkeun sumber pikeun $1",
"actionthrottled": "Peta diwates",
"actionthrottledtext": "Salaku tetengger anti-spam, anjeun teu diwenangkeun loba kitu peta dina jangka waktu anu sakitu heureutna. Mangga lajengkeun deui sanggeus sababaraha menit ka payun.",
- "protectedpagetext": "Ieu kaca dikonci ngarah teu bisa dirobah.",
+ "protectedpagetext": "Ieu kaca dijaga tina éditan atawa peta lianna.",
"viewsourcetext": "Anjeun bisa némbongkeun sarta nyalin sumber ieu kaca:",
"viewyourtext": "Anjeun bisa némbongkeun sarta nyalin sumber '''éditan anjeun''' ka ieu kaca:",
"protectedinterface": "Kaca ieu eusina teks antarmuka pikeun dipaké ku pakakas beyé sarta geus dikunci pikeun ngahindar ti kasalahan.",
"namespaceprotected": "Anjeun teu ngabogaan hak pikeun ngédit kaca di ngaranspasi '''$1'''.",
"customcssprotected": "Anjeun teu teu diwenangkeun pikeun ngédit ieu kaca CSS, sabab ngandung setélan pribadi kontributor séjén.",
"customjsprotected": "Anjeun teu teu diwenangkeun pikeun ngédit ieu kaca JavaScript, sabab ngandung setélan pribadi kontributor séjén.",
+ "mycustomcssprotected": "Anjeun teu boga kawenangan pikeun ngédit kaca CSS ieu.",
+ "mycustomjsprotected": "Anjeun teu boga kawenangan pikeun ngédit kaca JavaScript ieu.",
+ "myprivateinfoprotected": "Anjeun teu boga kawenangan pikeun ngédit émbaran pribadi anjeun.",
+ "mypreferencesprotected": "Anjeun teu boga kawenangan pikeun ngédit préferénsi anjeun.",
"ns-specialprotected": "Kaca dina ngaranspasi {{ns:special}} teu bisa di édit.",
"titleprotected": "Ieu judul dikonci ku [[User:$1|$1]] kalawan alesan ''$2''.",
+ "filereadonlyerror": "Berkas \"$1\" teu bisa dirobah kusabab répositori \"$2\" keur dina mode ukur-maca.\n\nKuncén anu ngonci méré alesan: \"$3\".",
+ "exception-nologin": "Henteu asup log",
+ "exception-nologin-text": "Mangga asup log pikeun bisa asup atawa ngarobah ieu kaca.",
"virus-badscanner": "Kasalahan konfigurasi: panyekén virus teu dipikawanoh: ''$1''",
"virus-scanfailed": "nyekén gagal (kode $1)",
"virus-unknownscanner": "antivirus teu dipikawanoh:",
"logouttext": "'''Anjeun ayeuna geus kaluar log.'''\n\nAnjeun bisa tetep migunakeun {{SITENAME}} bari anonim, atawa bisa <span class='plainlinks'>[$1 asup log deui]</span> salaku pamaké nu sarua atawa nu séjén deui.\nMangkahadé, sababaraha kaca bakal tetep némbongkeun saolah-olah anjeun asup log kénéh nepi ka anjeun ngosongkeun ''cache'' panyungsi anjeun.",
+ "welcomeuser": "Bagéa, $1!",
+ "welcomecreation-msg": "Akun anjeun geus dijieun.\nLamun minat, Anjeun bisa ngarobah [[Special:Preferences|préferénsi]] {{SITENAME}}.",
"yourname": "Sandiasma:",
+ "userlogin-yourname": "Sandiasma",
+ "userlogin-yourname-ph": "Asupkeun sandiasma anjeun",
+ "createacct-another-username-ph": "Asupkeun sandiasma",
"yourpassword": "Sandi anjeun",
+ "userlogin-yourpassword": "Kecap sandi",
+ "userlogin-yourpassword-ph": "Asupkeun kecap sandi anjeun",
+ "createacct-yourpassword-ph": "Asupkeun kecap sandi",
"yourpasswordagain": "Ketik deui sandi anjeun",
+ "createacct-yourpasswordagain": "Konfirmasi kecap sandi",
+ "createacct-yourpasswordagain-ph": "Asupkeun deui kecap sandi",
"remembermypassword": "Apalkeun login kuring dina ieu komputer (pikeun paling lila $1 {{PLURAL:$1|poé|poé}})",
+ "userlogin-signwithsecure": "Paké sambungan aman",
"yourdomainname": "Domain anjeun",
+ "password-change-forbidden": "Anjeun teu bisa ngarobah kecap sandi dina ieu wiki.",
"externaldberror": "Aya kasalahan dina pangkalan data oténtikasi luar, atawa anjeun mémang teu diwenangkeun pikeun ngaropéa rekening luar anjeun.",
"login": "Asup log",
"nav-login-createaccount": "Nyieun akun/asup log",
"logout": "Kaluar log",
"userlogout": "Kaluar log",
"notloggedin": "Can asup log",
+ "userlogin-noaccount": "Teu boga akun?",
+ "userlogin-joinproject": "Ngiluan {{SITENAME}}",
"nologin": "Teu boga akun? '''$1'''.",
"nologinlink": "Jieun akun",
"createaccount": "Jieun akun",
"gotaccount": "Geus boga akun? '''$1'''.",
"gotaccountlink": "Asup log",
"userlogin-resetlink": "Poho akun sorangan?",
- "createaccountmail": "ku surélék",
+ "userlogin-resetpassword-link": "Poho kecap sandi?",
+ "userlogin-helplink2": "Pitulung asup log",
+ "createacct-emailrequired": "Alamat surélék:",
+ "createacct-emailoptional": "Alamat surélék (teu wajib)",
+ "createacct-email-ph": "Asupkeun alamat surélék anjeun",
+ "createacct-another-email-ph": "Asupkeun alamat surélék",
+ "createaccountmail": "Paké kecap sandi acak sarta kirim ka alamat surélék",
+ "createacct-realname": "Ngaran asli (teu wajib)",
"createaccountreason": "Alesan:",
+ "createacct-reason": "Alesan",
+ "createacct-reason-ph": "Naha bet nyieun akun séjén",
+ "createacct-captcha": "Pamariksaan kaamanan",
+ "createacct-imgcaptcha-ph": "Asupkeun téks anu kabaca di luhur",
+ "createacct-submit": "Jieun akun anjeun",
+ "createacct-another-submit": "Jieun akun séjén",
+ "createacct-benefit-heading": "{{SITENAME}} téh dijieun ku jalma-jalma siga anjeun.",
+ "createacct-benefit-body1": "{{PLURAL:$1|édit|édit}}",
+ "createacct-benefit-body2": "{{PLURAL:$1|kaca|kaca}}",
+ "createacct-benefit-body3": "{{PLURAL:$1|kontributor|kontributor}} panungtung",
"badretype": "Sandi nu diasupkeun teu cocog.",
"userexists": "Sandiasma nu diasupkeun geus aya nu maké.\nMangga pilih sandiasma nu séjén.",
"loginerror": "Kasalahan asup log",
"passwordtooshort": "Sandina kudu diwangun ku sahanteuna {{PLURAL:$1|1 karakter|$1 karakter}}.",
"password-name-match": "Sandi anjeun kudu béda ti landihan.",
"password-login-forbidden": "Sandiasma jeung sandina teu bisa dipaké.",
- "mailmypassword": "Kirim sandi anyar ngaliwatan surélék",
+ "mailmypassword": "Setél ulang kecap sandi",
"passwordremindertitle": "Pangéling sandi ti {{SITENAME}}",
"passwordremindertext": "Aya (jigana anjeun ti alamat IP $1) nu ménta sangkan dikiriman sandi anyar asup log {{SITENAME}} ($4). Saheulaanan, sandi anyar keur pamaké \"$2\" ayeuna diganti jadi \"$3\". Anjeun kudu asup log sarta ngarobah sandi anjeun ayeuna. Ieu sandi bakal kadaluwarsa dina {{PLURAL:$5|sapoé|$5 poé}}.\n\nMun pamundut ieu datang ti nu séjén, atawa mun anjeun geus inget sandi anu tadina poho, sarta teu hayang ngarobah sandina, anjeun teu kudu ngawaro kana ieu surat sarta bisa tetep maké sandi anu ti heula.",
"noemail": "Teu aya alamat surélék karékam pikeun \"$1\".",
"noemailcreate": "Anjeun kudu nyadiakeun alamat surélék anu bener",
"passwordsent": "Sandi anyar geus dikirim ka alamat surélék nu kadaptar pikeun \"$1\". Mangga asup log deui satutasna katarima.",
"blocked-mailpassword": "Alamat IP anjeun dipeungpeuk, moal bisa ngédit, and so\nis not allowed to use the password recovery function to prevent abuse.",
- "eauthentsent": "Surélék konfirmasi geus dikirim ka alamat bieu. Méméh aya surat séjén asup ka rekeningna, anjeun kudu nuturkeun pituduh na surélékna pikeun ngonfirmasi yén rekening éta téh bener nu anjeun.",
+ "eauthentsent": "Surélék konfirmasi geus dikirim ka alamat bieu.\nMéméh aya surat séjén asup ka akunna, anjeun kudu nuturkeun pituduh dina surélékna pikeun mastikeun yén akun éta téh bener boga anjeun.",
"throttled-mailpassword": "Hiji panginget kecap sandi geus dikirimkeun dina {{PLURAL:$1|jam|$1 jam}} pamungkas.\nPikeun ngahindar disalahgunakeun, ngan hiji kecap sandi anu baris dikirimkeun saban {{PLURAL:$1|jam|$1 jam}}.",
"mailerror": "Kasalahan ngirim surat: $1",
"acct_creation_throttle_hit": "Punten,pamaké alamat IP anjeun geus nyieun {{PLURAL:$1|1 rekening|$1 rekening}} dina sapoé ieu. mangrupa jumlah nu di idinan dina sapoé.\nanjeun teu bisa nyieun deui samentara waktu.",
- "emailauthenticated": "Alamat surélék anjeun geus dioténtikasi dina $3, $2.",
- "emailnotauthenticated": "Alamat surélék anjeun <strong>can dioténtikasi</strong>. Moal aya surélék nu bakal dikirim pikeun fitur-fitur di handap ieu.",
+ "emailauthenticated": "Alamat surélék anjeun geus dikonfirmasi $2 tabuh $3.",
+ "emailnotauthenticated": "Alamat surélék anjeun can dikonfirmasi.\nMoal aya surélék nu bakal dikirim pikeun fitur-fitur di handap ieu.",
"noemailprefs": "Teu aya alamat surélék, fitur di handap moal bisa jalan.",
"emailconfirmlink": "Konfirmasi alamat surélék anjeun",
"invalidemailaddress": "Alamat surélék teu bisa ditarima sabab formatna salah.\nMangga lebetkeun alamat nu formatna bener atawa kosongkeun baé.",
"cannotchangeemail": "Alamat surat-é akun hanteu bisa dirobah di ieu wiki.",
+ "emaildisabled": "Ieu loka teu bisa ngirim surélék.",
"accountcreated": "Rekening geus dijieun.",
"accountcreatedtext": "Rekening pamaké pikeun $1 geus dijieun.",
"createaccount-title": "Nyieun rekening keur {{SITENAME}}",
"login-abort-generic": "Login gagal - Dibolaykeun",
"loginlanguagelabel": "Basa: $1",
"suspicious-userlogout": "Pamundut anjeun pikeun kaluar log ditolak ku sabab sigana dikirim ku pangaprak buntu atawa ''cache'' proxi.",
+ "pt-login": "Asup log",
+ "pt-login-button": "Asup log",
+ "pt-createaccount": "Jieun akun",
+ "pt-userlogout": "Kaluar log",
"php-mail-error-unknown": "Kasalahan nu teu kanyahoan dina fungsi PHP surélék().",
"user-mail-no-addy": "Nyobaan ngirim surélék tanpa alamat.",
"changepassword": "Robah sandi",
"changeemail-oldemail": "Alamat surélék ayeuna:",
"changeemail-newemail": "Alamat surélék anyar:",
"changeemail-none": "(euweuh)",
+ "changeemail-password": "Kecap sandi {{SITENAME}} Anjeun:",
"changeemail-submit": "Ganti surélék",
"changeemail-cancel": "Bolay",
+ "resettokens-tokens": "Token:",
"bold_sample": "Téks kandel",
"bold_tip": "Téks kandel",
"italic_sample": "Tulisan déngdék",
"token_suffix_mismatch": "'''Éditan anjeun ditolak sabab aplikasi klien Anjeun ngarobah karakter tanda baca dina éditan. Éditan kasebut ditolak keur nyegah kasalahan dina artikel téks. Hal ieu kadang-kadang kajadian lamun Anjeun maké proksi anonim basis web nu masalah.'''",
"edit_form_incomplete": "'''Sawatara bagian tina wangun éditan teu nepi ka sérver; pariksa deui naha éditan Anjeun tetep gembleng sarta cobaan deui.'''",
"editing": "Ngédit $1",
+ "creating": "Nyieun $1",
"editingsection": "Ngédit $1 (bagian)",
"editingcomment": "Ngédit $1 (bagian anyar)",
"editconflict": "Konflik éditan: $1",
"edit-gone-missing": "Kaca teu bisa dianyarkeun,\nsigana kusabab geus dihapus.",
"edit-conflict": "Éditan bantrok",
"edit-no-change": "Éditan anjeun teu diwaro, kusabab taya nu robah dina tulisanana.",
+ "postedit-confirmation-saved": "Éditan anjeun tos disimpen.",
"edit-already-exists": "Teu bisa nyieun kaca anyar.\nArtikelna geus aya.",
+ "defaultmessagetext": "Téks ti dituna",
+ "invalid-content-data": "Data eusi henteu valid",
+ "content-not-allowed-here": "Eusi \"$1\" teu diijinan di kaca [[$2]]",
+ "content-model-wikitext": "wikitéks",
+ "content-model-text": "téks polos",
+ "content-model-javascript": "JavaScript",
+ "content-model-css": "CSS",
"expensive-parserfunction-warning": "Inget!: Kaca ieu ngandung réa teuing maké fungsi ''parser''.\n\nAyeuna aya {{PLURAL:$1|$1 panggilan|$1 panggilan}}, sakuduna kurang ti $2 {{PLURAL:$2|panggilan|panggilan}}.",
"expensive-parserfunction-category": "Kaca kalawan réa teuing maké fungsi parser",
"post-expand-template-inclusion-warning": "Inget! : Ukuran citakan anu dipaké badag teuing.\nSawatara citakan baris teu diasupkeun.",
"histlegend": "Pilihan béda: tandaan wadah buleud vérsina pikeun ngabandingkeun sarta pencét énter atawa tombol di handap.<br />\nKaterangan: (kiw) = bédana jeung vérsi kiwari,\n(ahir) = bédana jeung vérsi nu harita, m = éditan minor.",
"history-fieldset-title": "Sungsi jujutan",
"history-show-deleted": "Ukur nu dihapus",
- "histfirst": "Pangheubeulna",
- "histlast": "Pangahirna",
+ "histfirst": "pangheubeulna",
+ "histlast": "panganyarna",
"historysize": "($1 {{PLURAL:$1|bit|bit}})",
"historyempty": "(kosong)",
"history-feed-title": "Sajarah révisi",
"revdelete-confirm": "Mangga geura konfirmasi yen Anjeun gaduh maksad pikeun ngalakukeun hal ieu, paham kana konsekwensina, tur nu dilakukeun ieu teh luyu sareng [[{{MediaWiki:Policy-url}}|kawijakanana]]",
"revdelete-suppress-text": "Nyumputkeun revisi '''ukur''' bisa digunakeun keur kasus-kasus di handap ieu:\n* Informasi nu boga potensi mitenah\n* Informasi pribadi nu teu pantes\n*: ''alamat imah katut nomer telepon, nomer kartu identitas, jeung lian-liana.''",
"revdelete-legend": "Setél réstriksi révisi:",
- "revdelete-hide-text": "Sumputkeun téks révisi",
+ "revdelete-hide-text": "Téks révisi",
"revdelete-hide-image": "Sumputkeun eusi gambar",
"revdelete-hide-name": "Sumputkeun lampah sarta udagan",
"revdelete-hide-comment": "Sumputkeun koméntar ngédit",
"revdelete-hide-user": "Sumputkeun ngaran pamaké/IP éditor",
"revdelete-hide-restricted": "Sumputkeun data boh ti kuncén atawa nu séjénna",
"revdelete-radio-same": "(ulah dirobah)",
- "revdelete-radio-set": "Enya",
- "revdelete-radio-unset": "Ulah",
+ "revdelete-radio-set": "Nyumput",
+ "revdelete-radio-unset": "Némbongan",
"revdelete-suppress": "Sumputkeun ogé ti kuncén",
"revdelete-unsuppress": "Hapus watesan kana révisi anu geus dipulangkeun",
"revdelete-log": "Alesan:",
"revdelete-submit": "Larapkeun kana {{PLURAL:$1|révisi|révisi}} nu dipilih",
- "revdelete-success": "Pangaturan nyumpukeun révisi junun dilarapkeun.",
+ "revdelete-success": "<strong>Visibilitas révisi geus dimutahirkeun.</strong>",
"revdelete-failure": "'''Visibilitas révisi teu bisa diapdét:'''\n$1",
"logdelete-success": "Log pangatur nyumputkeun junun dilarapkeun.",
"logdelete-failure": "'''Visibilitas log teu bisa disét:'''\n$1",
"search-section": "(bagean $1)",
"search-suggest": "Meureun maksud Anjeun nyaéta: $1",
"search-interwiki-caption": "Proyék sawargi",
- "search-interwiki-default": "$1 hasil:",
+ "search-interwiki-default": "Hasil ti $1:",
"search-interwiki-more": "(saterusna)",
"search-relatedarticle": "Patula-patali",
"searchrelated": "patula-patali",
"searchall": "sadayana",
"showingresults": "Di handap ieu némbongkeun {{PLURAL:$1|'''1''' hasil|'''$1''' hasil}}, dimimitianku #'''$2'''.",
- "showingresultsheader": "{{PLURAL:$5|Hasil '''$1''' ti '''$3'''|Hasil '''$1 - $2''' ti '''$3'''}} pikeun '''$4'''",
"search-nonefound": "Euweuh hasil nu cocog jeung kueri.",
"powersearch-legend": "Panéangan tuluy",
"powersearch-ns": "Téangan di ngaranspasi:",
"skin-preview": "Pramidang",
"datedefault": "Tanpa préferénsi",
"prefs-labs": "Fitur Labs",
+ "prefs-user-pages": "Kaca pamaké",
"prefs-personal": "Data pamaké",
"prefs-rc": "Panémbong robahan anyar jeung tukung",
"prefs-watchlist": "Awaskeuneun",
"timezoneregion-indian": "Samudra Indonésia",
"timezoneregion-pacific": "Samudra Pasifik",
"allowemail": "Buka koropak pikeun nampa surélék ti nu séjén",
- "prefs-searchoptions": "Piliheun Panéangan",
+ "prefs-searchoptions": "Paluruh",
"prefs-namespaces": "Ngaranspasi",
"default": "ti dituna",
"prefs-files": "Koropak",
"prefs-reset-intro": "Anjeun bisa maké ieu kaca pikeun mulangkeun préferénsi anjeun ka nu baku.\nMun geus anggeus teu bisa dibolaykeun.",
"prefs-emailconfirm-label": "Konfirmasi surélék:",
"youremail": "Surélék:",
- "username": "Landihan:",
- "prefs-memberingroups": "Anggota {{PLURAL:$1|jumplukan|jumplukan}}:",
+ "username": "{{GENDER:$1|Sandiasma}}:",
+ "prefs-memberingroups": "{{GENDER:$2|Anggota}} {{PLURAL:$1|kelompok|kelompok}}:",
"prefs-registration": "Waktu daptar:",
"yourrealname": "Ngaran anjeun*",
"yourlanguage": "Basa antarbeungeut",
"badsig": "Parafna teu valid; pariksa tag HTML-na geura.",
"badsiglength": "Tawis leungeun panjang teuing. Kuduna kurang ti $1 {{PLURAL:$1|karaktér|karaktér}}.",
"yourgender": "Jenis kelamin:",
- "gender-unknown": "Teu nyebutkeun",
- "gender-male": "Lalaki",
- "gender-female": "Awéwé",
+ "gender-unknown": "Moal béja-béja",
+ "gender-male": "Manéhna ngédit kaca wiki",
+ "gender-female": "Manéhna ngédit kaca wiki",
"email": "Surélék",
"prefs-help-realname": "* Ngaran asli (pilihan): mun anjeun milih ngeusian, bakal dipaké pikeun nandaan kontribusi anjeun.",
"prefs-help-email": "Surélék sipatna pilihan, tapi diperlukeun pikeun nyetél ulang sandi lamun anjeun poho.",
"prefs-signature": "Tandatangan",
"prefs-dateformat": "Format titimangsa",
"prefs-timeoffset": "Format waktu",
- "prefs-advancedediting": "Pilihan lengkep",
+ "prefs-advancedediting": "Pilihan umum",
+ "prefs-editor": "Éditor",
+ "prefs-preview": "Pratayang",
"prefs-advancedrc": "Pilihan lengkep",
"prefs-advancedrendering": "Pilihan lengkep",
"prefs-advancedsearchoptions": "Pilihan lengkep",
"prefs-advancedwatchlist": "Pilihan lengkep",
"prefs-displayrc": "Pilihan pidangan",
"prefs-displaywatchlist": "Pilihan pidangan",
+ "prefs-tokenwatchlist": "Token",
"prefs-diffs": "Béda",
"email-address-validity-valid": "Alamat surélék sigana bener",
"email-address-validity-invalid": "Asupkeun alamat ratron nu bener",
"right-move": "Mindahkeun kaca",
"right-move-subpages": "Pindahkeun kaca katut sakabéh subkacana",
"right-move-rootuserpages": "Mindahkeun akar kaca kontributor",
+ "right-move-categorypages": "Pindahkeun kaca kategori",
"right-movefile": "Mindahkeun berkas",
"right-suppressredirect": "Henteu nyieun hiji alihan ti ngaran lila sabot mindahkeun kaca",
"right-upload": "Muatkeun koropak",
"right-browsearchive": "Sungsi kaca nu geus dihapus",
"right-undelete": "Balikeun deui kaca",
"right-suppressrevision": "Mariksa jeung mulangkeun révisi anu disumputkeun ti kuncén",
+ "right-viewsuppressed": "Témbongkeun révisi anu disumputkeun ti pamaké lianna",
"right-suppressionlog": "Nempo log privat",
"right-block": "Peungpeuk pamaké lain tina ngédit",
"right-blockemail": "Halangan pamaké keur ngirim Surélék",
"right-hideuser": "Peungpeuk pamaké, tong ditingalikeun ka nulain",
"right-ipblock-exempt": "Narabas peungpeuk IP, peungpeuk-otomatis, jeung peungpeuk rentang",
"right-proxyunbannable": "Abaikeun pengpeuk otomatis keur proxy",
- "right-unblockself": "Muka peungpeuk ka dirina sorangan",
- "right-protect": "Ngarobah hambalan konci jeung ngédit kaca anu dikonci",
- "right-editprotected": "Ngédit kaca anu dikonci (tanpa ngarobah protéksi)",
+ "right-unblockself": "buka peungpeuk sorangan",
+ "right-protect": "Ngarobah hambalan protéksi jeung édit kaca anu dikonci",
+ "right-editprotected": "Edit kaca anu dikonci salaku \"{{int:protect-level-sysop}}\"",
"right-editinterface": "Édit antarbenget pamaké",
"right-editusercssjs": "Édit berkas CSS jeung JS pamaké séjén",
"right-editusercss": "Édit berkas CSS pamaké séjén",
"right-edituserjs": "Ngédit berkas JS pamaké séjén",
+ "right-viewmywatchlist": "Tempo awaskeuneun anjeun",
+ "right-viewmyprivateinfo": "Tempo data pribadi anjeun (alamat surélék, ngaran asli)",
+ "right-editmyprivateinfo": "Robah data pribadi anjeun (alamat surélék, ngaran asli)",
+ "right-editmyoptions": "Robah préferénsi anjeun",
"right-import": "Ngimpor kaca ti wiki séjén",
"right-importupload": "Ngimpor kaca tina hiji koropak nu dimuat",
"right-patrol": "Nandaan éditan pamaké séjén minangka geus dipatroli",
"action-createpage": "mitembeyan kaca anyar",
"action-createtalk": "mitembeyan kaca obrolan",
"action-createaccount": "nyieun rekening pamaké ieu",
+ "action-history": "tempo jujutan ieu kaca",
"action-minoredit": "nandaan ieu éditan salaku minor",
"action-move": "mindahkeun ieu kaca",
"action-move-subpages": "mindahkeun ieu kaca katut bagian-bagianana",
"action-move-rootuserpages": "mindahkeun kaca utama kontributor",
+ "action-move-categorypages": "pindahkeun kaca kategori",
"action-movefile": "mindahkeun ieu berkas",
"action-upload": "ngamuat ieu berkas",
"action-reupload": "nimpah berkas nu geus aya ieu",
"action-suppressionlog": "nempo ieu log pribadi",
"action-block": "meungpeuk ieu pamaké tina ngédit",
"action-protect": "ngarobah hambalan konci ieu kaca",
- "action-import": "impor ieu kaca ti séjén wiki",
+ "action-import": "impor kaca ti wiki séjén",
"action-patrol": "Nandaan éditan séjén minangka geus diroris",
"action-autopatrol": "tandaan éditan anjeun salaku geus diroris",
"action-unwatchedpages": "témbongkeun béréndélan kaca nu teu diawaskeun",
"action-userrights-interwiki": "ngarobah hak pamaké di wiki lianna",
"action-siteadmin": "ngonci atawa muka konci databés",
"action-sendemail": "ngirim surélék",
+ "action-editmywatchlist": "robah awaskeuneun anjeun",
+ "action-viewmyprivateinfo": "tempo émbaran pribadi anjeun",
+ "action-editmyprivateinfo": "robah émbaran pribadi anjeun",
"nchanges": "$1 {{PLURAL:$1|parobahan|parobahan}}",
+ "enhancedrc-history": "jujutan",
"recentchanges": "Anyar robah",
"recentchanges-legend": "Pilihan parobahan anyar",
"recentchanges-summary": "Lacak parobahan ka wiki panganyarna na kaca ieu.",
"recentchanges-label-minor": "Ieu éditan minor",
"recentchanges-label-bot": "Ieu parobahan dijieun ku bot",
"recentchanges-label-unpatrolled": "Ieu éditan can karoris",
+ "recentchanges-legend-heading": "'''Pedaran:'''",
"recentchanges-legend-newpage": "$1 - kaca anyar",
"rcnotefrom": "Di handap ieu parobahan saprak <b>$2</b> (nu ditémbongkeun nepi ka <b>$1</b>).",
"rclistfrom": "Témbongkeun nu anyar robah nepi ka $3 $2",
"rcshowhideminor": "$1 éditan minor",
+ "rcshowhideminor-show": "Témbongkeun",
+ "rcshowhideminor-hide": "Sumputkeun",
"rcshowhidebots": "$1 bot",
- "rcshowhideliu": "$1 kontributor nu asup log",
+ "rcshowhidebots-show": "Témbongkeun",
+ "rcshowhidebots-hide": "Sumputkeun",
+ "rcshowhideliu": "$1 pamaké kadaptar",
+ "rcshowhideliu-show": "Témbongkeun",
+ "rcshowhideliu-hide": "Sumputkeun",
"rcshowhideanons": "$1 kontributor anonim",
+ "rcshowhideanons-show": "Témbongkeun",
+ "rcshowhideanons-hide": "Sumputkeun",
"rcshowhidepatr": "$1 éditan karoris",
+ "rcshowhidepatr-show": "Témbongkeun",
+ "rcshowhidepatr-hide": "Sumputkeun",
"rcshowhidemine": "$1 éditan kuring",
+ "rcshowhidemine-show": "Témbongkeun",
+ "rcshowhidemine-hide": "Sumputkeun",
"rclinks": "Témbongkeun $1 parobahan ahir dina $2 poé ahir<br />$3",
"diff": "béda",
"hist": "juj",
"newsectionsummary": "/* $1 */ bagean anyar",
"rc-enhanced-expand": "Témbongkeun rincian (butuh JavaScript)",
"rc-enhanced-hide": "Sumputkeun rincian",
+ "rc-old-title": "Mimitina dijieun salaku \"$1\"",
"recentchangeslinked": "Parobahan nu patali",
"recentchangeslinked-feed": "Parobahan nu patali",
"recentchangeslinked-toolbox": "Parobahan nu patali",
"uploadbtn": "Muatkeun koropak",
"reuploaddesc": "Balik ka formulir muatan.",
"uploadnologin": "Can asup log",
- "uploadnologintext": "Anjeun kudu [[Special:UserLogin|asup log]] pikeun ngamuat koropak.",
+ "uploadnologintext": "Mangga $1 pikeun ngunggah berkas.",
"upload_directory_read_only": "Diréktori muatan ($1) teu bisa ditulis ku server ramat.",
"uploaderror": "Kasalahan muat",
"upload-recreate-warning": "'''Awas: berkas nu ngaranna kitu geus kungsi dihapus atawa dipindahkeun.'''\n\nLog hahapus jeung pipindah pikeun ieu kaca dipidangkeun di handap:",
"uploadwarning-text": "Ropéa pedaran berkas di handap terus cobaan deui.",
"savefile": "Simpen koropak",
"uploaddisabled": "Punten, ngamuat ayeuna ditumpurkeun.",
+ "copyuploaddisabled": "Unggahan dumasar URL ditumpurkeun.",
"uploaddisabledtext": "Fungsi ngamuat koropak ditumpurkeun.",
"uploadscripted": "Koropak ieu ngandung kode HTML atawa skrip nu bisa dibaca ngaco ku panyungsi ramat (''web browser'').",
"uploadvirus": "Koropakna ngandung virus! Katrangan: $1",
"lockmanager-fail-db-release": "Teu bisa ngaleupaskeun konci dina databés $1.",
"lockmanager-fail-svr-release": "Teu bisa ngaleupaskeun konci dina server $1.",
"zip-wrong-format": "Berkas anu dipilih lain berkas ZIP.",
+ "img-auth-accessdenied": "Aksés ditolak",
"img-auth-nofile": "Berkas \"$1\" henteu aya.",
"img-auth-noread": "Pamaké teu boga kawenangan maca \"$1\".",
"http-invalid-url": "URL teu bener: $1",
"license": "Lisénsi:",
"license-header": "Lisénsi",
"nolicense": "Taya nu dipilih",
+ "licenses-edit": "Robah pilihan lisénsi",
"license-nopreview": "(euweuh pramidang)",
"upload_source_url": "(URL nu sohéh sarta bisa dibuka ku umum)",
"upload_source_file": " (koropak dina komputer salira)",
+ "listfiles-delete": "hapus",
+ "listfiles-summary": "Ieu kaca husus némbongkeun sakabéh berkas anu geus diunggah.",
"listfiles_search_for": "Sungsi ngaran média:",
"imgfile": "koropak",
"listfiles": "Daptar gambar",
"listfiles_size": "Badagna",
"listfiles_description": "Pedaran",
"listfiles_count": "Vérsi",
+ "listfiles-latestversion": "Vérsi ayeuna",
+ "listfiles-latestversion-yes": "Enya",
+ "listfiles-latestversion-no": "Henteu",
"file-anchor-link": "Gambar",
"filehist": "Sajarah gambar",
"filehist-help": "Klik dina titimangsa pikeun nempo koropak nu aya dina mangsa éta.",
"filedelete-reason-otherlist": "Alesan séjén",
"filedelete-reason-dropdown": "*Alesan nu ilahar\n** Ngarumpak hak cipta\n** Koropak geus aya",
"filedelete-edit-reasonlist": "Alesan ngahapus éditan",
+ "filedelete-maintenance-title": "Henteu bisa ngahapus berkas",
"mimesearch": "Sungsi MIME",
"mimesearch-summary": "Ieu kaca bisa dipaké nyaring koropak dumasar tipeu MIME-na. Asupan: contenttype/subtype, contona <code>image/jpeg</code>.",
"mimetype": "Tipeu MIME:",
"unusedtemplateswlh": "tumbu lianna",
"randompage": "Kaca acak",
"randompage-nopages": "Euweuh kaca dina ieu spasi ngaran \"$1\".",
+ "randomincategory-category": "Kategori:",
"randomredirect": "Alihan acak",
"randomredirect-nopages": "Euweuh alihan dina ieu spasi ngaran \"$1\".",
"statistics": "Statistik",
"statistics-users-active": "Pamaké getol",
"statistics-users-active-desc": "Kontributor nu ngoprék salila {{PLURAL:$1|poé|$1 poé}} panungtung",
"statistics-mostpopular": "Kaca nu pangmindengna dibuka",
+ "pageswithprop-submit": "Jung",
"doubleredirects": "Alihan ganda",
"doubleredirectstext": "Ieu kaca ngabéréndélkeun kaca-kaca alihan ka kaca alihan lianna. Unggal baris ngandung tutumbu ka alihan kahiji jeung kadua, ogé tujul alihan kadua anu biasana tujul kaca anu \"bener\", anu sakuduna dituju ku alihan kahiji. Ëntri nu <del>dicorét</del> geus diropéa.",
"double-redirect-fixed-move": "[[$1]] geus pindah, dialihkeun ka [[$2]].",
"fewestrevisions": "Artikel nu pangjarangna dirévisi",
"nbytes": "$1 {{PLURAL:$1|bait|bait}}",
"ncategories": "$1 {{PLURAL:$1|kategori|kategori}}",
+ "ninterwikis": "$1 {{PLURAL:$1|interwiki|interwiki}}",
"nlinks": "$1 {{PLURAL:$1|tumbu|tumbu}}",
"nmembers": "$1 {{PLURAL:$1|kontributor|kontributor}}",
+ "nmemberschanged": "$1 → $2 {{PLURAL:$2|anggota|anggota}}",
"nrevisions": "$1 {{PLURAL:$1|révisi|révisi}}",
"nviews": "$1 {{PLURAL:$1|témbongan|témbongan}}",
"nimagelinks": "Dipaké di $1 {{PLURAL:$1|kaca|kaca}}",
"protectedpages": "Kaca-kaca nu dikonci",
"protectedpages-indef": "Ngan pikeun panangtayungan kalawan waktu nuteu kawates",
"protectedpagesempty": "Dina danget ieu, teu aya kaca nu dikonci dumasar kana ieu paraméter.",
+ "protectedpages-timestamp": "Cap titimangsa",
+ "protectedpages-page": "Kaca",
+ "protectedpages-expiry": "Kadaluwarsa",
+ "protectedpages-params": "Paraméter protéksi",
+ "protectedpages-reason": "Alesan",
+ "protectedpages-unknown-timestamp": "Teu kanyahoan",
+ "protectedpages-unknown-performer": "Pamaké henteu dipikawanoh",
"protectedtitles": "Judul nu dikonci",
"protectedtitlesempty": "Dina danget ieu, euweuh judul nu keur dikonci tina paraméter-paraméter éta.",
"listusers": "Daptar pamaké",
"booksources-text": "Di handap ieu ngabéréndélkeun tumbu ka loka-loka nu ngical buku, boh nu anyar atawa loakan, nu sugan uninga kana buku anu nuju dipilari:",
"booksources-invalid-isbn": "ISBN-na sigana henteu bener; pariksa deui bisi aya salah salin ti sumber aslina.",
"specialloguserlabel": "Pamaké:",
- "speciallogtitlelabel": "Judul:",
+ "speciallogtitlelabel": "Sasaran (judul atawa pamaké):",
"log": "Log",
"all-logs-page": "Sakabéh log umum",
"alllogstext": "Béréndélan sakabéh log nu aya di {{SITENAME}}.\nBisa dipondokkeun ku cara milih tipe log, ngaran pamaké, atawa kaca nu dimaksud.",
"emailuser": "Surélékan pamaké ieu",
"emailpage": "Surélékan pamaké",
"emailpagetext": "Anjeun bisa maké formulir di handap pikeun ngirim surélék ka ieu pamaké.\nAlamat surélék nu diasupkeun kana [[Special:Preferences|préferénsi pamaké anjeun]] bakal katémbong salaku alamat \"Ti\" dina surélékna, sahingga nu dituju bisa males langsung.",
- "defemailsubject": "Surélék {{SITENAME}}",
+ "defemailsubject": "Surélék {{SITENAME}} ti pamaké \"$1\"",
"usermaildisabled": "Surélék kontributor ditumpurkeun",
"usermaildisabledtext": "Anjeun teu bisa ngirim surélék ka kontributor séjén di ieu wiki",
"noemailtitle": "Teu aya alamat surélék",
"noemailtext": "Ieu pamaké ieu teu méré alamat surélék nu sah.",
"nowikiemailtext": "Ieu kontributor milih teu nampa surélék ti kontributor séjén.",
+ "emailnotarget": "Sandiasma panarima henteu valid atawa henteu aya.",
+ "emailtarget": "ASupkeun sandiasma panarima",
"emailusername": "Sandiasma:",
"emailusernamesubmit": "Kirim",
"email-legend": "Kirim surélék ka kontributor {{SITENAME}} lianna",
"emailsent": "Surélék geus dikirim",
"emailsenttext": "Surélék anjeun geus dikirim.",
"emailuserfooter": "Ieu surélék dikirim ku $1 ka $2 migunakeun fungsi \"Surélékan pamaké ieu\" di {{SITENAME}}.",
+ "usermessage-summary": "Ninggalkeun talatah sistem.",
"watchlist": "Awaskeuneun",
"mywatchlist": "Awaskeuneun",
"watchlistfor2": "Pikeun $1 $2",
"nowatchlist": "Anjeun teu boga awaskeuneun.",
- "watchlistanontext": "Mangga $1 pikeun némbongkeun atawa ngarobah béréndélan awaskeuneun anjeun.",
+ "watchlistanontext": "Mangga asup log pikeun nempo atawa ngarobah béréndélan awaskeuneun anjeun.",
"watchnologin": "Can asup log",
"addedwatchtext": "Kaca \"[[:$1]]\" geus ditambahkeun ka [[Special:Watchlist|awaskeuneun]] anjeun.\nJaga, parobahan na kaca ieu katut kaca obrolanana bakal dibéréndélkeun di dinya, sarta kacana bakal katémbong '''dikandelan''' dina kaca [[Special:RecentChanges|Nu anyar robah]] sangkan leuwih gampang ngawaskeunana.\n\n<p>Mun jaga anjeun moal deui ngawaskeun parobahan na kaca éta, klik tumbu \"Eureun ngawaskeun\" na lajursisi.",
+ "removewatch": "Piceun tina béréndélan awaskeuneun",
"removedwatchtext": "Kaca \"[[:$1]]\" geus dikaluarkeun tina [[Special:Watchlist|daptar awaskeuneun]] anjeun.",
+ "removedwatchtext-short": "Kaca \"$1\" geus dipiceun tina béréndélan awaskeuneun.",
"watch": "awaskeun",
"watchthispage": "Awaskeun kaca ieu",
"unwatch": "Eureun ngawaskeun",
"unwatchthispage": "Eureun ngawaskeun",
"notanarticle": "Sanés kaca eusi",
"notvisiblerev": "Révisi geus dihapus",
- "watchlist-details": "Aya {{PLURAL:$1|$1 kaca|$1 kaca}} nu ku anjeun diawaskeun, teu kaasup kaca obrolan/sawala.",
+ "watchlist-details": "Aya {{PLURAL:$1|$1 kaca|$1 kaca}} dina béréndélan awaskeuneun, teu kaasup kaca obrolan/sawala.",
"wlheader-enotif": "Pangémbar surélék difungsikeun.",
"wlheader-showupdated": "Kaca nu robah ti panungtungan anjeun sindang ditémbongkeun kalawan '''kandel'''",
"wlnote": "Di handap ieu mangrupa $1 {{PLURAL:$1|robahan|robahan}} ahir salila '''$2''' jam.",
"unwatching": "Eureun ngawaskeun...",
"enotif_reset": "Tandaan sadaya kaca nu geus dilongok",
"enotif_impersonal_salutation": "Pamaké {{SITENAME}}",
+ "enotif_subject_deleted": "Kaca {{SITENAME}} $1 geus {{GENDER:$2|dihapus}} ku $2",
"enotif_lastvisited": "Tempo $1 pikeun sadaya parobahan ti saprak anjeun ninggalkeun ieu kaca.",
"enotif_lastdiff": "Buka $1 pikeun nempo ieu parobahan.",
"enotif_anon_editor": "pamaké anonim $1",
"protect-level-sysop": "Ngan bisa ku kuncén",
"protect-summary-cascade": "ngaruntuykeun",
"protect-expiring": "kadaluwarsa $1",
+ "protect-expiring-local": "kadaluwarsa $1",
"protect-expiry-indefinite": "tanpa wates",
"protect-cascade": "Konci kaca nu kawengku dina ieu kaca (pangonci ngaruntuy).",
"protect-cantedit": "Anjeung teu wenang ngarobah hambalan ngonci ieu kaca.",
"protect-othertime": "Séjén waktu",
+ "protect-othertime-op": "séjén waktu",
"protect-existing-expiry": "Waktu mungkas nu aya: $3, $2",
+ "protect-existing-expiry-infinity": "Waktu kadaluwarsa nu aya: taya wates",
"protect-otherreason": "Alesan panambah/lianna:",
"protect-otherreason-op": "Alesan séjén",
"protect-dropdown": "*Alesan ngonci nu ilahar\n** Vandalismeu kamalinaan\n** Spamming kamalinaan\n** Perang éditan\n** Kaca loba pisan diédit",
"contributions": "Kontribusi ti kontributor",
"contributions-title": "Sumbangan tulisan ti $1",
"mycontris": "Kontribusi",
- "contribsub2": "Pikeun $1 ($2)",
+ "contribsub2": "Pikeun {{GENDER:$3|$1}} ($2)",
+ "contributions-userdoesnotexist": "Akun pamaké \"$1\" teu aya dina daptar.",
"nocontribs": "Taya robahan nu kapanggih cocog jeung patokan ieu.",
- "uctop": "(pangluhurna)",
+ "uctop": "(ayeuna)",
"month": "Ti bulan (jeung saméméhna):",
"year": "Ti taun (jeung saméméhna):",
"sp-contributions-newbies": "Témbongkeun kontribusi ti akun anyar wungkul",
"unblocklink": "buka blokir",
"change-blocklink": "Robah status blokir",
"contribslink": "kontribusi",
+ "emaillink": "kirim surélék",
"autoblocker": "Otomatis dipeungpeuk kusabab alamat IP anjeun dipaké ku \"[[User:$1|$1]]\".\nAlesan: \"$2\"",
"blocklogpage": "Log_peungpeuk",
"blocklog-showlog": "Ieu pamaké saméméhna geus kungsi dipeungpeuk.\nPikeun rujukan, logna dipidangkeun di handap ieu:",
"import": "Impor kaca",
"importinterwiki": "Impor transwiki",
"import-interwiki-text": "Pilih wiki jeung judul kaca nu rék diimpor.\nTanggal révisi katut ngaran nu ngédit bakal dipertahankeun.\nSadaya aktivitas impor transwiki baris kacatet dina [[Special:Log/import|log impor]].",
- "import-interwiki-source": "Wiki/kaca sumber:",
+ "import-interwiki-sourcewiki": "Wiki sumber:",
+ "import-interwiki-sourcepage": "Kaca sumber:",
"import-interwiki-history": "Salin sakabéh vérsi jujutan pikeun ieu kaca",
"import-interwiki-templates": "Kaasup sakabéh citakan",
"import-interwiki-submit": "Impor",
"import-logentry-upload-detail": "$1 {{PLURAL:$1|vérsi heubeul}}",
"import-logentry-interwiki": "$1 geus ditranswikikeun",
"import-logentry-interwiki-detail": "$1 {{PLURAL:$1|vérsi heubel}} ti $2",
+ "javascripttest": "Nguji JavaScript",
"tooltip-pt-userpage": "Kaca kontributor Anjeun",
"tooltip-pt-anonuserpage": "Kaca pamaké pikeun IP nu ku anjeun keur diédit",
"tooltip-pt-mytalk": "Kaca obrolan Anjeun",
"spamprotectiontitle": "Saringan spam",
"spamprotectiontext": "Kaca nu rék disimpen dipeungpeuk ku saringan spam.\nSigana mah ieu téh alatan tumbu ka loka luar.",
"pageinfo-title": "Émbaran pikeun \"$1\"",
- "pageinfo-header-edits": "Éditan",
+ "pageinfo-header-basic": "Émbaran dasar",
+ "pageinfo-header-edits": "Jujutan édit",
+ "pageinfo-header-restrictions": "Protéksi kaca",
"pageinfo-watchers": "Jumlah nu ngawaskeun",
"pageinfo-edits": "Jumlah éditan",
"pageinfo-authors": "Jumlah kontributor nu béda",
+ "pageinfo-contentpage-yes": "Enya",
+ "pageinfo-protect-cascading-yes": "Enya",
"markaspatrolleddiff": "Tandaan salaku geus diriksa",
"markaspatrolledtext": "Tandaan artikel ieu salaku geus diriksa",
"markedaspatrolled": "Tandaan salaku geus diriksa",
"searchall": "tất cả",
"showingresults": "Dưới đây là {{PLURAL:$1|'''1'''|'''$1'''}} kết quả bắt đầu từ #'''$2'''.",
"showingresultsinrange": "Dưới đây là cho tới <strong>$1</strong> kết quả từ #<strong>$2</strong> đến #<strong>$3</strong>.",
+ "search-showingresults": "{{PLURAL:$4|Kết quả thứ <strong>$1</strong> trong tổng số <strong>$3</strong>|Các kết quả <strong>$1–$2</strong> trong tổng số <strong>$3</strong>}}",
"search-nonefound": "Không có kết quả nào khớp với câu truy vấn.",
"powersearch-legend": "Tìm kiếm nâng cao",
"powersearch-ns": "Tìm trong không gian tên:",
"unblocked": "[[User:$1|$1]] đã hết bị cấm",
"unblocked-range": "$1 đã được bỏ cấm",
"unblocked-id": "$1 đã hết bị cấm",
+ "unblocked-ip": "[[Special:Contributions/$1|$1]] đã được bỏ cấm.",
"blocklist": "Người dùng bị cấm",
"ipblocklist": "Người dùng bị cấm",
"ipblocklist-legend": "Tìm một thành viên bị cấm",
"protect-othertime": "其它时间:",
"protect-othertime-op": "其它时间",
"protect-existing-expiry": "现有的终止时间:$2 $3",
+ "protect-existing-expiry-infinity": "当前到期时间:无限期",
"protect-otherreason": "其他/附加原因:",
"protect-otherreason-op": "其他原因",
"protect-dropdown": "*常见保护原因\n** 过度破坏\n** 过多垃圾信息\n** 负面的编辑战\n** 高流量页面",
]
},
"tog-underline": "連結顯示底線:",
- "tog-hideminor": "é\9a±è\97\8fæ\9c\80è¿\91è®\8aæ\9b´ä¸ç\9a\84å°\8fä¿®è¨\82",
+ "tog-hideminor": "é\9a±è\97\8fæ\9c\80è¿\91è®\8aæ\9b´ä»¥ä¾\86ç\9a\84å°\8f編輯",
"tog-hidepatrolled": "隱藏最近變更中巡查過的編輯",
"tog-newpageshidepatrolled": "隱藏新頁面清單中巡查過的頁面",
"tog-extendwatchlist": "展開監視清單顯示包含最近以外的所有變更",
"headline_tip": "第 2 層標題文字",
"nowiki_sample": "插入非格式化文字",
"nowiki_tip": "忽略 Wiki 格式化語法",
+ "image_sample": "範例.jpg",
"image_tip": "附加檔案",
"media_tip": "檔案連結",
"sig_tip": "您的簽名與日期時間",
'mediawiki.page.ready' => array(
'scripts' => 'resources/src/mediawiki.page/mediawiki.page.ready.js',
'dependencies' => array(
+ 'jquery.accessKeyLabel',
'jquery.checkboxShiftClick',
'jquery.makeCollapsible',
'jquery.placeholder',
'jquery.mw-jump',
- 'mediawiki.util',
),
'targets' => array( 'desktop', 'mobile' ),
),
/* MediaWiki UI */
'mediawiki.ui' => array(
- 'styles' => array(
- 'resources/src/mediawiki.ui/default.less',
+ 'skinStyles' => array(
+ 'default' => array(
+ 'resources/src/mediawiki.ui/default.less',
+ ),
),
'position' => 'top',
'targets' => array( 'desktop', 'mobile' ),
),
'mediawiki.ui.checkbox' => array(
- 'styles' => array(
- 'resources/src/mediawiki.ui/components/checkbox.less',
+ 'skinStyles' => array(
+ 'default' => array(
+ 'resources/src/mediawiki.ui/components/checkbox.less',
+ ),
),
'position' => 'top',
'targets' => array( 'desktop', 'mobile' ),
),
// Lightweight module for anchor styles
'mediawiki.ui.anchor' => array(
- 'styles' => array(
- 'resources/src/mediawiki.ui/components/anchors.less',
+ 'skinStyles' => array(
+ 'default' => array(
+ 'resources/src/mediawiki.ui/components/anchors.less',
+ ),
),
'position' => 'top',
'targets' => array( 'desktop', 'mobile' ),
),
// Lightweight module for button styles
'mediawiki.ui.button' => array(
- 'styles' => array(
- 'resources/src/mediawiki.ui/components/buttons.less',
+ 'skinStyles' => array(
+ 'default' => array(
+ 'resources/src/mediawiki.ui/components/buttons.less',
+ ),
),
'position' => 'top',
'targets' => array( 'desktop', 'mobile' ),
),
'mediawiki.ui.input' => array(
- 'styles' => array(
- 'resources/src/mediawiki.ui/components/inputs.less',
+ 'skinStyles' => array(
+ 'default' => array(
+ 'resources/src/mediawiki.ui/components/inputs.less',
+ ),
),
'position' => 'top',
'targets' => array( 'desktop', 'mobile' ),
--- /dev/null
+The icons used here are derived from the crystalsvg icons in the the
+pics/crystalsvg/ directory of kdelibs-3.4.0 they were modified on 2005-05-15
+by Ævar Arnfjörð Bjarmason for use in MediaWiki.
+
+What follows is the contents of the LICENSE.crystalsvg file found in the pics/
+subdirectory of kdelibs-3.4.0:
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+This copyright and license notice covers all CrystalSVG images.
+Note the license notice contains an add-on.
+********************************************************************************
+KDE Crystal theme icons.
+Copyright (C) 2002 and following years KDE Artists
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation,
+version 2.1 of the License.
+This library 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
+Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ **** NOTE THIS ADD-ON ****
+The GNU Lesser General Public License or LGPL is written for software libraries
+in the first place. We expressly want the LGPL to be valid for this artwork
+library too.
+KDE Crystal theme icons is a special kind of software library, it is an
+artwork library, it's elements can be used in a Graphical User Interface, or
+GUI.
+Source code, for this library means:
+ - for vectors svg;
+ - for pixels, if applicable, the multi-layered formats xcf or psd, or
+otherwise png.
+The LGPL in some sections obliges you to make the files carry
+notices. With images this is in some cases impossible or hardly useful.
+With this library a notice is placed at a prominent place in the directory
+containing the elements. You may follow this practice.
+The exception in section 6 of the GNU Lesser General Public License covers
+the use of elements of this art library in a GUI.
+kde-artists [at] kde.org
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"@metadata": {
"authors": [
"Vacio",
- "Xelgen"
+ "Xelgen",
+ "Դավիթ Սարոյան"
]
},
- "ooui-dialog-action-close": "Փակել",
"ooui-outline-control-move-down": "Իջեցնել կետը",
"ooui-outline-control-move-up": "Բարձրացնել կետը",
"ooui-outline-control-remove": "Հեռացնել տարրը",
- "ooui-toolbar-more": "Ավելին"
+ "ooui-toolbar-more": "Ավելին",
+ "ooui-dialog-message-accept": "Լավ",
+ "ooui-dialog-message-reject": "Չեղարկել",
+ "ooui-dialog-process-error": "Ինչ-որ սխալ է տեղի ունեցել",
+ "ooui-dialog-process-dismiss": "Փակել",
+ "ooui-dialog-process-retry": "Կրկին փորձել"
}
/*!
- * OOjs UI v0.1.0-pre (49b64bdba7)
+ * OOjs UI v0.1.0-pre (ec785c2c64)
* 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: 2014-09-15T22:18:37Z
+ * Date: 2014-09-18T01:30:17Z
*/
/*
* Blank theme mixins.
/*!
- * OOjs UI v0.1.0-pre (49b64bdba7)
+ * OOjs UI v0.1.0-pre (ec785c2c64)
* 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: 2014-09-15T22:18:37Z
+ * Date: 2014-09-18T01:30:17Z
*/
/*
* Blank theme mixins.
/*!
- * OOjs UI v0.1.0-pre (49b64bdba7)
+ * OOjs UI v0.1.0-pre (ec785c2c64)
* 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: 2014-09-15T22:18:37Z
+ * Date: 2014-09-18T01:30:17Z
*/
( function ( OO ) {
* @inheritdoc
*
* @param {Object} [data] Dialog opening data
- * @param {jQuery|string|Function|null} [data.label] Dialog label, omit to use #static-label
+ * @param {jQuery|string|Function|null} [data.title] Dialog title, omit to use #static-title
* @param {Object[]} [data.actions] List of OO.ui.ActionWidget configuration options for each
* action item, omit to use #static-actions
*/
};
/**
- * Set the ideal size.
+ * Set the ideal size. These are the dimensions the element will have when it's not being clipped.
*
* @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
OO.ui.ClippableElement.prototype.setIdealSize = function ( width, height ) {
this.idealWidth = width;
this.idealHeight = height;
+
+ if ( !this.clipping ) {
+ // Update dimensions
+ this.$clippable.css( { width: width, height: height } );
+ }
+ // While clipping, idealWidth and idealHeight are not considered
};
/**
var change = visible !== this.isVisible();
+ if ( change && visible ) {
+ // Make sure the width is set before the parent method runs.
+ // After this we have to call this.position(); again to actually
+ // position ourselves correctly.
+ this.position();
+ }
+
// Parent method
OO.ui.TextInputMenuWidget.super.prototype.toggle.call( this, visible );
this.$( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );
}
}
+
return this;
};
/*!
- * OOjs UI v0.1.0-pre (49b64bdba7)
+ * OOjs UI v0.1.0-pre (ec785c2c64)
* 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: 2014-09-15T22:18:37Z
+ * Date: 2014-09-18T01:30:17Z
*/
/*
* Blank theme mixins.
*/
/* Hide, but keep accessible for screen-readers. */
-.redirectTo {
+.redirectMsg p {
overflow: hidden;
height: 0;
zoom: 1;
/**
* Misc. utilities
*
- * @deprecated since 1.17 Use mediawiki.util instead
+ * @deprecated since 1.17 Use mediawiki.util or jquery.accessKeyLabel instead
*/
msg = 'Use mediawiki.util instead.';
-mw.log.deprecate( win, 'updateTooltipAccessKeys', mw.util.updateTooltipAccessKeys, msg );
mw.log.deprecate( win, 'addPortletLink', mw.util.addPortletLink, msg );
mw.log.deprecate( win, 'appendCSS', mw.util.addCSS, msg );
msg = 'Use jquery.accessKeyLabel instead.';
mw.log.deprecate( win, 'tooltipAccessKeyPrefix', 'alt-', msg );
mw.log.deprecate( win, 'tooltipAccessKeyRegexp', /\[(alt-)?(.)\]$/, msg );
+// mw.util.updateTooltipAccessKeys already generates a deprecation message.
+win.updateTooltipAccessKeys = function () {
+ return mw.util.updateTooltipAccessKeys.apply( null, arguments );
+};
/**
* Wikipage import methods
@colorGrayLight: #ccc;
@colorGrayLighter: #ddd;
@colorGrayLightest: #eee;
+
+// Global border radius to be used to buttons and inputs
+@borderRadius: 2px;
// Things outside the wikipage content
$( function () {
+ var $nodes;
if ( !supportsPlaceholder ) {
// Exclude content to avoid hitting it twice for the (first) wikipage content
}
// Add accesskey hints to the tooltips
- mw.util.updateTooltipAccessKeys();
+ if ( document.querySelectorAll ) {
+ // If we're running on a browser where we can do this efficiently,
+ // just find all elements that have accesskeys. We can't use jQuery's
+ // polyfill for the selector since looping over all elements on page
+ // load might be too slow.
+ $nodes = $( document.querySelectorAll( '[accesskey]' ) );
+ } else {
+ // Otherwise go through some elements likely to have accesskeys rather
+ // than looping over all of them. Unfortunately this will not fully
+ // work for custom skins with different HTML structures. Input, label
+ // and button should be rare enough that no optimizations are needed.
+ $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
+ }
+ $nodes.updateTooltipAccessKeys();
} );
* Styleguide 1.1.
*/
span.reference {
- font-size: smaller;
+ font-size: 80%;
line-height: 1;
vertical-align: super;
unicode-bidi: -moz-isolate;
//
// Styleguide 2.
-@buttonBorderRadius: 3px;
@transitionDuration: .1s;
@transitionFunction: ease-in-out;
// Neutral button styling
//
// Markup:
-// <button class="mw-ui-button">.mw-ui-button</button>
-// <button class="mw-ui-button" disabled>.mw-ui-button</button>
+// <div>
+// <button class="mw-ui-button">.mw-ui-button</button>
+// </div>
+// <div>
+// <button class="mw-ui-button" disabled>.mw-ui-button</button>
+// </div>
//
// Styleguide 2.1.
.mw-ui-button {
// Container styling
.button-colors(#FFF);
- border-radius: @buttonBorderRadius;
+ border-radius: @borderRadius;
+ min-width: 80px;
// Ensure that buttons and inputs are nicely aligned when they have differing heights
vertical-align: middle;
// using the mw-ui-big class.
//
// Markup:
- // <button class="mw-ui-button mw-ui-big">.mw-ui-button</button>
- // <button class="mw-ui-button mw-ui-progressive mw-ui-big">.mw-ui-progressive</button>
- // <button class="mw-ui-button mw-ui-constructive mw-ui-big">.mw-ui-constructive</button>
- // <button class="mw-ui-button mw-ui-destructive mw-ui-big">.mw-ui-destructive</button>
+ // <div>
+ // <button class="mw-ui-button mw-ui-big">.mw-ui-button</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-progressive mw-ui-big">.mw-ui-progressive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-constructive mw-ui-big">.mw-ui-constructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-destructive mw-ui-big">.mw-ui-destructive</button>
+ // </div>
//
// Styleguide 2.1.6.
&.mw-ui-big {
// Some buttons might need to be stacked.
//
// Markup:
- // <button class="mw-ui-button mw-ui-block">.mw-ui-button</button>
- // <button class="mw-ui-button mw-ui-progressive mw-ui-block">.mw-ui-progressive</button>
- // <button class="mw-ui-button mw-ui-constructive mw-ui-block">.mw-ui-constructive</button>
- // <button class="mw-ui-button mw-ui-destructive mw-ui-block">.mw-ui-destructive</button>
+ // <div>
+ // <button class="mw-ui-button mw-ui-block">.mw-ui-button</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-progressive mw-ui-block">.mw-ui-progressive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-constructive mw-ui-block">.mw-ui-constructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-destructive mw-ui-block">.mw-ui-destructive</button>
+ // </div>
//
// Styleguide 2.1.5.
&.mw-ui-block {
// .mw-ui-primary is deprecated, kept for compatibility.
//
// Markup:
- // <button class="mw-ui-button mw-ui-progressive">.mw-ui-progressive</button>
- // <button class="mw-ui-button mw-ui-progressive" disabled>.mw-ui-progressive</button>
+ // <div>
+ // <button class="mw-ui-button mw-ui-progressive">.mw-ui-progressive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-progressive" disabled>.mw-ui-progressive</button>
+ // </div>
//
// Styleguide 2.1.1.
&.mw-ui-progressive,
// e.g. save changes button
//
// Markup:
- // <button class="mw-ui-button mw-ui-constructive">.mw-ui-constructive</button>
- // <button class="mw-ui-button mw-ui-constructive" disabled>.mw-ui-constructive</button>
+ // <div>
+ // <button class="mw-ui-button mw-ui-constructive">.mw-ui-constructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-constructive" disabled>.mw-ui-constructive</button>
+ // </div>
//
// Styleguide 2.1.2.
&.mw-ui-constructive {
// This should not be used for cancel buttons.
//
// Markup:
- // <button class="mw-ui-button mw-ui-destructive">.mw-ui-destructive</button>
- // <button class="mw-ui-button mw-ui-destructive" disabled>.mw-ui-destructive</button>
+ // <div>
+ // <button class="mw-ui-button mw-ui-destructive">.mw-ui-destructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-destructive" disabled>.mw-ui-destructive</button>
+ // </div>
//
// Styleguide 2.1.3.
&.mw-ui-destructive {
// Use quiet buttons when they are less important and alongisde other progressive/destructive/progressive buttons.
//
// Markup:
- // <button class="mw-ui-button mw-ui-quiet">.mw-ui-button</button>
- // <button class="mw-ui-button mw-ui-constructive mw-ui-quiet">.mw-ui-constructive</button>
- // <button class="mw-ui-button mw-ui-constructive mw-ui-quiet" disabled>.mw-ui-constructive</button>
- // <button class="mw-ui-button mw-ui-destructive mw-ui-quiet">.mw-ui-destructive</button>
- // <button class="mw-ui-button mw-ui-destructive mw-ui-quiet" disabled>.mw-ui-destructive</button>
- // <button class="mw-ui-button mw-ui-progressive mw-ui-quiet">.mw-ui-progressive</button>
- // <button class="mw-ui-button mw-ui-progressive mw-ui-quiet" disabled>.mw-ui-progressive</button>
+ // <div>
+ // <button class="mw-ui-button mw-ui-quiet">.mw-ui-button</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-constructive mw-ui-quiet">.mw-ui-constructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-constructive mw-ui-quiet" disabled>.mw-ui-constructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-destructive mw-ui-quiet">.mw-ui-destructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-destructive mw-ui-quiet" disabled>.mw-ui-destructive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-progressive mw-ui-quiet">.mw-ui-progressive</button>
+ // </div>
+ // <div>
+ // <button class="mw-ui-button mw-ui-progressive mw-ui-quiet" disabled>.mw-ui-progressive</button>
+ // </div>
//
// Styleguide 2.1.4.
&.mw-ui-quiet {
float: left;
&:first-child {
- border-top-left-radius: @buttonBorderRadius;
- border-bottom-left-radius: @buttonBorderRadius;
+ border-top-left-radius: @borderRadius;
+ border-bottom-left-radius: @borderRadius;
}
&:not(:first-child) {
}
&:last-child{
- border-top-right-radius: @buttonBorderRadius;
- border-bottom-right-radius: @buttonBorderRadius;
+ border-top-right-radius: @borderRadius;
+ border-bottom-right-radius: @borderRadius;
}
}
@import "mediawiki.mixins";
+@import "mediawiki.ui/variables";
// Checkbox
//
// the pseudo before element of the label after the checkbox now looks like a checkbox
& + label {
+ cursor: pointer;
+
&::before {
content: '';
position: absolute;
left: 0;
display: inline-block;
- border-radius: 2px;
+ border-radius: @borderRadius;
margin-right: 18px;
width: @checkboxSize;
height: @checkboxSize;
background-color: #fff;
- cursor: pointer;
border: 1px solid grey;
}
}
}
// disabled checked boxes have a gray background
- &:disabled + label::before {
- background-color: lightgrey;
+ &:disabled + label {
+ cursor: default;
+
+ &::before {
+ background-color: lightgrey;
+ }
}
}
}
border: 1px solid @colorFieldBorder;
.box-sizing(border-box);
width: 100%;
- padding: .3em .3em .3em .6em;
+ padding: .4em .3em .2em .6em;
display: block;
vertical-align: middle;
+ border-radius: @borderRadius;
// Override user agent stylesheet properties. Instead use parent element.
color: inherit;
font-family: inherit;
// <button class="mw-ui-button mw-ui-constructive">go</button>
//
// Styleguide 1.2.
+input[type="number"],
.mw-ui-input-inline {
display: inline-block;
width: auto;
return null;
},
- /**
- * Add the appropriate prefix to the accesskey shown in the tooltip.
- *
- * If the `$nodes` parameter is given, only those nodes are updated;
- * otherwise, depending on browser support, we update either all elements
- * with accesskeys on the page or a bunch of elements which are likely to
- * have them on core skins.
- *
- * @param {Array|jQuery} [$nodes] A jQuery object, or array of nodes to update.
- */
- updateTooltipAccessKeys: function ( $nodes ) {
- if ( !$nodes ) {
- if ( document.querySelectorAll ) {
- // If we're running on a browser where we can do this efficiently,
- // just find all elements that have accesskeys. We can't use jQuery's
- // polyfill for the selector since looping over all elements on page
- // load might be too slow.
- $nodes = $( document.querySelectorAll( '[accesskey]' ) );
- } else {
- // Otherwise go through some elements likely to have accesskeys rather
- // than looping over all of them. Unfortunately this will not fully
- // work for custom skins with different HTML structures. Input, label
- // and button should be rare enough that no optimizations are needed.
- $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
- }
- } else if ( !( $nodes instanceof $ ) ) {
- $nodes = $( $nodes );
- }
-
- $nodes.updateTooltipAccessKeys();
- },
-
/**
* The content wrapper of the skin (e.g. `.mw-body`).
*
*/
mw.log.deprecate( util, 'tooltipAccessKeyRegexp', /\[(ctrl-)?(option-)?(alt-)?(shift-)?(esc-)?(.)\]$/, 'Use jquery.accessKeyLabel instead.' );
+ /**
+ * Add the appropriate prefix to the accesskey shown in the tooltip.
+ *
+ * If the `$nodes` parameter is given, only those nodes are updated;
+ * otherwise, depending on browser support, we update either all elements
+ * with accesskeys on the page or a bunch of elements which are likely to
+ * have them on core skins.
+ *
+ * @method updateTooltipAccessKeys
+ * @param {Array|jQuery} [$nodes] A jQuery object, or array of nodes to update.
+ * @deprecated since 1.24 Use the module jquery.accessKeyLabel instead.
+ */
+ mw.log.deprecate( util, 'updateTooltipAccessKeys', function ( $nodes ) {
+ if ( !$nodes ) {
+ if ( document.querySelectorAll ) {
+ // If we're running on a browser where we can do this efficiently,
+ // just find all elements that have accesskeys. We can't use jQuery's
+ // polyfill for the selector since looping over all elements on page
+ // load might be too slow.
+ $nodes = $( document.querySelectorAll( '[accesskey]' ) );
+ } else {
+ // Otherwise go through some elements likely to have accesskeys rather
+ // than looping over all of them. Unfortunately this will not fully
+ // work for custom skins with different HTML structures. Input, label
+ // and button should be rare enough that no optimizations are needed.
+ $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
+ }
+ } else if ( !( $nodes instanceof $ ) ) {
+ $nodes = $( $nodes );
+ }
+
+ $nodes.updateTooltipAccessKeys();
+ }, 'Use jquery.accessKeyLabel instead.' );
+
/**
* Add a little box at the top of the screen to inform the user of
* something, replacing any previous message.
return $page;
}
- public function provideCreatePages() {
+ public static function provideCreatePages() {
return array(
array( 'expected article being created',
'EditPageTest_testCreatePage',
<?php
+/**
+ * @group Database
+ */
+
class LinkerTest extends MediaWikiLangTestCase {
/**
$this->assertEquals( '1406833268', $timestamp->__toString() );
}
- public function provideValidTimestampDifferences() {
+ public static function provideValidTimestampDifferences() {
return array(
array( '1406833268', '1406833269', '00 00 00 01' ),
array( '1406833268', '1406833329', '00 00 01 01' ),
$this->assertEquals( $expectedLang, $langProperty->getValue( $message ) );
}
- public function provideConstructor() {
+ public static function provideConstructor() {
$langDe = Language::factory( 'de' );
$langEn = Language::factory( 'en' );
);
}
- public function provideTestParams() {
+ public static function provideTestParams() {
return array(
array( array() ),
array( array( 'foo' ), 'foo' ),
* If you want to run a the same test with a variety of data, use a data provider.
* see: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html
*/
- public function provideTitles() {
+ public static function provideTitles() {
return array(
array( 'Text', NS_MEDIA, 'Media:Text' ),
array( 'Text', null, 'Text' ),
$this->assertEquals( $title, $object->current->mTextform );
}
- public function provideNumberOfRows() {
+ public static function provideNumberOfRows() {
return array(
array( 0 ),
array( 1 ),
}
}
- public function provideValidSecureAndSplit() {
+ public static function provideValidSecureAndSplit() {
return array(
array( 'Sandbox' ),
array( 'A "B"' ),
);
}
- public function provideInvalidSecureAndSplit() {
+ public static function provideInvalidSecureAndSplit() {
return array(
array( '' ),
array( ':' ),
}
}
- /**
- * Provides test parameter values for testIsValidMoveOperation()
- */
- public function dataTestIsValidMoveOperation() {
+ public static function provideTestIsValidMoveOperation() {
return array(
array( 'Test', 'Test', 'selfmove' ),
array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
return $result;
}
- public static function provideTestIsValidMoveOperation() {
- return array(
- array( 'Test', 'Test', 'selfmove' ),
- array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
- );
- }
-
/**
* @dataProvider provideGetPageViewLanguage
* @covers Title::getPageViewLanguage
);
}
- public function provideNewFromTitleValue() {
+ public static function provideNewFromTitleValue() {
return array(
array( new TitleValue( NS_MAIN, 'Foo' ) ),
array( new TitleValue( NS_MAIN, 'Foo', 'bar' ) ),
$this->assertEquals( $value->getFragment(), $title->getFragment() );
}
- public function provideGetTitleValue() {
+ public static function provideGetTitleValue() {
return array(
array( 'Foo' ),
array( 'Foo#bar' ),
$this->assertEquals( $title->getFragment(), $value->getFragment() );
}
- public function provideGetFragment() {
+ public static function provideGetFragment() {
return array(
array( 'Foo', '' ),
array( 'Foo#bar', 'bar' ),
$this->assertEquals( $isKnown, $title->isAlwaysKnown() );
}
- public function provideIsAlwaysKnown() {
+ public static function provideIsAlwaysKnown() {
return array(
array( 'Some nonexistent page', false ),
array( 'UTPage', false ),
$this->assertEquals( $username, $object->current->mName );
}
- public function provideNumberOfRows() {
+ public static function provideNumberOfRows() {
return array(
array( 0 ),
array( 1 ),
}
}
- public function provideGetCanonicalName() {
+ public static function provideGetCanonicalName() {
return array(
array( ' trailing space ', array( 'creatable' => 'Trailing space' ), 'Trailing spaces' ),
// @todo FIXME: Maybe the createable name should be 'Talk:Username' or false to reject?
$this->assertEquals( $value, $obj->value );
}
- public function provideConstruction() {
+ public static function provideConstruction() {
return array(
array( null ),
array( '' ),
* @author Thiemo Mättig
*
* @group Action
+ * @group Database
*/
class ActionTest extends MediaWikiTestCase {
parent::setUp();
$this->setMwGlobals( array(
- 'wgArticlePath' => '/wiki/$1'
+ 'wgArticlePath' => '/wiki/$1',
+ 'wgLang' => Language::factory( 'qqx' )
) );
}
$line = $oldChangesList->recentChangesLine( $recentChange, false, 1 );
- $message = new Message( 'dellogpage' );
- $expectedLinkText = $message->inLanguage( 'en' )->text();
-
$this->assertRegExp( '/href="\/wiki\/Special:Log\/delete/', $line, 'link has href attribute' );
$this->assertRegExp( '/title="Special:Log\/delete/', $line, 'link has title attribute' );
- $this->assertRegExp( "/$expectedLinkText/", $line, 'link text' );
+ $this->assertRegExp( "/dellogpage/", $line, 'link text' );
}
public function testRecentChangesLine_DiffHistLinks() {
$line = $oldChangesList->recentChangesLine( $recentChange, false, 1 );
- $this->assertRegExp(
- "/<abbr class='newpage' title='This edit created a new page'>N<\/abbr>/",
+ $this->assertContains(
+ "<abbr class='newpage' title='(recentchanges-label-newpage)'>(newpageletter)</abbr>",
$line,
'new page flag'
);
- $this->assertRegExp(
- "/<abbr class='botedit' title='This edit was performed by a bot'>b<\/abbr>/",
+ $this->assertContains(
+ "<abbr class='botedit' title='(recentchanges-label-bot)'>(boteditletter)</abbr>",
$line,
'bot flag'
);
private function getContext() {
$user = $this->getTestUser();
$context = $this->testRecentChangesHelper->getTestContext( $user );
-
- $title = Title::newFromText( 'RecentChanges', NS_SPECIAL );
- $context->setTitle( $title );
+ $context->setLanguage( Language::factory( 'qqx' ) );
return $context;
}
$context->setUser( $user );
+ $title = Title::newFromText( 'RecentChanges', NS_SPECIAL );
+ $context->setTitle( $title );
+
return $context;
}
}
);
}
- public function provideGet() {
+ /**
+ * @covers GlobalVarConfig::has
+ */
+ public function testHas() {
+ $this->maybeStashGlobal( 'wgGlobalVarConfigTestHas' );
+ $GLOBALS['wgGlobalVarConfigTestHas'] = wfRandomString();
+ $this->maybeStashGlobal( 'wgGlobalVarConfigTestNotHas' );
+ $config = new GlobalVarConfig();
+ $this->assertTrue( $config->has( 'GlobalVarConfigTestHas' ) );
+ $this->assertFalse( $config->has( 'GlobalVarConfigTestNotHas' ) );
+ }
+
+ public static function provideGet() {
$set = array(
'wgSomething' => 'default1',
'wgFoo' => 'default2',
public function testGet( $name, $prefix, $expected ) {
$config = new GlobalVarConfig( $prefix );
if ( $expected === false ) {
- $this->setExpectedException( 'ConfigException', 'GlobalVarConfig::getWithPrefix: undefined variable:' );
+ $this->setExpectedException( 'ConfigException', 'GlobalVarConfig::get: undefined option:' );
}
$this->assertEquals( $config->get( $name ), $expected );
}
--- /dev/null
+<?php
+
+class HashConfigTest extends MediaWikiTestCase {
+
+ /**
+ * @covers HashConfig::newInstance
+ */
+ public function testNewInstance() {
+ $conf = HashConfig::newInstance();
+ $this->assertInstanceOf( 'HashConfig', $conf );
+ }
+
+ /**
+ * @covers HashConfig::__construct
+ */
+ public function testConstructor() {
+ $conf = new HashConfig();
+ $this->assertInstanceOf( 'HashConfig', $conf );
+
+ // Test passing arguments to the constructor
+ $conf2 = new HashConfig( array(
+ 'one' => '1',
+ ) );
+ $this->assertEquals( '1', $conf2->get( 'one' ) );
+ }
+
+ /**
+ * @covers HashConfig::get
+ */
+ public function testGet() {
+ $conf = new HashConfig( array(
+ 'one' => '1',
+ ));
+ $this->assertEquals( '1', $conf->get( 'one' ) );
+ $this->setExpectedException( 'ConfigException', 'HashConfig::get: undefined option' );
+ $conf->get( 'two' );
+ }
+
+ /**
+ * @covers HashConfig::has
+ */
+ public function testHas() {
+ $conf = new HashConfig( array(
+ 'one' => '1',
+ ) );
+ $this->assertTrue( $conf->has( 'one' ) );
+ $this->assertFalse( $conf->has( 'two' ) );
+ }
+
+ /**
+ * @covers HashConfig::set
+ */
+ public function testSet() {
+ $conf = new HashConfig( array(
+ 'one' => '1',
+ ) );
+ $conf->set( 'two', '2' );
+ $this->assertEquals( '2', $conf->get( 'two' ) );
+ // Check that set overwrites
+ $conf->set( 'one', '3' );
+ $this->assertEquals( '3', $conf->get( 'one' ) );
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+
+class MultiConfigTest extends MediaWikiTestCase {
+
+ /**
+ * Tests that settings are fetched in the right order
+ *
+ * @covers MultiConfig::get
+ */
+ public function testGet() {
+ $multi = new MultiConfig( array(
+ new HashConfig( array( 'foo' => 'bar' ) ),
+ new HashConfig( array( 'foo' => 'baz', 'bar' => 'foo' ) ),
+ new HashConfig( array( 'bar' => 'baz' ) ),
+ ) );
+
+ $this->assertEquals( 'bar', $multi->get( 'foo' ) );
+ $this->assertEquals( 'foo', $multi->get( 'bar' ) );
+ $this->setExpectedException( 'ConfigException', 'MultiConfig::get: undefined option:' );
+ $multi->get( 'notset' );
+ }
+
+ /**
+ * @covers MultiConfig::has
+ */
+ public function testHas() {
+ $conf = new MultiConfig( array(
+ new HashConfig( array( 'foo' => 'foo' ) ),
+ new HashConfig( array( 'something' => 'bleh' ) ),
+ new HashConfig( array( 'meh' => 'eh' ) ),
+ ) );
+
+ $this->assertTrue( $conf->has( 'foo' ) );
+ $this->assertTrue( $conf->has( 'something' ) );
+ $this->assertTrue( $conf->has( 'meh' ) );
+ $this->assertFalse( $conf->has( 'what' ) );
+ }
+}
$this->assertEquals( $expected, $obj->getJsonData() );
}
- public function provideValidConstruction() {
+ public static function provideValidConstruction() {
return array(
array( 'foo', CONTENT_MODEL_JSON, false, null ),
array( FormatJson::encode( array() ), CONTENT_MODEL_JSON, true, array() ),
$this->assertEquals( FormatJson::encode( $data, true ), $obj->beautifyJSON() );
}
- public function provideDataToEncode() {
+ public static function provideDataToEncode() {
return array(
array( array() ),
array( array( 'foo' ) ),
$obj = new JsonContent( FormatJson::encode( $data ) );
$parserOutput = $obj->getParserOutput( $this->getMockTitle(), null, null, true );
$this->assertInstanceOf( 'ParserOutput', $parserOutput );
-// var_dump( $parserOutput->getText(), "\n" );
$this->assertEquals( $expected, $parserOutput->getText() );
}
- public function provideDataAndParserText() {
+ public static function provideDataAndParserText() {
return array(
array(
array(),
$this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
}
+ public function testRedirectParserOption() {
+ $title = Title::newFromText( 'testRedirectParserOption' );
+
+ // Set up hook and its reporting variables
+ $wikitext = null;
+ $redirectTarget = null;
+ $this->mergeMwGlobalArrayValue( 'wgHooks', array(
+ 'InternalParseBeforeLinks' => array(
+ function ( &$parser, &$text, &$stripState ) use ( &$wikitext, &$redirectTarget ) {
+ $wikitext = $text;
+ $redirectTarget = $parser->getOptions()->getRedirectTarget();
+ }
+ )
+ ) );
+
+ // Test with non-redirect page
+ $wikitext = false;
+ $redirectTarget = false;
+ $content = $this->newContent( 'hello world.' );
+ $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+ $options->setRedirectTarget( $title );
+ $content->getParserOutput( $title, null, $options );
+ $this->assertEquals( 'hello world.', $wikitext,
+ 'Wikitext passed to hook was not as expected'
+ );
+ $this->assertEquals( null, $redirectTarget, 'Redirect seen in hook was not null' );
+ $this->assertEquals( $title, $options->getRedirectTarget(),
+ 'ParserOptions\' redirectTarget was changed'
+ );
+
+ // Test with a redirect page
+ $wikitext = false;
+ $redirectTarget = false;
+ $content = $this->newContent( "#REDIRECT [[TestRedirectParserOption/redir]]\nhello redirect." );
+ $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+ $content->getParserOutput( $title, null, $options );
+ $this->assertEquals( 'hello redirect.', $wikitext, 'Wikitext passed to hook was not as expected' );
+ $this->assertNotEquals( null, $redirectTarget, 'Redirect seen in hook was null' );
+ $this->assertEquals( 'TestRedirectParserOption/redir', $redirectTarget->getFullText(),
+ 'Redirect seen in hook was not the expected title'
+ );
+ $this->assertEquals( null, $options->getRedirectTarget(),
+ 'ParserOptions\' redirectTarget was changed'
+ );
+ }
+
public static function dataEquals() {
return array(
array( new WikitextContent( "hallo" ), null, false ),
$this->assertEquals( $expectedReturn, $e->runHooks( $name, $args ) );
}
- public function provideRunHooks() {
+ public static function provideRunHooks() {
return array(
array( null, null, null, null ),
array( array(), 'name', array(), null ),
$this->assertEquals( $expected, $e->isCommandLine() );
}
- public function provideIsCommandLine() {
+ public static function provideIsCommandLine() {
return array(
array( false, null ),
array( true, true ),
"The $exception_class exception should be JSON serializable, got false." );
}
- public function provideExceptionClasses() {
+ public static function provideExceptionClasses() {
return array(
array( 'Exception' ),
array( 'MWException' ),
/**
* Returns test cases: exception class, key name, gettype()
*/
- public function provideJsonSerializedKeys() {
+ public static function provideJsonSerializedKeys() {
$testCases = array();
foreach ( array( 'Exception', 'MWException' ) as $exClass ) {
$exTests = array(
* config is an array constructor argument for IPSet, and the tests are
* an array of IP => expected (boolean) result against the config dataset.
*/
- public function provider() {
+ public static function provideIPSets() {
return array(
array(
'old_list_subset',
* Validates IPSet loading and matching code
*
* @covers IPSet
- * @dataProvider provider
+ * @dataProvider provideIPSets
*/
public function testIPSet( $desc, array $cfg, array $tests ) {
$ipset = new IPSet( $cfg );
* using <https://github.com/msgpack/msgpack-php>, which includes a
* serialization function.
*/
- public function provider() {
+ public static function providePacks() {
$tests = array(
array( 'nil', null, 'c0' ),
array( 'bool', true, 'c3' ),
/**
* Verify that values are serialized correctly.
* @covers MWMessagePack::pack
- * @dataProvider provider
+ * @dataProvider providePacks
*/
public function testPack( $type, $value, $expected ) {
$actual = bin2hex( MWMessagePack::pack( $value ) );
$this->assertEquals( $expected, $actual );
}
- public function provideGetIndependentMetaArray() {
+ public static function provideGetIndependentMetaArray() {
return array(
array( 'nonanimated.gif', array(
'GIFFileComment' => array(
$this->assertEquals( $expected, $actual );
}
- public function provideGetIndependentMetaArray() {
+ public static function provideGetIndependentMetaArray() {
return array(
array( 'rgb-na-png.png', array() ),
array( 'xmp.png',
$this->assertEquals( $res, $expected );
}
- public function providerGetIndependentMetaArray() {
+ public static function providerGetIndependentMetaArray() {
return array(
array( 'Tux.svg', array(
'ObjectName' => 'Tux',
}
/** @todo document */
- public function provideAllBytes() {
+ public static function provideAllBytes() {
return array(
array( '', '' ),
array( 'x', '' ),
$this->assertEquals( $expected, $text, $msg );
}
- public function provideTestWrapping() {
+ public static function provideTestWrapping() {
$testMathML = <<<'MathML'
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
) );
}
- public function providePasswordTests() {
+ public static function providePasswordTests() {
/** @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong */
return array(
// Tests from glibc bcrypt implementation
);
}
- public function providePasswordTests() {
+ public static function providePasswordTests() {
/** @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong */
return array(
array( true, ':testLargeLayeredTop:sha512:1024:512!sha512:1024:512!sha512:1024:512!sha512:1024:512!5!vnRy+2SrSA0fHt3dwhTP5g==!AVnwfZsAQjn+gULv7FSGjA==!xvHUX3WcpkeSn1lvjWcvBg==!It+OC/N9tu+d3ByHhuB0BQ==!Tb.gqUOiD.aWktVwHM.Q/O!7CcyMfXUPky5ptyATJsR2nq3vUqtnBC', 'testPassword123' ),
*
* @return array
*/
- abstract public function providePasswordTests();
+ abstract public static function providePasswordTests();
/**
* @dataProvider providePasswordTests
) );
}
- public function providePasswordTests() {
+ public static function providePasswordTests() {
return array(
array( true, ":pbkdf2:sha1:1:20:c2FsdA==:DGDID5YfDnHzqbUkr2ASBi/gN6Y=", 'password' ),
array( true, ":pbkdf2:sha1:2:20:c2FsdA==:6mwBTcctb4zNHtkqzh1B8NjeiVc=", 'password' ),
$this->assertEquals( $expected, $module->isKnownEmpty( $context ) );
}
- public function provideIsKnownEmpty() {
+ public static function provideIsKnownEmpty() {
return array(
// No valid pages
array( array(), 'test1', true ),
--- /dev/null
+<?php
+/**
+ * Factory for handling the special page list and generating SpecialPage objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @covers SpecialPageFactory
+ * @group SpecialPage
+ */
+class SpecialPageFactoryTest extends MediaWikiTestCase {
+
+ public function newSpecialAllPages() {
+ return new SpecialAllPages();
+ }
+
+ public function specialPageProvider() {
+ return array(
+ 'class name' => array( 'SpecialAllPages', false ),
+ 'closure' => array( function() {
+ return new SpecialAllPages();
+ }, false ),
+ 'function' => array( array( $this, 'newSpecialAllPages' ), false ),
+ );
+ }
+
+ /**
+ * @dataProvider specialPageProvider
+ */
+ public function testGetPage( $spec, $shouldReuseInstance ) {
+ $this->mergeMwGlobalArrayValue( 'wgSpecialPages', array( 'testdummy' => $spec ) );
+
+ SpecialPageFactory::resetList();
+
+ $page = SpecialPageFactory::getPage( 'testdummy' );
+ $this->assertInstanceOf( 'SpecialPage', $page );
+
+ $page2 = SpecialPageFactory::getPage( 'testdummy' );
+ $this->assertEquals( $shouldReuseInstance, $page2 === $page, "Should re-use instance:" );
+
+ SpecialPageFactory::resetList();
+ }
+
+ public function testGetNames() {
+ $this->mergeMwGlobalArrayValue( 'wgSpecialPages', array( 'testdummy' => 'SpecialAllPages' ) );
+
+ SpecialPageFactory::resetList();
+ $names = SpecialPageFactory::getNames();
+ $this->assertInternalType( 'array', $names );
+ $this->assertContains( 'testdummy', $names );
+ SpecialPageFactory::resetList();
+ }
+
+ public function testResolveAlias() {
+ $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+
+ SpecialPageFactory::resetList();
+
+ list( $name, $param ) = SpecialPageFactory::resolveAlias( 'Spezialseiten/Foo' );
+ $this->assertEquals( 'Specialpages', $name );
+ $this->assertEquals( 'Foo', $param );
+
+ SpecialPageFactory::resetList();
+ }
+
+ public function testGetLocalNameFor() {
+ $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+
+ SpecialPageFactory::resetList();
+
+ $name = SpecialPageFactory::getLocalNameFor( 'Specialpages', 'Foo' );
+ $this->assertEquals( 'Spezialseiten/Foo', $name );
+
+ SpecialPageFactory::resetList();
+ }
+
+ public function testGetTitleForAlias() {
+ $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+
+ SpecialPageFactory::resetList();
+
+ $title = SpecialPageFactory::getTitleForAlias( 'Specialpages/Foo' );
+ $this->assertEquals( 'Spezialseiten/Foo', $title->getText() );
+ $this->assertEquals( NS_SPECIAL, $title->getNamespace() );
+
+ SpecialPageFactory::resetList();
+ }
+
+}
* Copyright © 2013, Siebrand Mazeland
* Copyright © 2013, Wikimedia Foundation Inc.
*
+ * @group Database
*/
class ImageListPagerTest extends MediaWikiTestCase {
<?php
+/**
+ * @group Database
+ */
+
class SpecialMIMESearchTest extends MediaWikiTestCase {
/** @var MIMESearchPage */
$this->assertEquals( $expected, $title );
}
- public function provideFindTitle() {
+ public static function provideFindTitle() {
return array(
array( null, '::Fail', 'en', 'en' ),
array( 'Page/Another', 'Page/Another/en', 'en', 'en' ),
* @covers MediaWikiPageLinkRenderer
*
* @group Title
+ * @group Database
*/
class MediaWikiPageLinkRendererTest extends MediaWikiTestCase {
return $genderCache;
}
- public function provideGetPageUrl() {
+ public static function provideGetPageUrl() {
return array(
array(
new TitleValue( NS_MAIN, 'Foo_Bar' ),
$this->assertEquals( $url, $actual );
}
- public function provideRenderHtmlLink() {
+ public static function provideRenderHtmlLink() {
return array(
array(
new TitleValue( NS_MAIN, 'Foo_Bar' ),
$this->assertRegExp( $pattern, $actual );
}
- public function provideRenderWikitextLink() {
+ public static function provideRenderWikitextLink() {
return array(
array(
new TitleValue( NS_MAIN, 'Foo_Bar' ),
return new MediaWikiTitleCodec( $lang, $gender );
}
- public function provideFormat() {
+ public static function provideFormat() {
return array(
array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ),
$this->assertEquals( $normalized, $actual2, 'normalized after round trip' );
}
- public function provideGetText() {
+ public static function provideGetText() {
return array(
array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'Hansi Maier' ),
$this->assertEquals( $expected, $actual );
}
- public function provideGetPrefixedText() {
+ public static function provideGetPrefixedText() {
return array(
array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier' ),
$this->assertEquals( $expected, $actual );
}
- public function provideGetFullText() {
+ public static function provideGetFullText() {
return array(
array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ),
$this->assertEquals( $expected, $actual );
}
- public function provideParseTitle() {
+ public static function provideParseTitle() {
//TODO: test capitalization and trimming
//TODO: test unicode normalization
$this->assertEquals( $title, $actual );
}
- public function provideParseTitle_invalid() {
+ public static function provideParseTitle_invalid() {
//TODO: test unicode errors
return array(
$codec->parseTitle( $text, NS_MAIN );
}
- public function provideGetNamespaceName() {
+ public static function provideGetNamespaceName() {
return array(
array( NS_MAIN, 'Foo', 'en', '' ),
array( NS_USER, 'Foo', 'en', 'User' ),
$stash->removeFile( $file->getFileKey() );
}
- public function provideInvalidRequests() {
+ public static function provideInvalidRequests() {
return array(
'Check failure on bad wpFileKey' =>
array( new FauxRequest( array( 'wpFileKey' => 'foo' ) ) ),
$this->assertFalse( UploadFromStash::isValidRequest( $request ) );
}
- public function provideValidRequests() {
+ public static function provideValidRequests() {
return array(
'Check good wpFileKey' =>
array( new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) ) ),