* mw.Api has a new option, useUS, to use U+001F (Unit Separator) when
appropriate for sending multi-valued parameters. This defaults to true when
the mw.Api instance seems to be for the local wiki.
+* After a client performs an action which alters a database that has replica databases,
+ MediaWiki will wait for the replica databases to synchronize with the master database
+ while it renders the HTML output. However, if the output is a redirect, it will instead
+ alter the redirect URL to include a ?cpPosTime parameter that triggers the database
+ synchronization when the URL is followed by the client.
=== External library changes in 1.28 ===
* OOjs UI PHP widgets constructed with the `'infusable' => true` config option
will no longer be automatically infused. You should call `OO.ui.infuse()`
on them yourself from your JavaScript code.
+* parserTests.php has moved to tests/parser/parserTests.php
+* The command line options specific to parser tests have been removed from
+ phpunit.php: --regex and --keep-uploads. Instead of --regex, use --filter.
+ Instead of --keep-uploads, use the same option to parserTests.php, but you
+ must specify a directory with --upload-dir.
+* The 'jquery.arrowSteps' ResourceLoader module was removed.
== Compatibility ==
"ext-xml": "*",
"liuggio/statsd-php-client": "1.0.18",
"mediawiki/at-ease": "1.1.0",
- "oojs/oojs-ui": "0.17.8",
+ "oojs/oojs-ui": "0.17.9",
"oyejorge/less.php": "1.7.0.10",
"php": ">=5.5.9",
"psr/log": "1.0.0",
*/
$wgTranscludeCacheExpiry = 3600;
+/**
+ * Enable the magic links feature of automatically turning ISBN xxx,
+ * PMID xxx, RFC xxx into links
+ *
+ * @since 1.28
+ */
+$wgEnableMagicLinks = [
+ 'ISBN' => true,
+ 'PMID' => true,
+ 'RFC' => true
+];
+
/** @} */ # end of parser settings }
/************************************************************************//**
'POST' => [
'readQueryTime' => 5,
'writeQueryTime' => 1,
- 'maxAffected' => 500
+ 'maxAffected' => 1000
],
'POST-nonwrite' => [
'masterConns' => 0,
'PostSend' => [
'readQueryTime' => 5,
'writeQueryTime' => 1,
- 'maxAffected' => 500
+ 'maxAffected' => 1000
],
// Background job runner
'JobRunner' => [
// May be overridden by revision.
$this->contentFormat = $request->getText( 'format', $this->contentFormat );
- if ( !ContentHandler::getForModelID( $this->contentModel )
- ->isSupportedFormat( $this->contentFormat )
- ) {
+ try {
+ $handler = ContentHandler::getForModelID( $this->contentModel );
+ } catch ( MWUnknownContentModelException $e ) {
+ throw new ErrorPageError(
+ 'editpage-invalidcontentmodel-title',
+ 'editpage-invalidcontentmodel-text',
+ [ $this->contentModel ]
+ );
+ }
+
+ if ( !$handler->isSupportedFormat( $this->contentFormat ) ) {
throw new ErrorPageError(
'editpage-notsupportedcontentformat-title',
'editpage-notsupportedcontentformat-text',
* subclasses may reorganize the form.
* Note that you do not need to worry about the label's for=, it will be
* inferred by the id given to the input. You can remove them both by
- * passing array( 'id' => false ) to $userInputAttrs.
+ * passing [ 'id' => false ] to $userInputAttrs.
*
* @param string $summary The value of the summary input
* @param string $labelText The html to place inside the label
* @param array $inputAttrs Array of attrs to use on the input
* @param array $spanLabelAttrs Array of attrs to use on the span inside the label
*
- * @return array An array in the format array( $label, $input )
+ * @return array An array in the format [ $label, $input ]
*/
function getSummaryInput( $summary = "", $labelText = null,
$inputAttrs = null, $spanLabelAttrs = null
*
* ;:@$!*(),/~
*
- * However, IIS7 redirects fail when the url contains a colon (Bug 22709),
+ * However, IIS7 redirects fail when the url contains a colon (see T24709),
* so no fancy : for IIS7.
*
* %2F in the page titles seems to fatally break for some reason.
* This is the basic structure used (brackets contain keys for $urlParts):
* [scheme][delimiter][user]:[pass]@[host]:[port][path]?[query]#[fragment]
*
- * @todo Need to integrate this into wfExpandUrl (bug 32168)
+ * @todo Need to integrate this into wfExpandUrl (see T34168)
*
* @since 1.19
* @param array $urlParts URL parts, as output from wfParseUrl
* '/a/./b/../c/' becomes '/a/c/'. For details on the algorithm, please see
* RFC3986 section 5.2.4.
*
- * @todo Need to integrate this into wfExpandUrl (bug 32168)
+ * @todo Need to integrate this into wfExpandUrl (see T34168)
*
* @param string $urlPath URL path, potentially containing dot-segments
* @return string URL path with all dot-segments removed
return false;
}
- /* Provide an empty host for eg. file:/// urls (see bug 28627) */
+ /* Provide an empty host for eg. file:/// urls (see T30627) */
if ( !isset( $bits['host'] ) ) {
$bits['host'] = '';
- // bug 45069
+ // See T47069
if ( isset( $bits['path'] ) ) {
/* parse_url loses the third / for file:///c:/ urls (but not on variants) */
if ( substr( $bits['path'], 0, 1 ) !== '/' ) {
* @return string
*/
function wfEscapeWikiText( $text ) {
+ global $wgEnableMagicLinks;
static $repl = null, $repl2 = null;
if ( $repl === null ) {
$repl = [
'__' => '__', '://' => '://',
];
+ $magicLinks = array_keys( array_filter( $wgEnableMagicLinks ) );
// We have to catch everything "\s" matches in PCRE
- foreach ( [ 'ISBN', 'RFC', 'PMID' ] as $magic ) {
+ foreach ( $magicLinks as $magic ) {
$repl["$magic "] = "$magic ";
$repl["$magic\t"] = "$magic	";
$repl["$magic\r"] = "$magic ";
// Refs:
// * http://web.archive.org/web/20020708081031/http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html
// * http://technet.microsoft.com/en-us/library/cc723564.aspx
- // * Bug #13518
+ // * T15518
// * CR r63214
// Double the backslashes before any double quotes. Escape the double quotes.
// @codingStandardsIgnoreEnd
* @throws MWException If not in testing mode.
*/
public static function clear( $name ) {
- if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
+ if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
throw new MWException( 'Cannot reset hooks in operation.' );
}
*
* @par Example:
* @code
- * $magicWords = array();
+ * $magicWords = [];
*
- * $magicWords['en'] = array(
- * 'magicwordkey' => array( 0, 'case_insensitive_magic_word' ),
- * 'magicwordkey2' => array( 1, 'CASE_sensitive_magic_word2' ),
- * );
+ * $magicWords['en'] = [
+ * 'magicwordkey' => [ 0, 'case_insensitive_magic_word' ],
+ * 'magicwordkey2' => [ 1, 'CASE_sensitive_magic_word2' ],
+ * ];
* @endcode
*
* For magic words which are also Parser variables, add a MagicWordwgVariableIDs
/**
* @see MediaWiki::preOutputCommit()
+ * @param callable $postCommitWork [default: null]
* @since 1.26
*/
- public function doPreOutputCommit() {
- self::preOutputCommit( $this->context );
+ public function doPreOutputCommit( callable $postCommitWork = null ) {
+ self::preOutputCommit( $this->context, $postCommitWork );
}
/**
* the user can receive a response (in case commit fails)
*
* @param IContextSource $context
+ * @param callable $postCommitWork [default: null]
* @since 1.27
*/
- public static function preOutputCommit( IContextSource $context ) {
+ public static function preOutputCommit(
+ IContextSource $context, callable $postCommitWork = null
+ ) {
// Either all DBs should commit or none
ignore_user_abort( true );
$config = $context->getConfig();
-
+ $request = $context->getRequest();
+ $output = $context->getOutput();
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+
// Commit all changes
$lbFactory->commitMasterChanges(
__METHOD__,
// Abort if any transaction was too big
[ 'maxWriteDuration' => $config->get( 'MaxUserDBWriteDuration' ) ]
);
+ wfDebug( __METHOD__ . ': primary transaction round committed' );
+ // Run updates that need to block the user or affect output (this is the last chance)
DeferredUpdates::doUpdates( 'enqueue', DeferredUpdates::PRESEND );
wfDebug( __METHOD__ . ': pre-send deferred updates completed' );
- // Record ChronologyProtector positions
- $lbFactory->shutdown();
- wfDebug( __METHOD__ . ': all transactions committed' );
+ // Decide when clients block on ChronologyProtector DB position writes
+ if (
+ $request->wasPosted() &&
+ $output->getRedirect() &&
+ $lbFactory->hasOrMadeRecentMasterChanges( INF ) &&
+ self::isWikiClusterURL( $output->getRedirect(), $context )
+ ) {
+ // OutputPage::output() will be fast; $postCommitWork will not be useful for
+ // masking the latency of syncing DB positions accross all datacenters synchronously.
+ // Instead, make use of the RTT time of the client follow redirects.
+ $flags = $lbFactory::SHUTDOWN_CHRONPROT_ASYNC;
+ // Client's next request should see 1+ positions with this DBMasterPos::asOf() time
+ $safeUrl = $lbFactory->appendPreShutdownTimeAsQuery(
+ $output->getRedirect(),
+ microtime( true )
+ );
+ $output->redirect( $safeUrl );
+ } else {
+ // OutputPage::output() is fairly slow; run it in $postCommitWork to mask
+ // the latency of syncing DB positions accross all datacenters synchronously
+ $flags = $lbFactory::SHUTDOWN_CHRONPROT_SYNC;
+ }
+ // Record ChronologyProtector positions for DBs affected in this request at this point
+ $lbFactory->shutdown( $flags, $postCommitWork );
+ wfDebug( __METHOD__ . ': LBFactory shutdown completed' );
// Set a cookie to tell all CDN edge nodes to "stick" the user to the DC that handles this
// POST request (e.g. the "master" data center). Also have the user briefly bypass CDN so
// ChronologyProtector works for cacheable URLs.
- $request = $context->getRequest();
if ( $request->wasPosted() && $lbFactory->hasOrMadeRecentMasterChanges() ) {
$expires = time() + $config->get( 'DataCenterUpdateStickTTL' );
$options = [ 'prefix' => '' ];
// also intimately related to the value of $wgCdnReboundPurgeDelay.
if ( $lbFactory->laggedReplicaUsed() ) {
$maxAge = $config->get( 'CdnMaxageLagged' );
- $context->getOutput()->lowerCdnMaxage( $maxAge );
+ $output->lowerCdnMaxage( $maxAge );
$request->response()->header( "X-Database-Lagged: true" );
wfDebugLog( 'replication', "Lagged DB used; CDN cache TTL limited to $maxAge seconds" );
}
// Avoid long-term cache pollution due to message cache rebuild timeouts (T133069)
if ( MessageCache::singleton()->isDisabled() ) {
$maxAge = $config->get( 'CdnMaxageSubstitute' );
- $context->getOutput()->lowerCdnMaxage( $maxAge );
+ $output->lowerCdnMaxage( $maxAge );
$request->response()->header( "X-Response-Substitute: true" );
}
}
+ /**
+ * @param string $url
+ * @param IContextSource $context
+ * @return bool Whether $url is to something on this wiki farm
+ */
+ private function isWikiClusterURL( $url, IContextSource $context ) {
+ static $relevantKeys = [ 'host' => true, 'port' => true ];
+
+ $infoCandidate = wfParseUrl( $url );
+ if ( $infoCandidate === false ) {
+ return false;
+ }
+
+ $infoCandidate = array_intersect_key( $infoCandidate, $relevantKeys );
+ $clusterHosts = array_merge(
+ // Local wiki host (the most common case)
+ [ $context->getConfig()->get( 'CanonicalServer' ) ],
+ // Any local/remote wiki virtual hosts for this wiki farm
+ $context->getConfig()->get( 'LocalVirtualHosts' )
+ );
+
+ foreach ( $clusterHosts as $clusterHost ) {
+ $parseUrl = wfParseUrl( $clusterHost );
+ if ( !$parseUrl ) {
+ continue;
+ }
+ $infoHost = array_intersect_key( $parseUrl, $relevantKeys );
+ if ( $infoCandidate === $infoHost ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* This function does work that can be done *after* the
* user gets the HTTP response so they don't block on it
// Show visible profiling data if enabled (which cannot be post-send)
Profiler::instance()->logDataPageOutputOnly();
- $that = $this;
- $callback = function () use ( $that, $mode ) {
+ $callback = function () use ( $mode ) {
try {
- $that->restInPeace( $mode );
+ $this->restInPeace( $mode );
} catch ( Exception $e ) {
MWExceptionHandler::handleException( $e );
}
private function main() {
global $wgTitle;
+ $output = $this->context->getOutput();
$request = $this->context->getRequest();
// Send Ajax requests to the Ajax dispatcher.
$dispatcher = new AjaxDispatcher( $this->config );
$dispatcher->performAction( $this->context->getUser() );
+
return;
}
// Setup dummy Title, otherwise OutputPage::redirect will fail
$title = Title::newFromText( 'REDIR', NS_MAIN );
$this->context->setTitle( $title );
- $output = $this->context->getOutput();
// Since we only do this redir to change proto, always send a vary header
$output->addVaryHeader( 'X-Forwarded-Proto' );
$output->redirect( $redirUrl );
$output->output();
+
return;
}
}
if ( $cache->isCacheGood( /* Assume up to date */ ) ) {
// Check incoming headers to see if client has this cached
$timestamp = $cache->cacheTimestamp();
- if ( !$this->context->getOutput()->checkLastModified( $timestamp ) ) {
+ if ( !$output->checkLastModified( $timestamp ) ) {
$cache->loadFromFileCache( $this->context );
}
// Do any stats increment/watchlist stuff
// Assume we're viewing the latest revision (this should always be the case with file cache)
$this->context->getWikiPage()->doViewUpdates( $this->context->getUser() );
// Tell OutputPage that output is taken care of
- $this->context->getOutput()->disable();
+ $output->disable();
+
return;
}
}
// Actually do the work of the request and build up any output
$this->performRequest();
+ // GUI-ify and stash the page output in MediaWiki::doPreOutputCommit() while
+ // ChronologyProtector synchronizes DB positions or slaves accross all datacenters.
+ $buffer = null;
+ $outputWork = function () use ( $output, &$buffer ) {
+ if ( $buffer === null ) {
+ $buffer = $output->output( true );
+ }
+
+ return $buffer;
+ };
+
// Now commit any transactions, so that unreported errors after
// output() don't roll back the whole DB transaction and so that
// we avoid having both success and error text in the response
- $this->doPreOutputCommit();
+ $this->doPreOutputCommit( $outputWork );
- // Output everything!
- $this->context->getOutput()->output();
+ // Now send the actual output
+ print $outputWork();
}
/**
/**
* Finally, all the text has been munged and accumulated into
* the object, let's actually output it:
+ *
+ * @param bool $return Set to true to get the result as a string rather than sending it
+ * @return string|null
+ * @throws Exception
+ * @throws FatalError
+ * @throws MWException
*/
- public function output() {
+ public function output( $return = false ) {
if ( $this->mDoNothing ) {
- return;
+ return $return ? '' : null;
}
$response = $this->getRequest()->response();
}
}
- return;
+ return $return ? '' : null;
} elseif ( $this->mStatusCode ) {
$response->statusHeader( $this->mStatusCode );
}
$this->sendCacheControl();
- ob_end_flush();
-
+ if ( $return ) {
+ return ob_get_clean();
+ } else {
+ ob_end_flush();
+ return null;
+ }
}
/**
*
* $router->add( "/wiki/$1" );
* - Matches /wiki/Foo style urls and extracts the title
- * $router->add( array( 'edit' => "/edit/$key" ), array( 'action' => '$key' ) );
+ * $router->add( [ 'edit' => "/edit/$key" ], [ 'action' => '$key' ] );
* - Matches /edit/Foo style urls and sets action=edit
* $router->add( '/$2/$1',
- * array( 'variant' => '$2' ),
- * array( '$2' => array( 'zh-hant', 'zh-hans' )
+ * [ 'variant' => '$2' ],
+ * [ '$2' => [ 'zh-hant', 'zh-hans' ] ]
* );
* - Matches /zh-hant/Foo or /zh-hans/Foo
- * $router->addStrict( "/foo/Bar", array( 'title' => 'Baz' ) );
+ * $router->addStrict( "/foo/Bar", [ 'title' => 'Baz' ] );
* - Matches /foo/Bar explicitly and uses "Baz" as the title
- * $router->add( '/help/$1', array( 'title' => 'Help:$1' ) );
+ * $router->add( '/help/$1', [ 'title' => 'Help:$1' ] );
* - Matches /help/Foo with "Help:Foo" as the title
- * $router->add( '/$1', array( 'foo' => array( 'value' => 'bar$2' ) );
+ * $router->add( '/$1', [ 'foo' => [ 'value' => 'bar$2' ] ] );
* - Matches /Foo and sets 'foo' to 'bar$2' without $2 being replaced
- * $router->add( '/$1', array( 'data:foo' => 'bar' ), array( 'callback' => 'functionname' ) );
+ * $router->add( '/$1', [ 'data:foo' => 'bar' ], [ 'callback' => 'functionname' ] );
* - Matches /Foo, adds the key 'foo' with the value 'bar' to the data array
* and calls functionname( &$matches, $data );
*
* - The default behavior is equivalent to `array( 'title' => '$1' )`,
* if you don't want the title parameter you can explicitly use `array( 'title' => false )`
* - You can specify a value that won't have replacements in it
- * using `'foo' => array( 'value' => 'bar' );`
+ * using `'foo' => [ 'value' => 'bar' ];`
*
* Options:
* - The option keys $1, $2, etc... can be specified to restrict the possible values
wfDebugLog( 'caches',
'cluster: ' . get_class( $wgMemc ) .
- ', WAN: ' . $wgMainWANCache .
+ ', WAN: ' . ( $wgMainWANCache === CACHE_NONE ? 'CACHE_NONE' : $wgMainWANCache ) .
', stash: ' . $wgMainStash .
', message: ' . get_class( $messageMemc ) .
', parser: ' . get_class( $parserMemc ) .
* @return int
*/
public function getInt( $name, $default = 0 ) {
- return intval( $this->getVal( $name, $default ) );
+ return intval( $this->getRawVal( $name, $default ) );
}
/**
* @return int|null
*/
public function getIntOrNull( $name ) {
- $val = $this->getVal( $name );
+ $val = $this->getRawVal( $name );
return is_numeric( $val )
? intval( $val )
: null;
* @return float
*/
public function getFloat( $name, $default = 0.0 ) {
- return floatval( $this->getVal( $name, $default ) );
+ return floatval( $this->getRawVal( $name, $default ) );
}
/**
* @return bool
*/
public function getBool( $name, $default = false ) {
- return (bool)$this->getVal( $name, $default );
+ return (bool)$this->getRawVal( $name, $default );
}
/**
* @return bool
*/
public function getFuzzyBool( $name, $default = false ) {
- return $this->getBool( $name, $default ) && strcasecmp( $this->getVal( $name ), 'false' ) !== 0;
+ return $this->getBool( $name, $default )
+ && strcasecmp( $this->getRawVal( $name ), 'false' ) !== 0;
}
/**
public function getCheck( $name ) {
# Checkboxes and buttons are only present when clicked
# Presence connotes truth, absence false
- return $this->getVal( $name, null ) !== null;
+ return $this->getRawVal( $name, null ) !== null;
}
/**
}
public function onSubmit( $data ) {
- return $this->page->doPurge();
+ return $this->page->doPurge( WikiPage::PURGE_ALL );
}
public function show() {
$touched = null;
}
+ // If a page was purged on HTTP GET, relect that timestamp to avoid sending 304s
+ $touched = max( $touched, $this->page->getLastPurgeTimestamp() );
+
// Send HTTP 304 if the IMS matches or otherwise set expiry/last-modified headers
if ( $touched && $this->getOutput()->checkLastModified( $touched ) ) {
wfDebug( __METHOD__ . ": done 304\n" );
}
// Try bot passwords
- if ( $authRes === false && $this->getConfig()->get( 'EnableBotPasswords' ) &&
- strpos( $params['name'], BotPassword::getSeparator() ) !== false
+ if (
+ $authRes === false && $this->getConfig()->get( 'EnableBotPasswords' ) &&
+ ( $botLoginData = BotPassword::canonicalizeLoginData( $params['name'], $params['password'] ) )
) {
$status = BotPassword::login(
- $params['name'], $params['password'], $this->getRequest()
+ $botLoginData[0], $botLoginData[1], $this->getRequest()
);
if ( $status->isOK() ) {
$session = $status->getValue();
$authRes = 'Success';
$loginType = 'BotPassword';
- } else {
+ } elseif ( !$botLoginData[2] ) {
$authRes = 'Failed';
$message = $status->getMessage();
LoggerFactory::getInstance( 'authentication' )->info(
ApiQueryBase::addTitleInfo( $r, $title );
$page = WikiPage::factory( $title );
if ( !$user->pingLimiter( 'purge' ) ) {
- $page->doPurge(); // Directly purge and skip the UI part of purge().
+ $flags = WikiPage::PURGE_ALL;
+ if ( !$this->getRequest()->wasPosted() ) {
+ $flags ^= WikiPage::PURGE_GLOBAL_PCACHE; // skip DB_MASTER write
+ }
+ // Directly purge and skip the UI part of purge()
+ $page->doPurge( $flags );
$r['purged'] = true;
} else {
$error = $this->parseMsg( [ 'actionthrottledtext' ] );
$limit = $params['limit'];
$result = $this->getResult();
- $extensionDefinedTags = array_fill_keys( ChangeTags::listExtensionDefinedTags(), 0 );
+ $softwareDefinedTags = array_fill_keys( ChangeTags::listSoftwareDefinedTags(), 0 );
$explicitlyDefinedTags = array_fill_keys( ChangeTags::listExplicitlyDefinedTags(), 0 );
- $extensionActivatedTags = array_fill_keys( ChangeTags::listExtensionActivatedTags(), 0 );
+ $softwareActivatedTags = array_fill_keys( ChangeTags::listSoftwareActivatedTags(), 0 );
- $definedTags = array_merge( $extensionDefinedTags, $explicitlyDefinedTags );
+ $definedTags = array_merge( $softwareDefinedTags, $explicitlyDefinedTags );
# Fetch defined tags that aren't past the continuation
if ( $params['continue'] !== null ) {
$tag['hitcount'] = $hitcount;
}
- $isExtension = isset( $extensionDefinedTags[$tagName] );
+ $isSoftware = isset( $softwareDefinedTags[$tagName] );
$isExplicit = isset( $explicitlyDefinedTags[$tagName] );
if ( $fld_defined ) {
- $tag['defined'] = $isExtension || $isExplicit;
+ $tag['defined'] = $isSoftware || $isExplicit;
}
if ( $fld_source ) {
$tag['source'] = [];
- if ( $isExtension ) {
+ if ( $isSoftware ) {
+ // TODO: Can we change this to 'software'?
$tag['source'][] = 'extension';
}
if ( $isExplicit ) {
}
if ( $fld_active ) {
- $tag['active'] = $isExplicit || isset( $extensionActivatedTags[$tagName] );
+ $tag['active'] = $isExplicit || isset( $softwareActivatedTags[$tagName] );
}
$fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $tag );
"apihelp-expandtemplates-paramvalue-prop-volatile": "Se l'output o segge volatile e o no 'agge da ese riadoeuviou atr'onde a l'interno da paggina.",
"apihelp-expandtemplates-paramvalue-prop-ttl": "O tempo mascimo doppo o quæ e memoizaçioin tempoannie (cache) do risultou dovieivan ese invalidæ.",
"apihelp-feedcontributions-param-feedformat": "O formato do feed.",
+ "apihelp-feedrecentchanges-param-feedformat": "O formato do feed.",
+ "apihelp-feedrecentchanges-param-namespace": "Namespace a-o quæ limitâ i risultæ.",
+ "apihelp-feedrecentchanges-param-associated": "Inciodi namespace associou (discuscion ò prinçipâ)",
+ "apihelp-feedrecentchanges-param-days": "Intervallo de giorni pe-i quæ limitâ i risultæ.",
+ "apihelp-feedrecentchanges-param-limit": "Nummero mascimo di risultæ da restituî.",
+ "apihelp-feedrecentchanges-param-from": "Mostra i cangiamenti da alloa.",
+ "apihelp-feedrecentchanges-param-hideminor": "Ascondi e modiffiche menoî.",
+ "apihelp-feedrecentchanges-param-hidebots": "Ascondi e modiffiche fæte da di bot.",
+ "apihelp-feedrecentchanges-param-hideanons": "Ascondi e modiffiche fæte da di utenti anonnimi.",
+ "apihelp-feedrecentchanges-param-hideliu": "Ascondi e modiffiche fæte da-i utenti registræ.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Ascondi e modiffiche veificæ.",
+ "apihelp-feedrecentchanges-param-hidemyself": "O l'asconde e modiffiche fæte da l'utente attoale.",
+ "apihelp-feedrecentchanges-param-hidecategorization": "Ascondi e variaçioin d'apartegninça a-e categorie.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filtra pe etichetta.",
+ "apihelp-feedrecentchanges-param-target": "Mostra solo e modifiche a-e paggine collegæ da questa paggina.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Fanni védde sôlo i cangiaménti a-e pàggine colegæ a-a quella speçificâ",
+ "apihelp-feedrecentchanges-param-categories": "Mostra solo e variaçioin in sce-e paggine de tutte queste categorie.",
+ "apihelp-feedrecentchanges-param-categories_any": "Mostra invece solo e variaçioin in sce-e paggine inte 'na qualonque categoria.",
"apihelp-feedrecentchanges-example-simple": "Mostra i urtime modiffiche.",
"apihelp-feedrecentchanges-example-30days": "Mostra e modifiche di urtimi 30 giorni.",
"apihelp-feedwatchlist-param-feedformat": "O formato do feed.",
"apihelp-options-example-reset": "Reimposta tutte e preferençe.",
"apihelp-paraminfo-description": "Otegni de informaçioin in scî modduli API.",
"apihelp-paraminfo-param-helpformat": "Formato de stringhe d'agiutto.",
- "apihelp-parse-param-summary": "Ogetto da analizâ."
+ "apihelp-parse-param-summary": "Ogetto da analizâ.",
+ "apihelp-query+allcategories-param-prop": "Quæ propietæ otegnî:",
+ "apihelp-query+allcategories-paramvalue-prop-size": "Azonzi o nummero de paggine inta categoria.",
+ "apihelp-query+allcategories-paramvalue-prop-hidden": "Etichetta e categorie che son ascose con <code>__HIDDENCAT__</code>.",
+ "apihelp-query+allcategories-example-size": "Elenca e categorie con de informaçioin in sciô numero de paggine in ciascun-a.",
+ "apihelp-query+alldeletedrevisions-description": "Elenca tutte e verscioin scassæ da 'n utente ò inte 'n namespace.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "O poeu ese doeuviou solo con <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "O no poeu ese doeuviou con <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-param-start": "O timestamp da-o quæ començâ l'elenco.",
+ "apihelp-query+alldeletedrevisions-param-end": "O timestamp a-o quæ interrompî l'elenco.",
+ "apihelp-query+alldeletedrevisions-param-from": "Comença l'elenco a questo tittolo.",
+ "apihelp-query+alldeletedrevisions-param-to": "Interrompi l'elenco a questo titolo.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Riçerca pe tutti i titoli de pagine che començan con questo valô.",
+ "apihelp-query+alldeletedrevisions-param-user": "Elenca solo e verscioin de questo utente.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "No elencâ e verscioin de questo utente.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Elenca solo e paggine inte questo namespace.",
+ "apihelp-query+alldeletedrevisions-example-user": "Elenca i urtimi 50 contributi scassæ de l'utente <kbd>Example</kbd>.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Elenca e primme 50 verscioin scassæ into namespace prinçipâ.",
+ "apihelp-query+allfileusages-param-from": "O titolo do file da-o quæ començâ l'elenco.",
+ "apihelp-query+allfileusages-param-to": "O tittolo do file a-o quæ interrompî l'elenco.",
+ "apihelp-query+allfileusages-param-prefix": "Riçerca pe tutti i titoli di file che començan con questo valô.",
+ "apihelp-query+allfileusages-paramvalue-prop-title": "O l'azonze o tittolo do file.",
+ "apihelp-query+allfileusages-param-limit": "Quanti elementi totali restitoî.",
+ "apihelp-query+allfileusages-param-dir": "A direçion inta quæ elencâ.",
+ "apihelp-query+allfileusages-example-generator": "Otegni e paggine contegninte i file.",
+ "apihelp-query+allimages-param-sort": "Propietæ d'amerçamento.",
+ "apihelp-query+allimages-param-dir": "A direçion inta quæ elencâ.",
+ "apihelp-query+allimages-param-from": "O titolo de l'inmagine da-a quæ començâ l'elenco. O poeu ese doeuviou solo con $1sort=name."
}
"apihelp-managetags-param-reason": "Opcjonalny powód utworzenia, usunięcia, włączenia lub wyłączenia znacznika.",
"apihelp-managetags-param-ignorewarnings": "Czy zignorować ostrzeżenia, które pojawiają się w trakcie operacji.",
"apihelp-mergehistory-description": "Łączenie historii edycji.",
+ "apihelp-mergehistory-param-reason": "Powód łączenia historii.",
"apihelp-move-description": "Przenieś stronę.",
"apihelp-move-param-reason": "Powód zmiany nazwy.",
"apihelp-move-param-movetalk": "Zmień nazwę strony dyskusji, jeśli istnieje.",
"Iniquity",
"Лилиә",
"Айсар",
- "Гизатуллина"
+ "Гизатуллина",
+ "MaxSem"
]
},
"apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Документация]]\n* [[mw:API:FAQ|ЧаВО]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Почтовая рассылка]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Новости API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Ошибки и запросы]\n</div>\n<strong>Статус:</strong> Все отображаемые на этой странице функции должны работать, однако API находится в статусе активной разработки и может измениться в любой момент. Подпишитесь на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ почтовую рассылку mediawiki-api-announce], чтобы быть в курсе обновлений.\n\n<strong>Ошибочные запросы:</strong> Если API получает запрос с ошибкой, вернётся заголовок HTTP с ключом «MediaWiki-API-Error», после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:API:Errors_and_warnings|API: Ошибки и предупреждения]].\n\n<strong>Тестирование:</strong> для удобства тестирования API-запросов, см. [[Special:ApiSandbox]].",
"apihelp-main-param-requestid": "Любое заданное здесь значение будет включено в ответ. Может быть использовано для различения запросов.",
"apihelp-main-param-servedby": "Включить в результаты имя хоста, обработавшего запрос.",
"apihelp-main-param-curtimestamp": "Включить в результаты временную метку.",
- "apihelp-main-param-origin": "При обращении к API, используя кросс-доменный AJAX-запрос (CORS), задайте параметру значение исходного домена. Он должен быть включён в любой предварительный запрос и таким образом должен быть частью URI-запроса (не тела POST).\n\nДля аутентифицированных запросов он должен точно соответствовать одному из источников в заголовке <code>Origin<code>, так что он должен быть задан наподобие <kbd>https://ru.wikipedia.org</kbd> или <kbd>https://meta.wikimedia.org</kbd>. Если параметр не соответствует заголовку <code>Origin<code>, будет возвращён ответ с кодом ошибки 403. Если параметр соответствует заголовку <code>Origin</code>, и источник находится в белом списке, будут установлены заголовки <code>Access-Control-Allow-Origin</code> и <code>Access-Control-Allow-Credentials</code>.\n\nДля неаутентифицированных запросов укажите значение <kbd>*</kbd>. Это приведёт к установке заголовка <code>Access-Control-Allow-Origin</code> заголовка должен быть установлен, но <code>Access-Control-Allow-Credentials</code> примет значение <code>false</code> и все пользовательские данные будут ограничены.",
+ "apihelp-main-param-origin": "При обращении к API, используя кросс-доменный AJAX-запрос (CORS), задайте параметру значение исходного домена. Он должен быть включён в любой предварительный запрос и таким образом должен быть частью URI-запроса (не тела POST).\n\nДля аутентифицированных запросов он должен точно соответствовать одному из источников в заголовке <code>Origin</code>, так что он должен быть задан наподобие <kbd>https://ru.wikipedia.org</kbd> или <kbd>https://meta.wikimedia.org</kbd>. Если параметр не соответствует заголовку <code>Origin</code>, будет возвращён ответ с кодом ошибки 403. Если параметр соответствует заголовку <code>Origin</code>, и источник находится в белом списке, будут установлены заголовки <code>Access-Control-Allow-Origin</code> и <code>Access-Control-Allow-Credentials</code>.\n\nДля неаутентифицированных запросов укажите значение <kbd>*</kbd>. Это приведёт к установке заголовка <code>Access-Control-Allow-Origin</code> заголовка должен быть установлен, но <code>Access-Control-Allow-Credentials</code> примет значение <code>false</code> и все пользовательские данные будут ограничены.",
"apihelp-block-description": "Блокировка участника.",
"apihelp-block-param-user": "Имя участника, IP-адрес или диапазон IP-адресов, которые вы хотите заблокировать.",
"apihelp-block-param-reason": "Причина блокировки.",
$user = User::newFromName( $res->username, 'usable' );
if ( !$user ) {
+ $provider = $this->getAuthenticationProvider( $state['primary'] );
throw new \DomainException(
get_class( $provider ) . " returned an invalid username: {$res->username}"
);
$this->logger->info( 'Login for {user} succeeded', [
'user' => $user->getName(),
] );
+ /** @var RememberMeAuthenticationRequest $req */
$req = AuthenticationRequest::getRequestByClass(
$beginReqs, RememberMeAuthenticationRequest::class
);
'creator' => $creator->getName(),
] );
$status = $user->addToDatabase();
- if ( !$status->isOk() ) {
+ if ( !$status->isOK() ) {
// @codeCoverageIgnoreStart
$ret = AuthenticationResponse::newFail( $status->getMessage() );
$this->callMethodOnProviders( 7, 'postAccountCreation', [ $user, $creator, $ret ] );
);
$logEntry->setPerformer( $isAnon ? $user : $creator );
$logEntry->setTarget( $user->getUserPage() );
+ /** @var CreationReasonAuthenticationRequest $req */
$req = AuthenticationRequest::getRequestByClass(
$state['reqs'], CreationReasonAuthenticationRequest::class
);
$this->logger->debug( __METHOD__ . ': name "{username}" is not creatable', [
'username' => $username,
] );
- $session->set( 'AuthManager::AutoCreateBlacklist', 'noname', 600 );
+ $session->set( 'AuthManager::AutoCreateBlacklist', 'noname' );
$user->setId( 0 );
$user->loadFromId();
return Status::newFatal( 'noname' );
'username' => $username,
'ip' => $anon->getName(),
] );
- $session->set( 'AuthManager::AutoCreateBlacklist', 'authmanager-autocreate-noperm', 600 );
+ $session->set( 'AuthManager::AutoCreateBlacklist', 'authmanager-autocreate-noperm' );
$session->persist();
$user->setId( 0 );
$user->loadFromId();
'username' => $username,
'reason' => $ret->getWikiText( null, null, 'en' ),
] );
- $session->set( 'AuthManager::AutoCreateBlacklist', $status, 600 );
+ $session->set( 'AuthManager::AutoCreateBlacklist', $status );
$user->setId( 0 );
$user->loadFromId();
return $ret;
$trxProfiler->setSilenced( true );
try {
$status = $user->addToDatabase();
- if ( !$status->isOk() ) {
+ if ( !$status->isOK() ) {
// Double-check for a race condition (T70012). We make use of the fact that when
// addToDatabase fails due to the user already existing, the user object gets loaded.
if ( $user->getId() ) {
$title = $this->getTitle();
// Never send an RC notification email about categorization changes
- if ( $this->mAttribs['rc_type'] != RC_CATEGORIZE ) {
- if ( Hooks::run( 'AbortEmailNotification', [ $editor, $title, $this ] ) ) {
- # @todo FIXME: This would be better as an extension hook
+ if (
+ $this->mAttribs['rc_type'] != RC_CATEGORIZE &&
+ Hooks::run( 'AbortEmailNotification', [ $editor, $title, $this ] )
+ ) {
+ // @FIXME: This would be better as an extension hook
+ // Send emails or email jobs once this row is safely committed
+ $dbw->onTransactionIdle( function () use ( $editor, $title ) {
$enotif = new EmailNotification();
$enotif->notifyOnPageChange(
$editor,
$this->mAttribs['rc_last_oldid'],
$this->mExtra['pageStatus']
);
- }
+ } );
}
}
*/
const MAX_DELETE_USES = 5000;
+ /**
+ * @var string[]
+ */
+ private static $coreTags = [ 'mw-contentmodelchange' ];
+
/**
* Creates HTML for the given tags
*
// to be removed, a tag must not be defined by an extension, or equivalently it
// has to be either explicitly defined or not defined at all
// (assuming no edge case of a tag both explicitly-defined and extension-defined)
- $extensionDefinedTags = self::listExtensionDefinedTags();
- $intersect = array_intersect( $tagsToRemove, $extensionDefinedTags );
+ $softwareDefinedTags = self::listSoftwareDefinedTags();
+ $intersect = array_intersect( $tagsToRemove, $softwareDefinedTags );
if ( $intersect ) {
return self::restrictedTagError( 'tags-update-remove-not-allowed-one',
'tags-update-remove-not-allowed-multi', $intersect );
return Status::newFatal( 'tags-delete-too-many-uses', $tag, self::MAX_DELETE_USES );
}
- $extensionDefined = self::listExtensionDefinedTags();
- if ( in_array( $tag, $extensionDefined ) ) {
+ $softwareDefined = self::listSoftwareDefinedTags();
+ if ( in_array( $tag, $softwareDefined ) ) {
// extension-defined tags can't be deleted unless the extension
// specifically allows it
$status = Status::newFatal( 'tags-delete-not-allowed' );
}
/**
- * Lists those tags which extensions report as being "active".
+ * Lists those tags which core or extensions report as being "active".
*
* @return array
* @since 1.25
*/
- public static function listExtensionActivatedTags() {
+ public static function listSoftwareActivatedTags() {
+ // core active tags
+ $tags = self::$coreTags;
+ if ( !Hooks::isRegistered( 'ChangeTagsListActive' ) ) {
+ return $tags;
+ }
return ObjectCache::getMainWANInstance()->getWithSetCallback(
wfMemcKey( 'active-tags' ),
WANObjectCache::TTL_MINUTE * 5,
- function ( $oldValue, &$ttl, array &$setOpts ) {
+ function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags ) {
$setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
// Ask extensions which tags they consider active
- $extensionActive = [];
- Hooks::run( 'ChangeTagsListActive', [ &$extensionActive ] );
- return $extensionActive;
+ Hooks::run( 'ChangeTagsListActive', [ &$tags ] );
+ return $tags;
},
[
'checkKeys' => [ wfMemcKey( 'active-tags' ) ],
);
}
+ /**
+ * @see listSoftwareActivatedTags
+ * @deprecated since 1.28 call listSoftwareActivatedTags directly
+ * @return array
+ */
+ public static function listExtensionActivatedTags() {
+ wfDeprecated( __METHOD__, '1.28' );
+ return self::listSoftwareActivatedTags();
+ }
+
/**
* Basically lists defined tags which count even if they aren't applied to anything.
* It returns a union of the results of listExplicitlyDefinedTags() and
*/
public static function listDefinedTags() {
$tags1 = self::listExplicitlyDefinedTags();
- $tags2 = self::listExtensionDefinedTags();
+ $tags2 = self::listSoftwareDefinedTags();
return array_values( array_unique( array_merge( $tags1, $tags2 ) ) );
}
}
/**
- * Lists tags defined by extensions using the ListDefinedTags hook.
+ * Lists tags defined by core or extensions using the ListDefinedTags hook.
* Extensions need only define those tags they deem to be in active use.
*
* Tries memcached first.
* @return string[] Array of strings: tags
* @since 1.25
*/
- public static function listExtensionDefinedTags() {
+ public static function listSoftwareDefinedTags() {
+ // core defined tags
+ $tags = self::$coreTags;
+ if ( !Hooks::isRegistered( 'ListDefinedTags' ) ) {
+ return $tags;
+ }
return ObjectCache::getMainWANInstance()->getWithSetCallback(
wfMemcKey( 'valid-tags-hook' ),
WANObjectCache::TTL_MINUTE * 5,
- function ( $oldValue, &$ttl, array &$setOpts ) {
+ function ( $oldValue, &$ttl, array &$setOpts ) use ( $tags ) {
$setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
- $tags = [];
Hooks::run( 'ListDefinedTags', [ &$tags ] );
return array_filter( array_unique( $tags ) );
},
);
}
+ /**
+ * Call listSoftwareDefinedTags directly
+ *
+ * @see listSoftwareDefinedTags
+ * @deprecated since 1.28
+ */
+ public static function listExtensionDefinedTags() {
+ wfDeprecated( __METHOD__, '1.28' );
+ return self::listSoftwareDefinedTags();
+ }
+
/**
* Invalidates the short-term cache of defined tags used by the
* list*DefinedTags functions, as well as the tag statistics cache.
protected $key;
/** @var string Hash of client parameters */
protected $clientId;
+ /** @var float|null Minimum UNIX timestamp of 1+ expected startup positions */
+ protected $waitForPosTime;
+ /** @var int Max seconds to wait on positions to appear */
+ protected $waitForPosTimeout = self::POS_WAIT_TIMEOUT;
/** @var bool Whether to no-op all method calls */
protected $enabled = true;
/** @var bool Whether to check and wait on positions */
/** @var float[] Map of (DB master name => 1) */
protected $shutdownTouchDBs = [];
+ /** @var integer Seconds to store positions */
+ const POSITION_TTL = 60;
+ /** @var integer Max time to wait for positions to appear */
+ const POS_WAIT_TIMEOUT = 5;
+
/**
* @param BagOStuff $store
* @param array $client Map of (ip: <IP>, agent: <user-agent>)
+ * @param float $posTime UNIX timestamp
* @since 1.27
*/
- public function __construct( BagOStuff $store, array $client ) {
+ public function __construct( BagOStuff $store, array $client, $posTime = null ) {
$this->store = $store;
$this->clientId = md5( $client['ip'] . "\n" . $client['agent'] );
$this->key = $store->makeGlobalKey( __CLASS__, $this->clientId );
+ $this->waitForPosTime = $posTime;
}
/**
* Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now.
* May commit chronology data to persistent storage.
*
+ * @param callable|null $workCallback Work to do instead of waiting on syncing positions
+ * @param string $mode One of (sync, async); whether to wait on remote datacenters
* @return DBMasterPos[] Empty on success; returns the (db name => position) map on failure
*/
- public function shutdown() {
+ public function shutdown( callable $workCallback = null, $mode = 'sync' ) {
if ( !$this->enabled ) {
return [];
}
+ $store = $this->store;
// Some callers might want to know if a user recently touched a DB.
// These writes do not need to block on all datacenters receiving them.
foreach ( $this->shutdownTouchDBs as $dbName => $unused ) {
- $this->store->set(
+ $store->set(
$this->getTouchedKey( $this->store, $dbName ),
microtime( true ),
- BagOStuff::TTL_DAY
+ $store::TTL_DAY
);
}
// CP-protected writes should overwhemingly go to the master datacenter, so get DC-local
// lock to merge the values. Use a DC-local get() and a synchronous all-DC set(). This
// makes it possible for the BagOStuff class to write in parallel to all DCs with one RTT.
- if ( $this->store->lock( $this->key, 3 ) ) {
- $ok = $this->store->set(
+ if ( $store->lock( $this->key, 3 ) ) {
+ if ( $workCallback ) {
+ // Let the store run the work before blocking on a replication sync barrier. By the
+ // time it's done with the work, the barrier should be fast if replication caught up.
+ $store->addBusyCallback( $workCallback );
+ }
+ $ok = $store->set(
$this->key,
- self::mergePositions( $this->store->get( $this->key ), $this->shutdownPositions ),
- BagOStuff::TTL_MINUTE,
- BagOStuff::WRITE_SYNC
+ self::mergePositions( $store->get( $this->key ), $this->shutdownPositions ),
+ self::POSITION_TTL,
+ ( $mode === 'sync' ) ? $store::WRITE_SYNC : 0
);
- $this->store->unlock( $this->key );
+ $store->unlock( $this->key );
} else {
$ok = false;
}
if ( !$ok ) {
+ $bouncedPositions = $this->shutdownPositions;
// Raced out too many times or stash is down
wfDebugLog( 'replication',
__METHOD__ . ": failed to save master pos for " .
implode( ', ', array_keys( $this->shutdownPositions ) ) . "\n"
);
-
- return $this->shutdownPositions;
+ } elseif ( $mode === 'sync' &&
+ $store->getQoS( $store::ATTR_SYNCWRITES ) < $store::QOS_SYNCWRITES_BE
+ ) {
+ // Positions may not be in all datacenters, force LBFactory to play it safe
+ wfDebugLog( 'replication',
+ __METHOD__ . ": store does not report ability to sync replicas. " );
+ $bouncedPositions = $this->shutdownPositions;
+ } else {
+ $bouncedPositions = [];
}
- return [];
+ return $bouncedPositions;
}
/**
$this->initialized = true;
if ( $this->wait ) {
- $data = $this->store->get( $this->key );
+ // If there is an expectation to see master positions with a certain min
+ // timestamp, then block until they appear, or until a timeout is reached.
+ if ( $this->waitForPosTime ) {
+ $data = null;
+ $loop = new WaitConditionLoop(
+ function () use ( &$data ) {
+ $data = $this->store->get( $this->key );
+
+ return ( self::minPosTime( $data ) >= $this->waitForPosTime )
+ ? WaitConditionLoop::CONDITION_REACHED
+ : WaitConditionLoop::CONDITION_CONTINUE;
+ },
+ $this->waitForPosTimeout
+ );
+ $result = $loop->invoke();
+ $waitedMs = $loop->getLastWaitTime() * 1e3;
+
+ if ( $result == $loop::CONDITION_REACHED ) {
+ $msg = "expected and found pos time {$this->waitForPosTime} ({$waitedMs}ms)";
+ } else {
+ $msg = "expected but missed pos time {$this->waitForPosTime} ({$waitedMs}ms)";
+ }
+ wfDebugLog( 'replication', $msg );
+ } else {
+ $data = $this->store->get( $this->key );
+ }
+
$this->startupPositions = $data ? $data['positions'] : [];
wfDebugLog( 'replication', __METHOD__ . ": key is {$this->key} (read)\n" );
} else {
}
}
+ /**
+ * @param array|bool $data
+ * @return float|null
+ */
+ private static function minPosTime( $data ) {
+ if ( !isset( $data['positions'] ) ) {
+ return null;
+ }
+
+ $min = null;
+ foreach ( $data['positions'] as $pos ) {
+ /** @var DBMasterPos $pos */
+ $min = $min ? min( $pos->asOfTime(), $min ) : $pos->asOfTime();
+ }
+
+ return $min;
+ }
+
/**
* @param array|bool $curValue
* @param DBMasterPos[] $shutdownPositions
return $this->lazyMasterHandle;
}
- /**
- * @return TransactionProfiler
- */
- protected function getTransactionProfiler() {
- return $this->trxProfiler;
- }
-
/**
* @param TransactionProfiler $profiler
* @since 1.27
# Keep track of whether the transaction has write queries pending
if ( $this->mTrxLevel && !$this->mTrxDoneWrites && $isWrite ) {
$this->mTrxDoneWrites = true;
- $this->getTransactionProfiler()->transactionWritingIn(
+ $this->trxProfiler->transactionWritingIn(
$this->mServer, $this->mDBname, $this->mTrxShortId );
}
$this->mRTTEstimate = $queryRuntime;
}
- $this->getTransactionProfiler()->recordQueryCompletion(
+ $this->trxProfiler->recordQueryCompletion(
$queryProf, $startTime, $isWrite, $this->affectedRows()
);
MWDebug::query( $sql, $fname, $isMaster, $queryRuntime );
} else {
$useIndex = '';
}
+ if ( isset( $options['IGNORE INDEX'] ) && is_string( $options['IGNORE INDEX'] ) ) {
+ $ignoreIndex = $this->ignoreIndexClause( $options['IGNORE INDEX'] );
+ } else {
+ $ignoreIndex = '';
+ }
- return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail ];
+ return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ];
}
/**
$useIndexes = ( isset( $options['USE INDEX'] ) && is_array( $options['USE INDEX'] ) )
? $options['USE INDEX']
: [];
+ $ignoreIndexes = ( isset( $options['IGNORE INDEX'] ) && is_array( $options['IGNORE INDEX'] ) )
+ ? $options['IGNORE INDEX']
+ : [];
if ( is_array( $table ) ) {
$from = ' FROM ' .
- $this->tableNamesWithUseIndexOrJOIN( $table, $useIndexes, $join_conds );
+ $this->tableNamesWithIndexClauseOrJOIN( $table, $useIndexes, $ignoreIndexes, $join_conds );
} elseif ( $table != '' ) {
if ( $table[0] == ' ' ) {
$from = ' FROM ' . $table;
} else {
$from = ' FROM ' .
- $this->tableNamesWithUseIndexOrJOIN( [ $table ], $useIndexes, [] );
+ $this->tableNamesWithIndexClauseOrJOIN( [ $table ], $useIndexes, $ignoreIndexes, [] );
}
} else {
$from = '';
}
- list( $startOpts, $useIndex, $preLimitTail, $postLimitTail ) =
+ list( $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ) =
$this->makeSelectOptions( $options );
if ( !empty( $conds ) ) {
if ( is_array( $conds ) ) {
$conds = $this->makeList( $conds, LIST_AND );
}
- $sql = "SELECT $startOpts $vars $from $useIndex WHERE $conds $preLimitTail";
+ $sql = "SELECT $startOpts $vars $from $useIndex $ignoreIndex WHERE $conds $preLimitTail";
} else {
- $sql = "SELECT $startOpts $vars $from $useIndex $preLimitTail";
+ $sql = "SELECT $startOpts $vars $from $useIndex $ignoreIndex $preLimitTail";
}
if ( isset( $options['LIMIT'] ) ) {
/**
* Get the aliased table name clause for a FROM clause
- * which might have a JOIN and/or USE INDEX clause
+ * which might have a JOIN and/or USE INDEX or IGNORE INDEX clause
*
* @param array $tables ( [alias] => table )
* @param array $use_index Same as for select()
+ * @param array $ignore_index Same as for select()
* @param array $join_conds Same as for select()
* @return string
*/
- protected function tableNamesWithUseIndexOrJOIN(
- $tables, $use_index = [], $join_conds = []
+ protected function tableNamesWithIndexClauseOrJOIN(
+ $tables, $use_index = [], $ignore_index = [], $join_conds = []
) {
$ret = [];
$retJOIN = [];
$use_index = (array)$use_index;
+ $ignore_index = (array)$ignore_index;
$join_conds = (array)$join_conds;
foreach ( $tables as $alias => $table ) {
$tableClause .= ' ' . $use;
}
}
+ if ( isset( $ignore_index[$alias] ) ) { // has IGNORE INDEX?
+ $ignore = $this->ignoreIndexClause( implode( ',', (array)$ignore_index[$alias] ) );
+ if ( $ignore != '' ) {
+ $tableClause .= ' ' . $ignore;
+ }
+ }
$on = $this->makeList( (array)$conds, LIST_AND );
if ( $on != '' ) {
$tableClause .= ' ON (' . $on . ')';
implode( ',', (array)$use_index[$alias] )
);
+ $ret[] = $tableClause;
+ } elseif ( isset( $ignore_index[$alias] ) ) {
+ // Is there an INDEX clause for this table?
+ $tableClause = $this->tableNameWithAlias( $table, $alias );
+ $tableClause .= ' ' . $this->ignoreIndexClause(
+ implode( ',', (array)$ignore_index[$alias] )
+ );
+
$ret[] = $tableClause;
} else {
$tableClause = $this->tableNameWithAlias( $table, $alias );
return '';
}
+ /**
+ * IGNORE INDEX clause. Unlikely to be useful for anything but MySQL. This
+ * is only needed because a) MySQL must be as efficient as possible due to
+ * its use on Wikipedia, and b) MySQL 4.0 is kind of dumb sometimes about
+ * which index to pick. Anyway, other databases might have different
+ * indexes on a given table. So don't bother overriding this unless you're
+ * MySQL.
+ * @param string $index
+ * @return string
+ */
+ public function ignoreIndexClause( $index ) {
+ return '';
+ }
+
public function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
$quotedTable = $this->tableName( $table );
$selectOptions = [ $selectOptions ];
}
- list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
+ list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) = $this->makeSelectOptions(
+ $selectOptions );
if ( is_array( $srcTable ) ) {
$srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) );
$sql = "INSERT $insertOptions INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
" SELECT $startOpts " . implode( ',', $varMap ) .
- " FROM $srcTable $useIndex ";
+ " FROM $srcTable $useIndex $ignoreIndex ";
if ( $conds != '*' ) {
if ( is_array( $conds ) ) {
$this->doCommit( $fname );
if ( $this->mTrxDoneWrites ) {
$this->mDoneWrites = microtime( true );
- $this->getTransactionProfiler()->transactionWritingOut(
+ $this->trxProfiler->transactionWritingOut(
$this->mServer, $this->mDBname, $this->mTrxShortId, $writeTime );
}
$this->doRollback( $fname );
$this->mTrxAtomicLevels = [];
if ( $this->mTrxDoneWrites ) {
- $this->getTransactionProfiler()->transactionWritingOut(
+ $this->trxProfiler->transactionWritingOut(
$this->mServer, $this->mDBname, $this->mTrxShortId );
}
}
// we want this to be compatible with the output of parent::makeSelectOptions()
- return [ $startOpts, '', $tailOpts, '' ];
+ return [ $startOpts, '', $tailOpts, '', '' ];
}
/**
return "FORCE INDEX (" . $this->indexName( $index ) . ")";
}
+ /**
+ * @param string $index
+ * @return string
+ */
+ function ignoreIndexClause( $index ) {
+ return "IGNORE INDEX (" . $this->indexName( $index ) . ")";
+ }
+
/**
* @return string
*/
if ( !is_array( $selectOptions ) ) {
$selectOptions = [ $selectOptions ];
}
- list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
+ list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) =
+ $this->makeSelectOptions( $selectOptions );
if ( is_array( $srcTable ) ) {
$srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) );
} else {
$sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
" SELECT $startOpts " . implode( ',', $varMap ) .
- " FROM $srcTable $useIndex ";
+ " FROM $srcTable $useIndex $ignoreIndex ";
if ( $conds != '*' ) {
$sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
}
$useIndex = '';
}
- return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail ];
+ if ( isset( $options['IGNORE INDEX'] ) && !is_array( $options['IGNORE INDEX'] ) ) {
+ $ignoreIndex = $this->ignoreIndexClause( $options['IGNORE INDEX'] );
+ } else {
+ $ignoreIndex = '';
+ }
+
+ return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ];
}
public function delete( $table, $conds, $fname = __METHOD__ ) {
if ( !is_array( $selectOptions ) ) {
$selectOptions = [ $selectOptions ];
}
- list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
+ list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) =
+ $this->makeSelectOptions( $selectOptions );
if ( is_array( $srcTable ) ) {
$srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) );
} else {
$sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
" SELECT $startOpts " . implode( ',', $varMap ) .
- " FROM $srcTable $useIndex";
+ " FROM $srcTable $useIndex $ignoreIndex ";
if ( $conds != '*' ) {
$sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
*/
function makeSelectOptions( $options ) {
$preLimitTail = $postLimitTail = '';
- $startOpts = $useIndex = '';
+ $startOpts = $useIndex = $ignoreIndex = '';
$noKeyOptions = [];
foreach ( $options as $key => $option ) {
$startOpts .= 'DISTINCT';
}
- return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail ];
+ return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ];
}
function getDBname() {
/** @var callable[] */
protected $replicationWaitCallbacks = [];
- const SHUTDOWN_NO_CHRONPROT = 1; // don't save ChronologyProtector positions (for async code)
+ const SHUTDOWN_NO_CHRONPROT = 0; // don't save DB positions at all
+ const SHUTDOWN_CHRONPROT_ASYNC = 1; // save DB positions, but don't wait on remote DCs
+ const SHUTDOWN_CHRONPROT_SYNC = 2; // save DB positions, waiting on all DCs
/**
* Construct a factory based on a configuration array (typically from $wgLBFactoryConf)
* @see LoadBalancer::disable()
*/
public function destroy() {
- $this->shutdown();
+ $this->shutdown( self::SHUTDOWN_NO_CHRONPROT );
$this->forEachLBCallMethod( 'disable' );
}
/**
* Prepare all tracked load balancers for shutdown
- * @param integer $flags Supports SHUTDOWN_* flags
- */
- public function shutdown( $flags = 0 ) {
- if ( !( $flags & self::SHUTDOWN_NO_CHRONPROT ) ) {
- $this->shutdownChronologyProtector( $this->chronProt );
+ * @param integer $mode One of the class SHUTDOWN_* constants
+ * @param callable|null $workCallback Work to mask ChronologyProtector writes
+ */
+ public function shutdown(
+ $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null
+ ) {
+ if ( $mode === self::SHUTDOWN_CHRONPROT_SYNC ) {
+ $this->shutdownChronologyProtector( $this->chronProt, $workCallback, 'sync' );
+ } elseif ( $mode === self::SHUTDOWN_CHRONPROT_ASYNC ) {
+ $this->shutdownChronologyProtector( $this->chronProt, null, 'async' );
}
+
$this->commitMasterChanges( __METHOD__ ); // sanity
}
/**
* Determine if any master connection has pending/written changes from this request
+ * @param float $age How many seconds ago is "recent" [defaults to LB lag wait timeout]
* @return bool
* @since 1.27
*/
- public function hasOrMadeRecentMasterChanges() {
+ public function hasOrMadeRecentMasterChanges( $age = null ) {
$ret = false;
- $this->forEachLB( function ( LoadBalancer $lb ) use ( &$ret ) {
- $ret = $ret || $lb->hasOrMadeRecentMasterChanges();
+ $this->forEachLB( function ( LoadBalancer $lb ) use ( $age, &$ret ) {
+ $ret = $ret || $lb->hasOrMadeRecentMasterChanges( $age );
} );
return $ret;
}
'ifWritesSince' => null
];
- foreach ( $this->replicationWaitCallbacks as $callback ) {
- $callback();
- }
-
// Figure out which clusters need to be checked
/** @var LoadBalancer[] $lbs */
$lbs = [];
$masterPositions[$i] = $lb->getMasterPos();
}
+ // Run any listener callbacks *after* getting the DB positions. The more
+ // time spent in the callbacks, the less time is spent in waitForAll().
+ foreach ( $this->replicationWaitCallbacks as $callback ) {
+ $callback();
+ }
+
$failed = [];
foreach ( $lbs as $i => $lb ) {
if ( $masterPositions[$i] ) {
ObjectCache::getMainStashInstance(),
[
'ip' => $request->getIP(),
- 'agent' => $request->getHeader( 'User-Agent' )
- ]
+ 'agent' => $request->getHeader( 'User-Agent' ),
+ ],
+ $request->getFloat( 'cpPosTime', null )
);
if ( PHP_SAPI === 'cli' ) {
$chronProt->setEnabled( false );
}
/**
+ * Get and record all of the staged DB positions into persistent memory storage
+ *
* @param ChronologyProtector $cp
+ * @param callable|null $workCallback Work to do instead of waiting on syncing positions
+ * @param string $mode One of (sync, async); whether to wait on remote datacenters
*/
- protected function shutdownChronologyProtector( ChronologyProtector $cp ) {
- // Get all the master positions needed
+ protected function shutdownChronologyProtector(
+ ChronologyProtector $cp, $workCallback, $mode
+ ) {
+ // Record all the master positions needed
$this->forEachLB( function ( LoadBalancer $lb ) use ( $cp ) {
$cp->shutdownLB( $lb );
} );
- // Write them to the stash
- $unsavedPositions = $cp->shutdown();
+ // Write them to the persistent stash. Try to do something useful by running $work
+ // while ChronologyProtector waits for the stash write to replicate to all DCs.
+ $unsavedPositions = $cp->shutdown( $workCallback, $mode );
+ if ( $unsavedPositions && $workCallback ) {
+ // Invoke callback in case it did not cache the result yet
+ $workCallback(); // work now to block for less time in waitForAll()
+ }
// If the positions failed to write to the stash, at least wait on local datacenter
// replica DBs to catch up before responding. Even if there are several DCs, this increases
// the chance that the user will see their own changes immediately afterwards. As long
}
}
+ /**
+ * Append ?cpPosTime parameter to a URL for ChronologyProtector purposes if needed
+ *
+ * Note that unlike cookies, this works accross domains
+ *
+ * @param string $url
+ * @param float $time UNIX timestamp just before shutdown() was called
+ * @return string
+ * @since 1.28
+ */
+ public function appendPreShutdownTimeAsQuery( $url, $time ) {
+ $usedCluster = 0;
+ $this->forEachLB( function ( LoadBalancer $lb ) use ( &$usedCluster ) {
+ $usedCluster |= ( $lb->getServerCount() > 1 );
+ } );
+
+ if ( !$usedCluster ) {
+ return $url; // no master/replica clusters touched
+ }
+
+ return wfAppendQuery( $url, [ 'cpPosTime' => $time ] );
+ }
+
/**
* Close all open database connections on all open load balancers.
* @since 1.28
public function closeAll() {
$this->forEachLBCallMethod( 'closeAll', [] );
}
-
}
*
* @param IDatabase $conn Replica DB
* @param DBMasterPos|bool $pos Master position; default: current position
- * @param integer $timeout Timeout in seconds
+ * @param integer|null $timeout Timeout in seconds [optional]
* @return bool Success
* @since 1.27
*/
- public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = 10 ) {
+ public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = null ) {
if ( $this->getServerCount() == 1 || !$conn->getLBInfo( 'replica' ) ) {
return true; // server is not a replica DB
}
return false; // something is misconfigured
}
+ $timeout = $timeout ?: $this->mWaitTimeout;
$result = $conn->masterPosWait( $pos, $timeout );
if ( $result == -1 || is_null( $result ) ) {
$msg = __METHOD__ . ": Timed out waiting on {$conn->getServer()} pos {$pos}";
*
* Usage:
* @code
- * $wgMWLoggerDefaultSpi = array(
+ * $wgMWLoggerDefaultSpi = [
* 'class' => '\\MediaWiki\\Logger\\LegacySpi',
- * );
+ * ];
* @endcode
*
* @see \MediaWiki\Logger\LoggerFactory
*
* Usage:
*
- * $wgMWLoggerDefaultSpi = array(
+ * $wgMWLoggerDefaultSpi = [
* 'class' => '\\MediaWiki\\Logger\\NullSpi',
- * );
+ * ];
*
* @see \MediaWiki\Logger\LoggerFactory
* @since 1.25
* Convenience method, calls doUpdate() on every DataUpdate in the array.
*
* @param DataUpdate[] $updates A list of DataUpdate instances
- * @param string $mode Use "enqueue" to use the job queue when possible [Default: run]
* @throws Exception
* @deprecated Since 1.28 Use DeferredUpdates::execute()
*/
- public static function runUpdates( array $updates, $mode = 'run' ) {
- DeferredUpdates::execute( $updates, $mode, DeferredUpdates::ALL );
+ public static function runUpdates( array $updates ) {
+ foreach ( $updates as $update ) {
+ $update->doUpdate();
+ }
}
}
}
/**
+ * Immediately run/queue a list of updates
+ *
* @param DeferrableUpdate[] &$queue List of DeferrableUpdate objects
* @param string $mode Use "enqueue" to use the job queue when possible
* @param integer $stage Class constant (PRESEND, POSTSEND) (since 1.28)
* @throws ErrorPageError Happens on top-level calls
* @throws Exception Happens on second-level calls
*/
- public static function execute( array &$queue, $mode, $stage ) {
+ protected static function execute( array &$queue, $mode, $stage ) {
$services = MediaWikiServices::getInstance();
$stats = $services->getStatsdDataFactory();
$lbFactory = $services->getDBLoadBalancerFactory();
$method = RequestContext::getMain()->getRequest()->getMethod();
+ $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
+
/** @var ErrorPageError $reportableError */
$reportableError = null;
/** @var DeferrableUpdate[] $updates Snapshot of queue */
// Order will be DataUpdate followed by generic DeferrableUpdate tasks
$updatesByType = [ 'data' => [], 'generic' => [] ];
foreach ( $updates as $du ) {
- $updatesByType[$du instanceof DataUpdate ? 'data' : 'generic'][] = $du;
+ if ( $du instanceof DataUpdate ) {
+ $du->setTransactionTicket( $ticket );
+ $updatesByType['data'][] = $du;
+ } else {
+ $updatesByType['generic'][] = $du;
+ }
+
$name = ( $du instanceof DeferrableCallback )
? get_class( $du ) . '-' . $du->getOrigin()
: get_class( $du );
* @param string $titleMsg A message key to set the page title.
* Optional, default: 'exception-nologin'
* @param array $params Parameters to wfMessage().
- * Optional, default: array()
+ * Optional, default: []
*/
public function __construct(
$reasonMsg = 'exception-nologin-text',
}
if ( !is_string( $value ) && !is_int( $value ) ) {
- return false;
+ return $this->msg( 'htmlform-required' )->parse();
}
$validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
"config-restart": "হ্যাঁ, পুনরায় চালু করুন",
"config-env-php": "পিএইচপি $1 ইন্সটল করা হয়েছে।",
"config-env-hhvm": "HHVM $1 ইনস্টল করা হয়েছে।",
+ "config-memory-raised": "পিএইচপির <code>memory_limit</code> হচ্ছে $1, বৃদ্ধি পেয়ে $2 হয়েছে।",
"config-xcache": "[http://xcache.lighttpd.net/ XCache] ইনস্টল করা হয়েছে",
"config-apc": "[http://www.php.net/apc এপিসি] ইনস্টল হয়েছে",
"config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] ইনস্টল করা হয়েছে",
"config-missing-db-host": "আপনাকে অবশ্যই \"{{int:config-db-host}}\"-এর জন্য একটি মান প্রবেশ করাতে হবে।",
"config-missing-db-server-oracle": "আপনাকে অবশ্যই \"{{int:config-db-host-oracle}}\"-এর জন্য একটি মান প্রবেশ করাতে হবে।",
"config-connection-error": "$1।\n\n\nদয়া করে প্রস্তাবকারী, ব্যবহারকারী নাম ও পাসওয়ার্ড দেখুন এবং পুনরায় চেষ্টা করুন।",
+ "config-sqlite-readonly": "ফাইল <code>$1</code> লিখনযোগ্য নয়।",
+ "config-sqlite-cant-create-db": "ডাটাবেজ ফাইল <code>$1</code> তৈরি করা যায়নি।",
"config-regenerate": "LocalSettings.php পুনরূত্পাদিত করুন →",
"config-mysql-engine": "সংরক্ষণ ইঞ্জিন:",
"config-mysql-innodb": "ইনোডিবি",
"config-license-cc-choose": "একটি স্বনির্ধারিত ক্রিয়েটিভ কমন্স লাইসেন্ট নির্বাচন করুন",
"config-email-settings": "ই-মেইল সেটিংস",
"config-email-user": "ব্যবহারকারী-থেকে-ব্যবহারকারী ই-মেইল সুবিধা সক্রিয় করো",
+ "config-email-usertalk": "ব্যবহারকারী আলাপ পাতার বিজ্ঞপ্তি সক্রিয় করো",
"config-upload-settings": "চিত্র এবং ফাইল আপলোড",
"config-upload-enable": "ফাইল আপলোড সক্রিয় করো",
"config-upload-deleted": "অপসারণকৃত ফাইলের ডিরেক্টরি:",
"config-logo": "লোগো ইউআরএল:",
+ "config-advanced-settings": "উন্নত কনফিগারেশন",
"config-memcached-servers": "মেমক্যাশেকৃত সার্ভারসমূহ:",
"config-extensions": "এক্সটেনশন",
"config-skins": "আবরণ",
"config-install-tables": "টেবিল তৈরি",
"config-install-keys": "গোপন কি তৈরি",
"config-help": "সাহায্য",
+ "config-help-tooltip": "প্রসারিত করতে ক্লিক করুন",
"mainpagetext": "<strong>মিডিয়াউইকি ইনস্টল করা হয়েছে।</strong>",
"mainpagedocfooter": "কীভাবে উইকি সফটওয়্যারটি ব্যবহারকার করবেন, তা জানতে [https://meta.wikimedia.org/wiki/Help:Contents ব্যবহারকারী সহায়িকা] দেখুন।\n\n== কোথা থেকে শুরু করবেন ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings কনফিগারেশন সেটিংস তালিকা]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ প্রশ্নোত্তরে মিডিয়াউইকি]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce মিডিয়াউইকি মুক্তির মেইলিং লিস্ট]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources আপনার ভাষার জন্য মিডিয়াউইকি স্থানীয়করণ করুন]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam আপনার উইকিতে স্প্যামের সাথে লড়াই করার উপায় সম্পর্কে জানুন]"
}
* @file
* @author Aaron Schulz
*/
+use MediaWiki\MediaWikiServices;
/**
* Class to handle job queues stored in the DB
* @return void
*/
protected function doWaitForBackups() {
- wfWaitForSlaves( false, $this->wiki, $this->cluster ?: false );
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $lbFactory->waitForReplication( [ 'wiki' => $this->wiki, 'cluster' => $this->cluster ] );
}
/**
* @return DBConnRef
*/
protected function getDB( $index ) {
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$lb = ( $this->cluster !== false )
- ? wfGetLBFactory()->getExternalLB( $this->cluster, $this->wiki )
- : wfGetLB( $this->wiki );
+ ? $lbFactory->getExternalLB( $this->cluster, $this->wiki )
+ : $lbFactory->getMainLB( $this->wiki );
return $lb->getConnectionRef( $index, [], $this->wiki );
}
$this->cache->clear( 'queues-ready' );
}
}
+
+ $cache = ObjectCache::getLocalClusterInstance();
+ $cache->set(
+ $cache->makeGlobalKey( 'jobqueue', $this->wiki, 'hasjobs', self::TYPE_ANY ),
+ 'true',
+ 15
+ );
+ if ( array_intersect( array_keys( $jobsByType ), $this->getDefaultQueueTypes() ) ) {
+ $cache->set(
+ $cache->makeGlobalKey( 'jobqueue', $this->wiki, 'hasjobs', self::TYPE_DEFAULT ),
+ 'true',
+ 15
+ );
+ }
}
/**
* @since 1.23
*/
public function queuesHaveJobs( $type = self::TYPE_ANY ) {
- $key = wfMemcKey( 'jobqueue', 'queueshavejobs', $type );
$cache = ObjectCache::getLocalClusterInstance();
+ $key = $cache->makeGlobalKey( 'jobqueue', $this->wiki, 'hasjobs', $type );
$value = $cache->get( $key );
if ( $value === false ) {
MWExceptionHandler::rollbackMasterChangesAndLog( $e );
$status = false;
$error = get_class( $e ) . ': ' . $e->getMessage();
- MWExceptionHandler::logException( $e );
}
// Always attempt to call teardown() even if Job throws exception.
try {
* @since 1.27
*/
class CategoryMembershipChangeJob extends Job {
+ /** @var integer|null */
+ private $ticket;
+
const ENQUEUE_FUDGE_SEC = 60;
public function __construct( Title $title, array $params ) {
}
public function run() {
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $lb = $lbFactory->getMainLB();
+ $dbw = $lb->getConnection( DB_MASTER );
+
+ $this->ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
+
$page = WikiPage::newFromID( $this->params['pageId'], WikiPage::READ_LATEST );
if ( !$page ) {
$this->setLastError( "Could not find page #{$this->params['pageId']}" );
return false; // deleted?
}
- $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
- $dbw = $lb->getConnection( DB_MASTER );
// Use a named lock so that jobs for this page see each others' changes
$lockKey = "CategoryMembershipUpdates:{$page->getId()}";
$scopedLock = $dbw->getScopedLockAndFlush( $lockKey, __METHOD__, 10 );
return false;
}
- $dbr = wfGetDB( DB_REPLICA, [ 'recentchanges' ] );
+ $dbr = $lb->getConnection( DB_REPLICA, [ 'recentchanges' ] );
// Wait till the replica DB is caught up so that jobs for this page see each others' changes
if ( !$lb->safeWaitForMasterPos( $dbr ) ) {
$this->setLastError( "Timed out while waiting for replica DB to catch up" );
);
// Apply all category updates in revision timestamp order
- $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
foreach ( $res as $row ) {
$this->notifyUpdatesForRevision( $lbFactory, $page, Revision::newFromRow( $row ) );
}
return; // nothing to do
}
- $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
-
$catMembChange = new CategoryMembershipChange( $title, $newRev );
$catMembChange->checkTemplateLinks();
$categoryTitle = Title::makeTitle( NS_CATEGORY, $categoryName );
$catMembChange->triggerCategoryAddedNotification( $categoryTitle );
if ( $insertCount++ && ( $insertCount % $batchSize ) == 0 ) {
- $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
+ $lbFactory->commitAndWaitForReplication( __METHOD__, $this->ticket );
}
}
$categoryTitle = Title::makeTitle( NS_CATEGORY, $categoryName );
$catMembChange->triggerCategoryRemovedNotification( $categoryTitle );
if ( $insertCount++ && ( $insertCount++ % $batchSize ) == 0 ) {
- $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
+ $lbFactory->commitAndWaitForReplication( __METHOD__, $this->ticket );
}
}
}
// enqueued will be reflected in backlink page parses when the leaf jobs run.
if ( !isset( $params['range'] ) ) {
try {
- wfGetLBFactory()->waitForReplication( [
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $lbFactory->waitForReplication( [
'wiki' => wfWikiID(),
'timeout' => self::LAG_WAIT_TIMEOUT
] );
* @return bool
*/
protected function runForTitle( Title $title ) {
- $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+ $services = MediaWikiServices::getInstance();
+ $stats = $services->getStatsdDataFactory();
+ $lbFactory = $services->getDBLoadBalancerFactory();
+ $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
$page = WikiPage::factory( $title );
$page->loadPageData( WikiPage::READ_LATEST );
// Serialize links updates by page ID so they see each others' changes
- $scopedLock = LinksUpdate::acquirePageLock( wfGetDB( DB_MASTER ), $page->getId(), 'job' );
+ $dbw = $lbFactory->getMainLB()->getConnection( DB_MASTER );
+ /** @noinspection PhpUnusedLocalVariableInspection */
+ $scopedLock = LinksUpdate::acquirePageLock( $dbw, $page->getId(), 'job' );
// Get the latest ID *after* acquirePageLock() flushed the transaction.
// This is used to detect edits/moves after loadPageData() but before the scope lock.
// The works around the chicken/egg problem of determining the scope lock key.
$parserOutput
);
- $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
- $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
foreach ( $updates as $key => $update ) {
- $update->setTransactionTicket( $ticket );
// FIXME: This code probably shouldn't be here?
// Needed by things like Echo notifications which need
// to know which user caused the links update
}
foreach ( $updates as $update ) {
+ $update->setTransactionTicket( $ticket );
$update->doUpdate();
}
*
* @file
*/
+use MediaWiki\MediaWikiServices;
+
class PurgeJobUtils {
/**
* Invalidate the cache of a list of pages from a single namespace.
return;
}
- $dbw->onTransactionPreCommitOrIdle( function() use ( $dbw, $namespace, $dbkeys ) {
+ $dbw->onTransactionIdle( function() use ( $dbw, $namespace, $dbkeys ) {
+ $services = MediaWikiServices::getInstance();
+ $lbFactory = $services->getDBLoadBalancerFactory();
// Determine which pages need to be updated.
// This is necessary to prevent the job queue from smashing the DB with
// large numbers of concurrent invalidations of the same page.
__METHOD__
);
- if ( $ids === [] ) {
+ if ( !$ids ) {
return;
}
- // Do the update.
- // We still need the page_touched condition, in case the row has changed since
- // the non-locking select above.
- $dbw->update(
- 'page',
- [ 'page_touched' => $now ],
- [
- 'page_id' => $ids,
- 'page_touched < ' . $dbw->addQuotes( $now )
- ],
- __METHOD__
- );
+ $batchSize = $services->getMainConfig()->get( 'UpdateRowsPerQuery' );
+ $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
+ foreach ( array_chunk( $ids, $batchSize ) as $idBatch ) {
+ $dbw->update(
+ 'page',
+ [ 'page_touched' => $now ],
+ [
+ 'page_id' => $idBatch,
+ 'page_touched < ' . $dbw->addQuotes( $now ) // handle races
+ ],
+ __METHOD__
+ );
+ $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
+ }
} );
}
}
* @return mixed The cached value if found or the result of $callback otherwise
*/
public function getWithSetCallback( $key, callable $callback ) {
- $value = $this->get( $key );
- if ( $value === null ) {
+ if ( $this->has( $key ) ) {
+ $value = $this->get( $key );
+ } else {
$value = call_user_func( $callback );
if ( $value !== false ) {
$this->set( $key, $value );
private $timeout;
/** @var float Seconds */
private $lastWaitTime;
+ /** @var integer|null */
+ private $rusageMode;
const CONDITION_REACHED = 1;
const CONDITION_CONTINUE = 0; // evaluates as falsey
$this->condition = $condition;
$this->timeout = $timeout;
$this->busyCallbacks =& $busyCallbacks;
+
+ if ( defined( 'HHVM_VERSION' ) && PHP_OS === 'Linux' ) {
+ $this->rusageMode = 2; // RUSAGE_THREAD
+ } elseif ( function_exists( 'getrusage' ) ) {
+ $this->rusageMode = 0; // RUSAGE_SELF
+ }
}
/**
* @return float Returns 0.0 if not supported (Windows on PHP < 7)
*/
protected function getCpuTime() {
- $time = 0.0;
-
- if ( defined( 'HHVM_VERSION' ) && PHP_OS === 'Linux' ) {
- $ru = getrusage( 2 /* RUSAGE_THREAD */ );
- } else {
- $ru = getrusage( 0 /* RUSAGE_SELF */ );
- }
- if ( $ru ) {
- $time += $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6;
- $time += $ru['ru_stime.tv_sec'] + $ru['ru_stime.tv_usec'] / 1e6;
+ if ( $this->rusageMode === null ) {
+ return microtime( true ); // assume worst case (all time is CPU)
}
+ $ru = getrusage( $this->rusageMode );
+ $time = $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6;
+ $time += $ru['ru_stime.tv_sec'] + $ru['ru_stime.tv_usec'] / 1e6;
+
return $time;
}
// Medium attributes constants related to emulation or media type
const ATTR_EMULATION = 1;
const QOS_EMULATION_SQL = 1;
+ // Medium attributes constants related to replica consistency
+ const ATTR_SYNCWRITES = 2; // SYNC_WRITES flag support
+ const QOS_SYNCWRITES_NONE = 1; // replication only supports eventual consistency or less
+ const QOS_SYNCWRITES_BE = 2; // best effort synchronous with limited retries
+ const QOS_SYNCWRITES_QC = 3; // write quorum applied directly to state machines where R+W > N
+ const QOS_SYNCWRITES_SS = 4; // strict-serializable, nodes refuse reads if possible stale
// Generic "unknown" value that is useful for comparisons (e.g. always good enough)
const QOS_UNKNOWN = INF;
}
/** @var MemcachedClient|Memcached */
protected $client;
+ function __construct( array $params ) {
+ parent::__construct( $params );
+
+ $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE; // unreliable
+ }
+
/**
* Fill in some defaults for missing keys in $params.
*
}
// Make sure URL ends with /
$this->url = rtrim( $params['url'], '/' ) . '/';
+ // Default config, R+W > N; no locks on reads though; writes go straight to state-machine
+ $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_QC;
}
/**
} else {
$this->automaticFailover = true;
}
+
+ $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_NONE;
}
protected function doGet( $key, $flags = 0 ) {
parent::__construct( $params );
$this->attrMap[self::ATTR_EMULATION] = self::QOS_EMULATION_SQL;
+ $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_NONE;
if ( isset( $params['servers'] ) ) {
$this->serverInfos = [];
// Default to using the main wiki's database servers
$this->serverInfos = false;
$this->numServers = 1;
+ $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE;
}
if ( isset( $params['purgePeriod'] ) ) {
$this->purgePeriod = intval( $params['purgePeriod'] );
*/
public static function newFromID( $id ) {
$t = Title::newFromID( $id );
- # @todo FIXME: Doesn't inherit right
- return $t == null ? null : new self( $t );
- # return $t == null ? null : new static( $t ); // PHP 5.3
+ return $t == null ? null : new static( $t );
}
/**
* Call to WikiPage function for backwards compatibility.
* @see WikiPage::doPurge
*/
- public function doPurge() {
- return $this->mPage->doPurge();
+ public function doPurge( $flags = WikiPage::PURGE_ALL ) {
+ return $this->mPage->doPurge( $flags );
+ }
+
+ /**
+ * Call to WikiPage function for backwards compatibility.
+ * @see WikiPage::getLastPurgeTimestamp
+ */
+ public function getLastPurgeTimestamp() {
+ return $this->mPage->getLastPurgeTimestamp();
}
/**
return new WikiCategoryPage( $title );
}
- /**
- * Constructor from a page id
- * @param int $id Article ID to load
- * @return CategoryPage|null
- */
- public static function newFromID( $id ) {
- $t = Title::newFromID( $id );
- # @todo FIXME: Doesn't inherit right
- return $t == null ? null : new self( $t );
- # return $t == null ? null : new static( $t ); // PHP 5.3
- }
-
function view() {
$request = $this->getContext()->getRequest();
$diff = $request->getVal( 'diff' );
return new WikiFilePage( $title );
}
- /**
- * Constructor from a page id
- * @param int $id Article ID to load
- * @return ImagePage|null
- */
- public static function newFromID( $id ) {
- $t = Title::newFromID( $id );
- # @todo FIXME: Doesn't inherit right
- return $t == null ? null : new self( $t );
- # return $t == null ? null : new static( $t ); // PHP 5.3
- }
-
/**
* @param File $file
* @return void
return $this->mDupes;
}
- /**
- * Override handling of action=purge
- * @return bool
- */
- public function doPurge() {
+ public function doPurge( $flags = self::PURGE_ALL ) {
$this->loadFile();
+
if ( $this->mFile->exists() ) {
wfDebug( 'ImagePage::doPurge purging ' . $this->mFile->getName() . "\n" );
DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->mTitle, 'imagelinks' ) );
// Purge redirect cache
$this->mRepo->invalidateImageRedirect( $this->mTitle );
}
- return parent::doPurge();
+
+ return parent::doPurge( $flags );
}
/**
*/
protected $mLinksUpdated = '19700101000000';
+ const PURGE_CDN_CACHE = 1; // purge CDN cache for page variant URLs
+ const PURGE_CLUSTER_PCACHE = 2; // purge parser cache in the local datacenter
+ const PURGE_GLOBAL_PCACHE = 4; // set page_touched to clear parser cache in all datacenters
+ const PURGE_ALL = 7;
+
/**
* Constructor and clear the article
* @param Title $title Reference to a Title object.
* @return bool
*/
public function hasViewableContent() {
- return $this->exists() || $this->mTitle->isAlwaysKnown();
+ return $this->mTitle->isKnown();
}
/**
/**
* Perform the actions of a page purging
+ * @param integer $flags Bitfield of WikiPage::PURGE_* constants
* @return bool
*/
- public function doPurge() {
+ public function doPurge( $flags = self::PURGE_ALL ) {
if ( !Hooks::run( 'ArticlePurge', [ &$this ] ) ) {
return false;
}
- $this->mTitle->invalidateCache();
- // Send purge after above page_touched update was committed
- DeferredUpdates::addUpdate(
- new CdnCacheUpdate( $this->mTitle->getCdnUrls() ),
- DeferredUpdates::PRESEND
- );
+ if ( ( $flags & self::PURGE_GLOBAL_PCACHE ) == self::PURGE_GLOBAL_PCACHE ) {
+ // Set page_touched in the database to invalidate all DC caches
+ $this->mTitle->invalidateCache();
+ } elseif ( ( $flags & self::PURGE_CLUSTER_PCACHE ) == self::PURGE_CLUSTER_PCACHE ) {
+ // Delete the parser options key in the local cluster to invalidate the DC cache
+ ParserCache::singleton()->deleteOptionsKey( $this );
+ // Avoid sending HTTP 304s in ViewAction to the client who just issued the purge
+ $cache = ObjectCache::getLocalClusterInstance();
+ $cache->set(
+ $cache->makeKey( 'page', 'last-dc-purge', $this->getId() ),
+ wfTimestamp( TS_MW ),
+ $cache::TTL_HOUR
+ );
+ }
+
+ if ( ( $flags & self::PURGE_CDN_CACHE ) == self::PURGE_CDN_CACHE ) {
+ // Clear any HTML file cache
+ HTMLFileCache::clearFileCache( $this->getTitle() );
+ // Send purge after any page_touched above update was committed
+ DeferredUpdates::addUpdate(
+ new CdnCacheUpdate( $this->mTitle->getCdnUrls() ),
+ DeferredUpdates::PRESEND
+ );
+ }
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
// @todo move this logic to MessageCache
return true;
}
+ /**
+ * Get the last time a user explicitly purged the page via action=purge
+ *
+ * @return string|bool TS_MW timestamp or false
+ * @since 1.28
+ */
+ public function getLastPurgeTimestamp() {
+ $cache = ObjectCache::getLocalClusterInstance();
+
+ return $cache->get( $cache->makeKey( 'page', 'last-dc-purge', $this->getId() ) );
+ }
+
/**
* Insert a new empty page record for this article.
* This *must* be followed up by creating a revision
*/
public function doEditContent(
Content $content, $summary, $flags = 0, $baseRevId = false,
- User $user = null, $serialFormat = null, $tags = null
+ User $user = null, $serialFormat = null, $tags = []
) {
global $wgUser, $wgUseAutomaticEditSummaries;
+ // Old default parameter for $tags was null
+ if ( $tags === null ) {
+ $tags = [];
+ }
+
// Low-level sanity check
if ( $this->mTitle->getText() === '' ) {
throw new MWException( 'Something is trying to edit an article with an empty title' );
$old_revision = $this->getRevision(); // current revision
$old_content = $this->getContent( Revision::RAW ); // current revision's content
+ if ( $old_content && $old_content->getModel() !== $content->getModel() ) {
+ $tags[] = 'mw-contentmodelchange';
+ }
+
// Provide autosummaries if one is not provided and autosummaries are enabled
if ( $wgUseAutomaticEditSummaries && ( $flags & EDIT_AUTOSUMMARY ) && $summary == '' ) {
$handler = $content->getContentHandler();
Hooks::run( 'WikiPageDeletionUpdates', [ $this, $content, &$updates ] );
return $updates;
}
+
+ /**
+ * Whether this content displayed on this page
+ * comes from the local database
+ *
+ * @since 1.28
+ * @return bool
+ */
+ public function isLocal() {
+ return true;
+ }
}
public $mDefaultDirection = IndexPager::DIR_DESCENDING;
public $mYear;
public $mMonth;
+ public $mDay;
function getNavigationBar() {
if ( !$this->isNavigationBarShown() ) {
return $this->mNavigationBar;
}
- function getDateCond( $year, $month ) {
+ /**
+ * Set and return the mOffset timestamp such that we can get all revisions with
+ * a timestamp up to the specified parameters.
+ * @param int $year [optional] Year up to which we want revisions. Default is current year.
+ * @param int $month [optional] Month up to which we want revisions. Default is end of year.
+ * @param int $day [optional] Day up to which we want revisions. Default is end of month.
+ * @return string Timestamp
+ */
+ function getDateCond( $year = -1, $month = -1, $day = -1 ) {
$year = intval( $year );
$month = intval( $month );
+ $day = intval( $day );
- // Basic validity checks
+ // Basic validity checks for year and month
$this->mYear = $year > 0 ? $year : false;
$this->mMonth = ( $month > 0 && $month < 13 ) ? $month : false;
- // Given an optional year and month, we need to generate a timestamp
+ // Given an optional year, month, and day, we need to generate a timestamp
// to use as "WHERE rev_timestamp <= result"
- // Examples: year = 2006 equals < 20070101 (+000000)
- // year=2005, month=1 equals < 20050201
- // year=2005, month=12 equals < 20060101
- if ( !$this->mYear && !$this->mMonth ) {
- return;
- }
-
+ // Examples: year = 2006 equals < 20070101 (+000000)
+ // year=2005, month=1 equals < 20050201
+ // year=2005, month=12 equals < 20060101
+ // year=2005, month=12, day=5 equals < 20051206
if ( $this->mYear ) {
$year = $this->mYear;
} else {
}
if ( $this->mMonth ) {
- $month = $this->mMonth + 1;
- // For December, we want January 1 of the next year
+ $month = $this->mMonth;
+
+ // Day validity check after we have month and year checked
+ $this->mDay = checkdate( $month, $day, $year ) ? $day : false;
+
+ if ( $this->mDay ) {
+ // If we have a day, we want up to the day immediately afterward
+ $day = $this->mDay + 1;
+
+ // Did we overflow the current month?
+ if ( !checkdate( $month, $day, $year ) ) {
+ $day = 1;
+ $month++;
+ }
+ } else {
+ // If no day, assume beginning of next month
+ $day = 1;
+ $month++;
+ }
+
+ // Did we overflow the current year?
if ( $month > 12 ) {
$month = 1;
$year++;
}
+
} else {
// No month implies we want up to the end of the year in question
$month = 1;
+ $day = 1;
$year++;
}
$year = 2032;
}
- $ymd = (int)sprintf( "%04d%02d01", $year, $month );
+ $ymd = (int)sprintf( "%04d%02d%02d", $year, $month, $day );
if ( $ymd > 20320101 ) {
$ymd = 20320101;
$timestamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
$this->mOffset = $this->mDb->timestamp( $timestamp->getTimestamp() );
+ return $this->mOffset;
}
}
} elseif ( isset( $m[5] ) && $m[5] !== '' ) {
# RFC or PMID
if ( substr( $m[0], 0, 3 ) === 'RFC' ) {
+ if ( !$this->mOptions->getMagicRFCLinks() ) {
+ return $m[0];
+ }
$keyword = 'RFC';
$urlmsg = 'rfcurl';
$cssClass = 'mw-magiclink-rfc';
$id = $m[5];
} elseif ( substr( $m[0], 0, 4 ) === 'PMID' ) {
+ if ( !$this->mOptions->getMagicPMIDLinks() ) {
+ return $m[0];
+ }
$keyword = 'PMID';
$urlmsg = 'pubmedurl';
$cssClass = 'mw-magiclink-pmid';
}
$url = wfMessage( $urlmsg, $id )->inContentLanguage()->text();
return Linker::makeExternalLink( $url, "{$keyword} {$id}", true, $cssClass, [], $this->mTitle );
- } elseif ( isset( $m[6] ) && $m[6] !== '' ) {
+ } elseif ( isset( $m[6] ) && $m[6] !== ''
+ && $this->mOptions->getMagicISBNLinks()
+ ) {
# ISBN
$isbn = $m[6];
$space = self::SPACE_NOT_NL; # non-newline space
* Replace external links (REL)
*
* Note: this is all very hackish and the order of execution matters a lot.
- * Make sure to run tests/parserTests.php if you change this code.
+ * Make sure to run tests/parser/parserTests.php if you change this code.
*
* @private
*
}
/**
- * @param WikiPage $article
+ * @param WikiPage $page
* @return mixed|string
*/
- protected function getOptionsKey( $article ) {
- $pageid = $article->getId();
- return wfMemcKey( 'pcache', 'idoptions', "{$pageid}" );
+ protected function getOptionsKey( $page ) {
+ return wfMemcKey( 'pcache', 'idoptions', $page->getId() );
+ }
+
+ /**
+ * @param WikiPage $page
+ * @since 1.28
+ */
+ public function deleteOptionsKey( $page ) {
+ $this->mMemc->delete( $this->getOptionsKey( $page ) );
}
/**
*/
private $mExtraKey = '';
+ /**
+ * Are magic ISBN links enabled?
+ */
+ private $mMagicISBNLinks = true;
+
+ /**
+ * Are magic PMID links enabled?
+ */
+ private $mMagicPMIDLinks = true;
+
+ /**
+ * Are magic RFC links enabled?
+ */
+ private $mMagicRFCLinks = true;
+
/**
* Function to be called when an option is accessed.
*/
return $this->getUserLangObj()->getCode();
}
+ /**
+ * @since 1.28
+ * @return bool
+ */
+ public function getMagicISBNLinks() {
+ return $this->mMagicISBNLinks;
+ }
+
+ /**
+ * @since 1.28
+ * @return bool
+ */
+ public function getMagicPMIDLinks() {
+ return $this->mMagicPMIDLinks;
+ }
+ /**
+ * @since 1.28
+ * @return bool
+ */
+ public function getMagicRFCLinks() {
+ return $this->mMagicRFCLinks;
+ }
public function setInterwikiMagic( $x ) {
return wfSetVar( $this->mInterwikiMagic, $x );
}
return wfSetVar( $this->mIsPrintable, $x );
}
+ /**
+ * @since 1.28
+ */
+ public function setMagicISBNLinks( $x ) {
+ return wfSetVar( $this->mMagicISBNLinks, $x );
+ }
+
+ /**
+ * @since 1.28
+ */
+ public function setMagicPMIDLinks( $x ) {
+ return wfSetVar( $this->mMagicPMIDLinks, $x );
+ }
+
+ /**
+ * @since 1.28
+ */
+ public function setMagicRFCLinks( $x ) {
+ return wfSetVar( $this->mMagicRFCLinks, $x );
+ }
+
/**
* Set the redirect target.
*
$wgAllowExternalImagesFrom, $wgEnableImageWhitelist, $wgAllowSpecialInclusion,
$wgMaxArticleSize, $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth,
$wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit,
- $wgMaxGeneratedPPNodeCount, $wgDisableLangConversion, $wgDisableTitleConversion;
+ $wgMaxGeneratedPPNodeCount, $wgDisableLangConversion, $wgDisableTitleConversion,
+ $wgEnableMagicLinks;
// *UPDATE* ParserOptions::matches() if any of this changes as needed
$this->mInterwikiMagic = $wgInterwikiMagic;
$this->mExternalLinkTarget = $wgExternalLinkTarget;
$this->mDisableContentConversion = $wgDisableLangConversion;
$this->mDisableTitleConversion = $wgDisableLangConversion || $wgDisableTitleConversion;
+ $this->mMagicISBNLinks = $wgEnableMagicLinks['ISBN'];
+ $this->mMagicPMIDLinks = $wgEnableMagicLinks['PMID'];
+ $this->mMagicRFCLinks = $wgEnableMagicLinks['RFC'];
$this->mUser = $user;
$this->mNumberHeadings = $user->getOption( 'numberheadings' );
* Values considered empty:
*
* - null
- * - array()
+ * - []
* - new XmlJsCode( '{}' )
- * - new stdClass() // (object) array()
+ * - new stdClass() // (object) []
*
* @param Array $array
*/
* // Scripts to always include
* 'scripts' => [file path string or array of file path strings],
* // Scripts to include in specific language contexts
- * 'languageScripts' => array(
+ * 'languageScripts' => [
* [language code] => [file path string or array of file path strings],
- * ),
+ * ],
* // Scripts to include in specific skin contexts
- * 'skinScripts' => array(
+ * 'skinScripts' => [
* [skin name] => [file path string or array of file path strings],
- * ),
+ * ],
* // Scripts to include in debug contexts
* 'debugScripts' => [file path string or array of file path strings],
* // Modules which must be loaded before this module
* 'dependencies' => [module name string or array of module name strings],
- * 'templates' => array(
+ * 'templates' => [
* [template alias with file.ext] => [file path to a template file],
- * ),
+ * ],
* // Styles to always load
* 'styles' => [file path string or array of file path strings],
* // Styles to include in specific skin contexts
- * 'skinStyles' => array(
+ * 'skinStyles' => [
* [skin name] => [file path string or array of file path strings],
- * ),
+ * ],
* // Messages to always load
* 'messages' => [array of message key strings],
* // Group which this module should be loaded together with
* Below is a description for the $options array:
* @par Construction options:
* @code
- * array(
+ * [
* // Base path to prepend to all local paths in $options. Defaults to $IP
* 'localBasePath' => [base path],
* // Path to JSON file that contains any of the settings below
* 'selectorWithoutVariant' => [CSS selector template, variables: {prefix} {name}],
* 'selectorWithVariant' => [CSS selector template, variables: {prefix} {name} {variant}],
* // List of variants that may be used for the image files
- * 'variants' => array(
- * [theme name] => array(
- * [variant name] => array(
+ * 'variants' => [
+ * [theme name] => [
+ * [variant name] => [
* 'color' => [color string, e.g. '#ffff00'],
* 'global' => [boolean, if true, this variant is available
* for all images of this type],
- * ),
+ * ],
* ...
- * ),
+ * ],
* ...
- * ),
+ * ],
* // List of image files and their options
- * 'images' => array(
- * [theme name] => array(
- * [icon name] => array(
+ * 'images' => [
+ * [theme name] => [
+ * [icon name] => [
* 'file' => [file path string or array whose values are file path strings
* and whose keys are 'default', 'ltr', 'rtl', a single
* language code like 'en', or a list of language codes like
* 'en,de,ar'],
* 'variants' => [array of variant name strings, variants
* available for this image],
- * ),
+ * ],
* ...
- * ),
+ * ],
* ...
- * ),
- * )
+ * ],
+ * ]
* @endcode
* @throws InvalidArgumentException
*/
]
);
- $dbw->onTransactionResolution( function () use ( &$scopeLock ) {
- ScopedCallback::consume( $scopeLock ); // release after commit
- } );
+ if ( $dbw->trxLevel() ) {
+ $dbw->onTransactionResolution( function () use ( &$scopeLock ) {
+ ScopedCallback::consume( $scopeLock ); // release after commit
+ } );
+ }
}
} catch ( Exception $e ) {
wfDebugLog( 'resourceloader', __METHOD__ . ": failed to update DB: $e" );
*
* @code
* $summary = parent::getDefinitionSummary( $context );
- * $summary[] = array(
+ * $summary[] = [
* 'foo' => 123,
* 'bar' => 'quux',
- * );
+ * ];
* return $summary;
* @endcode
*
/**
* Get the string representation of the token at a timestamp
- * @param int timestamp
+ * @param int $timestamp
* @return string
*/
protected function toStringAtTimestamp( $timestamp ) {
*
* If a "data" key is present, it must be an array, where the keys represent
* the data-xxx properties with their provided values. For example,
- * $item['data'] = array(
+ * $item['data'] = [
* 'foo' => 1,
* 'bar' => 'baz',
- * );
+ * ];
* will render as element properties:
* data-foo='1' data-bar='baz'
*
* a link in. This should be an array of arrays containing a 'tag' and
* optionally an 'attributes' key. If you only have one element you don't
* need to wrap it in another array. eg: To use <a><span>...</span></a>
- * in all links use array( 'text-wrapper' => array( 'tag' => 'span' ) )
+ * in all links use [ 'text-wrapper' => [ 'tag' => 'span' ] ]
* for your options.
* - 'link-class' key can be used to specify additional classes to apply
* to all links.
*
* BaseTemplate::getSidebar can be used to simplify the format and id generation in new skins.
*
- * The format of the returned array is array( heading => content, ... ), where:
+ * The format of the returned array is [ heading => content, ... ], where:
* - heading is the heading of a navigation portlet. It is either:
* - magic string to be handled by the skins ('SEARCH' / 'LANGUAGES' / 'TOOLBOX' / ...)
* - a message name (e.g. 'navigation'), the message should be HTML-escaped by the skin
$content_navigation['namespaces'][$talkId]['context'] = 'talk';
if ( $userCanRead ) {
- $isForeignFile = $title->inNamespace( NS_FILE ) && $this->canUseWikiPage() &&
- $this->getWikiPage() instanceof WikiFilePage && !$this->getWikiPage()->isLocal();
-
- // Adds view view link
- if ( $title->exists() || $isForeignFile ) {
+ // Adds "view" view link
+ if ( $title->isKnown() ) {
$content_navigation['views']['view'] = $this->tabAction(
$isTalk ? $talkPage : $subjectPage,
[ "$skname-view-view", 'view' ],
$content_navigation['views']['view']['redundant'] = true;
}
+ $isForeignFile = $title->inNamespace( NS_FILE ) && $this->canUseWikiPage() &&
+ $this->getWikiPage() instanceof WikiFilePage && !$this->getWikiPage()->isLocal();
+
// If it is a non-local file, show a link to the file in its own repository
+ // @todo abstract this for remote content that isn't a file
if ( $isForeignFile ) {
$file = $this->getWikiPage()->getFile();
$content_navigation['views']['view-foreign'] = [
'href' => $title->getLocalURL( 'action=edit§ion=new' )
];
}
- // Checks if the page has some kind of viewable content
+ // Checks if the page has some kind of viewable source content
} elseif ( $title->hasSourceText() ) {
// Adds view source view link
$content_navigation['views']['viewsource'] = [
] );
if ( $this->operation === 'insert' || !empty( $data['resetPassword'] ) ) {
- $this->password = PasswordFactory::generateRandomPasswordString(
- max( 32, $this->getConfig()->get( 'MinimalPasswordLength' ) )
- );
+ $this->password = BotPassword::generatePassword( $this->getConfig() );
$passwordFactory = new PasswordFactory();
$passwordFactory->init( RequestContext::getMain()->getConfig() );
$password = $passwordFactory->newFromPlaintext( $this->password );
$out->addWikiMsg(
'botpasswords-newpassword',
htmlspecialchars( $username . $sep . $this->par ),
- htmlspecialchars( $this->password )
+ htmlspecialchars( $this->password ),
+ htmlspecialchars( $username ),
+ htmlspecialchars( $this->par . $sep . $this->password )
);
$this->password = null;
}
protected $explicitlyDefinedTags;
/**
- * @var array List of extension defined tags
+ * @var array List of software defined tags
*/
- protected $extensionDefinedTags;
+ protected $softwareDefinedTags;
/**
- * @var array List of extension activated tags
+ * @var array List of software activated tags
*/
- protected $extensionActivatedTags;
+ protected $softwareActivatedTags;
function __construct() {
parent::__construct( 'Tags' );
// Used in #doTagRow()
$this->explicitlyDefinedTags = array_fill_keys(
ChangeTags::listExplicitlyDefinedTags(), true );
- $this->extensionDefinedTags = array_fill_keys(
- ChangeTags::listExtensionDefinedTags(), true );
+ $this->softwareDefinedTags = array_fill_keys(
+ ChangeTags::listSoftwareDefinedTags(), true );
// List all defined tags, even if they were never applied
- $definedTags = array_keys( $this->explicitlyDefinedTags + $this->extensionDefinedTags );
+ $definedTags = array_keys( $this->explicitlyDefinedTags + $this->softwareDefinedTags );
// Show header only if there exists atleast one tag
if ( !$tagStats && !$definedTags ) {
);
// Used in #doTagRow()
- $this->extensionActivatedTags = array_fill_keys(
- ChangeTags::listExtensionActivatedTags(), true );
+ $this->softwareActivatedTags = array_fill_keys(
+ ChangeTags::listSoftwareActivatedTags(), true );
// Insert tags that have been applied at least once
foreach ( $tagStats as $tag => $hitcount ) {
$newRow .= Xml::tags( 'td', null, $desc );
$sourceMsgs = [];
- $isExtension = isset( $this->extensionDefinedTags[$tag] );
+ $isSoftware = isset( $this->softwareDefinedTags[$tag] );
$isExplicit = isset( $this->explicitlyDefinedTags[$tag] );
- if ( $isExtension ) {
+ if ( $isSoftware ) {
+ // TODO: Rename this message
$sourceMsgs[] = $this->msg( 'tags-source-extension' )->escaped();
}
if ( $isExplicit ) {
}
$newRow .= Xml::tags( 'td', null, implode( Xml::element( 'br' ), $sourceMsgs ) );
- $isActive = $isExplicit || isset( $this->extensionActivatedTags[$tag] );
+ $isActive = $isExplicit || isset( $this->softwareActivatedTags[$tag] );
$activeMsg = ( $isActive ? 'tags-active-yes' : 'tags-active-no' );
$newRow .= Xml::tags( 'td', null, $this->msg( $activeMsg )->escaped() );
$preText .= $this->msg( 'tags-delete-explanation-warning', $tag )->parseAsBlock();
// see if the tag is in use
- $this->extensionActivatedTags = array_fill_keys(
- ChangeTags::listExtensionActivatedTags(), true );
- if ( isset( $this->extensionActivatedTags[$tag] ) ) {
+ $this->softwareActivatedTags = array_fill_keys(
+ ChangeTags::listSoftwareActivatedTags(), true );
+ if ( isset( $this->softwareActivatedTags[$tag] ) ) {
$preText .= $this->msg( 'tags-delete-explanation-active', $tag )->parseAsBlock();
}
* @ingroup SpecialPage
*/
class UserrightsPage extends SpecialPage {
- # The target of the local right-adjuster's interest. Can be gotten from
- # either a GET parameter or a subpage-style parameter, so have a member
- # variable for it.
+ /**
+ * The target of the local right-adjuster's interest. Can be gotten from
+ * either a GET parameter or a subpage-style parameter, so have a member
+ * variable for it.
+ * @var null|string $mTarget
+ */
protected $mTarget;
/*
* @var null|User $mFetchedUser The user object of the target username or null.
$this->mTarget = $request->getVal( 'user' );
}
+ if ( is_string( $this->mTarget ) ) {
+ $this->mTarget = trim( $this->mTarget );
+ }
+
$available = $this->changeableGroups();
if ( $this->mTarget === null ) {
return (bool)$dbw->affectedRows();
}
+ /**
+ * Returns a (raw, unhashed) random password string.
+ * @param Config $config
+ * @return string
+ */
+ public static function generatePassword( $config ) {
+ return PasswordFactory::generateRandomPasswordString(
+ max( 32, $config->get( 'MinimalPasswordLength' ) ) );
+ }
+
+ /**
+ * There are two ways to login with a bot password: "username@appId", "password" and
+ * "username", "appId@password". Transform it so it is always in the first form.
+ * Returns [bot username, bot password, could be normal password?] where the last one is a flag
+ * meaning this could either be a bot password or a normal password, it cannot be decided for
+ * certain (although in such cases it almost always will be a bot password).
+ * If this cannot be a bot password login just return false.
+ * @param string $username
+ * @param string $password
+ * @return array|false
+ */
+ public static function canonicalizeLoginData( $username, $password ) {
+ $sep = BotPassword::getSeparator();
+ if ( strpos( $username, $sep ) !== false ) {
+ // the separator is not valid in usernames so this must be a bot login
+ return [ $username, $password, false ];
+ } elseif ( strlen( $password ) > 32 && strpos( $password, $sep ) !== false ) {
+ // the strlen check helps minimize the password information obtainable from timing
+ $segments = explode( $sep, $password );
+ $password = array_pop( $segments );
+ $appId = implode( $sep, $segments );
+ if ( preg_match( '/^[0-9a-w]{32,}$/', $password ) ) {
+ return [ $username . $sep . $appId, $password, true ];
+ }
+ }
+ return false;
+ }
+
/**
* Try to log the user in
* @param string $username Combined user name and app ID
const AUDIENCE_PUBLIC = 1;
const AUDIENCE_RAW = 2;
- /** @var CentralIdLookup[][] */
+ /** @var CentralIdLookup[] */
private static $instances = [];
/** @var string */
}
$audience = $this->checkAudience( $audience );
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
- $options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
- ? [ 'LOCK IN SHARE MODE' ]
- : [];
+ list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags );
+ $db = wfGetDB( $index );
$tables = [ 'user' ];
$fields = [ 'user_id', 'user_name' ];
}
$audience = $this->checkAudience( $audience );
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
- $options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
- ? [ 'LOCK IN SHARE MODE' ]
- : [];
+ list( $index, $options ) = DBAccessObjectUtils::getDBOptions( $flags );
+ $db = wfGetDB( $index );
$tables = [ 'user' ];
$fields = [ 'user_id', 'user_name' ];
* @note If the user doesn't have 'editmywatchlist', this will do nothing.
*/
public function clearAllNotifications() {
- if ( wfReadOnly() ) {
- return;
- }
-
+ global $wgUseEnotif, $wgShowUpdatedMarker;
// Do nothing if not allowed to edit the watchlist
- if ( !$this->isAllowed( 'editmywatchlist' ) ) {
+ if ( wfReadOnly() || !$this->isAllowed( 'editmywatchlist' ) ) {
return;
}
- global $wgUseEnotif, $wgShowUpdatedMarker;
if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
$this->setNewtalk( false );
return;
}
+
$id = $this->getId();
- if ( $id != 0 ) {
- $dbw = wfGetDB( DB_MASTER );
- $dbw->update( 'watchlist',
- [ /* SET */ 'wl_notificationtimestamp' => null ],
- [ /* WHERE */ 'wl_user' => $id, 'wl_notificationtimestamp IS NOT NULL' ],
- __METHOD__
- );
- // We also need to clear here the "you have new message" notification for the own user_talk page;
- // it's cleared one page view later in WikiPage::doViewUpdates().
+ if ( !$id ) {
+ return;
}
+
+ $dbw = wfGetDB( DB_MASTER );
+ $asOfTimes = array_unique( $dbw->selectFieldValues(
+ 'watchlist',
+ 'wl_notificationtimestamp',
+ [ 'wl_user' => $id, 'wl_notificationtimestamp IS NOT NULL' ],
+ __METHOD__,
+ [ 'ORDER BY' => 'wl_notificationtimestamp DESC', 'LIMIT' => 500 ]
+ ) );
+ if ( !$asOfTimes ) {
+ return;
+ }
+ // Immediately update the most recent touched rows, which hopefully covers what
+ // the user sees on the watchlist page before pressing "mark all pages visited"....
+ $dbw->update(
+ 'watchlist',
+ [ 'wl_notificationtimestamp' => null ],
+ [ 'wl_user' => $id, 'wl_notificationtimestamp' => $asOfTimes ],
+ __METHOD__
+ );
+ // ...and finish the older ones in a post-send update with lag checks...
+ DeferredUpdates::addUpdate( new AutoCommitUpdate(
+ $dbw,
+ __METHOD__,
+ function () use ( $dbw, $id ) {
+ global $wgUpdateRowsPerQuery;
+
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
+ $asOfTimes = array_unique( $dbw->selectFieldValues(
+ 'watchlist',
+ 'wl_notificationtimestamp',
+ [ 'wl_user' => $id, 'wl_notificationtimestamp IS NOT NULL' ],
+ __METHOD__
+ ) );
+ foreach ( array_chunk( $asOfTimes, $wgUpdateRowsPerQuery ) as $asOfTimeBatch ) {
+ $dbw->update(
+ 'watchlist',
+ [ 'wl_notificationtimestamp' => null ],
+ [ 'wl_user' => $id, 'wl_notificationtimestamp' => $asOfTimeBatch ],
+ __METHOD__
+ );
+ $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
+ }
+ }
+ ) );
+ // We also need to clear here the "you have new message" notification for the own
+ // user_talk page; it's cleared one page view later in WikiPage::doViewUpdates().
}
/**
"resources/src/mediawiki.toolbar",
"resources/src/mediawiki.widgets",
"resources/src/jquery/jquery.accessKeyLabel.js",
- "resources/src/jquery/jquery.arrowSteps.js",
"resources/src/jquery/jquery.autoEllipsis.js",
"resources/src/jquery/jquery.badge.js",
"resources/src/jquery/jquery.byteLength.js",
"botpasswords-updated-body": "كلمة سر البوت \"$1\" للمستخدم \"$2\" تم تحديثها.",
"botpasswords-deleted-title": "كلمة سر البوت حذفت",
"botpasswords-deleted-body": "كلمة سر البوت \"$1\" لمستخدم \"$2\" قد حذفت.",
- "botpasswords-newpassword": "كلمة السر الجديدة لتسجيل الدخول ب <strong>$1</strong> هي <strong>$2</strong>. <em>من فضلك سجل هذه كمرجع في المستقبل .</em>",
+ "botpasswords-newpassword": "كلمة السر الجديدة لتسجيل الدخول ب <strong>$1</strong> هي <strong>$2</strong>. <em>من فضلك سجل هذه كمرجع في المستقبل .</em><br> (للبوتات القديمة التي تتطلب أن يكون اسم تسجيل الدخول مثل اسم المستخدم النهائي، يمكنك أيضا استخدام <strong>$3</strong> كاسم مستخدم و <strong>$4</strong> ككلمة سر.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider غير متاح.",
"botpasswords-restriction-failed": "قيود كلمة مرور البوت تمنع هذا الولوج.",
"botpasswords-invalid-name": "اسم المستخدم الموفر لا يحتوي على فاصل كلمة سر البوت (\"$1\").",
"invalid-content-data": "بيانات المحتوى غير صالحة",
"content-not-allowed-here": "\"$1\" المحتوى غير مسموح على صفحة [[$2]]",
"editwarning-warning": "مغادرة هذه الصفحة قد تتسبب بخسارتك لأي تغييرات أجريتها.\nإذا كنت مسجل الدخول، فيمكنك تعطيل هذا التحذير في قسم \"{{int:prefs-editing}}\" في تفضيلاتك.",
+ "editpage-invalidcontentmodel-title": "موديل المحتوى غير مدعوم",
+ "editpage-invalidcontentmodel-text": "موديل المحتوى \"$1\" غير مدعوم.",
"editpage-notsupportedcontentformat-title": "تنسيق المحتوى غير مدعوم",
"editpage-notsupportedcontentformat-text": "تنسيق المحتوى $1 غير مدعوم بواسطة نموذج المحتوى $2.",
"content-model-wikitext": "نص ويكي",
"print.css": "/* الأنماط المتراصة CSS المعروضة هنا ستؤثر على ناتج الطباعة */",
"noscript.css": "/* الأنماط المتراصة CSS المعروضة هنا ستؤثر على المستخدمين الذين الجافاسكريبت لديهم معطلة */",
"group-autoconfirmed.css": "/* الأنماط المتراصة CSS المعروضة هنا ستؤثر على المستخدمين المؤكدين تلقائيا فقط */",
+ "group-user.css": "/* CSS المعروض هنا سيؤثر على المستخدمين المسجلين فقط */",
"group-bot.css": "/* الأنماط المتراصة CSS المعروضة هنا ستؤثر على البوتات فقط */",
"group-sysop.css": "/* الأنماط المتراصة CSS المعروضة هنا ستؤثر على الإداريين فقط */",
"group-bureaucrat.css": "/* الأنماط المتراصة CSS المعروضة هنا ستؤثر على البيروقراطيين فقط */",
"common.js": "/* الجافاسكريبت الموضوع هنا سيتم تحميله لكل المستخدمين مع كل تحميل للصفحة. */",
"group-autoconfirmed.js": "/* أي جافاسكريبت هنا سيتم تحميلها للمستخدمين المؤكدين تلقائيا فقط */",
+ "group-user.js": "/* أي JavaScript هنا سيتم تحميله للمستخدمين المسجلين فقط */",
"group-bot.js": "/* أي جافاسكريبت هنا سيتم تحميلها للبوتات فقط */",
"group-sysop.js": "/* أي جافاسكريبت هنا سيتم تحميلها للإداريين فقط */",
"group-bureaucrat.js": "/* أي جافاسكريبت هنا سيتم تحميلها للبيروقراطيين فقط */",
"tag-filter": "مرشح [[Special:Tags|الوسوم]]:",
"tag-filter-submit": "مرشح",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1||وسم|وسمان|وسوم}}]]: $2)",
+ "tag-mw-contentmodelchange": "تغيير موديل المحتوى",
+ "tag-mw-contentmodelchange-description": "التعديلات التي [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel تغير موديل المحتوى] لصفحة",
"tags-title": "وسوم",
"tags-intro": "هذه الصفحة تعرض الوسوم التي ربما يعلم البرنامج تعديلا بها، ومعانيها.",
"tags-tag": "اسم الوسم",
"tags-actions-header": "إجراءات",
"tags-active-yes": "نعم",
"tags-active-no": "لا",
- "tags-source-extension": "Ù\8aعرÙ\81Ù\87 اÙ\85تداد",
+ "tags-source-extension": "Ù\85عرÙ\81 بÙ\88اسطة اÙ\84برÙ\86اÙ\85ج",
"tags-source-manual": "تم تطبيقه يدويا بواسطة المستخدمين والبوتات.",
"tags-source-none": "لم يعد قيد الاستخدام",
"tags-edit": "عدل",
"createacct-yourpasswordagain-ph": "Escriba nuevamente la contraseña",
"userlogin-remembermypassword": "Caltener abierta la sesión",
"userlogin-signwithsecure": "Usar una conexón segura",
+ "cannotlogin-title": "Nun pudo aniciase sesión",
+ "cannotlogin-text": "Nun ye posible aniciar sesión.",
"cannotloginnow-title": "Nun puede aniciase sesión agora",
"cannotloginnow-text": "Nun puede aniciase sesión cuando s'usa $1.",
+ "cannotcreateaccount-title": "Nun pueden crease cuentes",
+ "cannotcreateaccount-text": "La creación direuta de cuentes nun ta activada nesta wiki.",
"yourdomainname": "El to dominiu:",
"password-change-forbidden": "Nun se pueden camudar les contraseñes nesta wiki.",
"externaldberror": "O hebo un fallu d'autenticación de la base de datos o nun tienes permisu p'anovar la to cuenta esterna.",
"pageinfo-article-id": "ID de la páxina",
"pageinfo-language": "Llingua del conteníu de la páxina",
"pageinfo-content-model": "Plantía del conteníu de la páxina",
+ "pageinfo-content-model-change": "camudar",
"pageinfo-robot-policy": "Indexación por robots",
"pageinfo-robot-index": "Permitío",
"pageinfo-robot-noindex": "Torgao",
"createacct-yourpasswordagain-ph": "Увядзіце пароль зноў",
"userlogin-remembermypassword": "Запомніць мяне",
"userlogin-signwithsecure": "Скарыстацца бясьпечным злучэньнем",
+ "cannotlogin-title": "Немагчыма ўвайсьці",
+ "cannotlogin-text": "Уваход у сыстэму немагчымы.",
"cannotloginnow-title": "Цяпер немагчыма ўвайсьці",
"cannotloginnow-text": "Уваход у сыстэму немагчымы пры выкарыстаньні $1.",
+ "cannotcreateaccount-title": "Немагчыма стварыць рахункі",
+ "cannotcreateaccount-text": "Непасрэднае стварэньне рахункаў ня ўключана ў гэтай вікі.",
"yourdomainname": "Ваш дамэн:",
"password-change-forbidden": "Вы ня можаце зьмяняць паролі ў гэтай вікі.",
"externaldberror": "Адбылася памылка аўтэнтыфікацыі з дапамогай вонкавай базы зьвестак, ці Вам не дазволена абнаўляць свой рахунак.",
"botpasswords-updated-body": "Пароль робата для робата «$1» удзельніка «$2» быў абноўлены.",
"botpasswords-deleted-title": "Пароль робата выдалены",
"botpasswords-deleted-body": "Пароль робата для робата «$1» удзельніка «$2» быў выдалены.",
- "botpasswords-newpassword": "Новы пароль для ўваходу пад <strong>$1</strong> — <strong>$2</strong>. <em>Калі ласка, запішыце яго для далейшага выкарыстаньня.</em>",
+ "botpasswords-newpassword": "Новы пароль для ўваходу пад <strong>$1</strong> — <strong>$2</strong>. <em>Калі ласка, запішыце яго для далейшага выкарыстаньня.</em><br>(Для старых робатаў, якія патрабуюць, каб імя для ўваходу было аднолькавым з патэнцыйным імем удзельніка, вы можаце таксама карыстацца <strong>$3</strong> у якасьці імя і <strong>$4</strong> у якасьці паролю.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider недаступны.",
"botpasswords-restriction-failed": "Уваход ня выкананы праз абмежаваньні на пароль робата",
"botpasswords-invalid-name": "Пададзенае імя ўдзельніка ня ўтрымлівае падзяляльнік для паролю робата («$1»).",
"createacct-yourpasswordagain-ph": "Увядзіце пароль яшчэ раз",
"userlogin-remembermypassword": "Заставацца ў сістэме",
"userlogin-signwithsecure": "Выкарыстоўваць абароненае злучэнне",
+ "cannotlogin-title": "Немагчыма ўвайсці",
+ "cannotlogin-text": "Уваход у сістэму немагчымы.",
"cannotloginnow-title": "Зараз немагчыма ўвайсці",
"cannotloginnow-text": "Пры выкарыстанні $1 немагчыма прадставіцца сістэме.",
+ "cannotcreateaccount-title": "Немагчыма стварыць уліковыя запісы",
+ "cannotcreateaccount-text": "Непасрэднае стварэнне ўліковых запісаў не ўключана на гэтай вікі.",
"yourdomainname": "Ваш дамен:",
"password-change-forbidden": "Вы не можаце змяняць паролі на гэтай Вікі.",
"externaldberror": "Або памылка вонкавай аўтэнтыкацыі ў базе дадзеных, або вам не дазволена абнаўляць свой вонкавы рахунак.",
"uploaded-href-attribute-svg": "у SVG файлах атрыбутам href дазволены толькі мэты віду http:// або https://, знойдзена <code><$1 $2=\"$3\"></code>.",
"uploaded-href-unsafe-target-svg": "У ўкладзеным SVG файле знойдзена спасылка на небяспечныя звесткі: URI мэты <code><$1 $2=\"$3\"></code>.",
"uploaded-animate-svg": "У ўкладзеным SVG файле знойдзены тэг \"animate\", здольны змяніць спасылку з дапамогай атрыбута \"from\" <code><$1 $2=\"$3\"></code>.",
+ "uploaded-setting-event-handler-svg": "Устаноўка атрыбутаў апрацоўкі падзей заблакавана, у ўкладзеным SVG-файле знойдзены код <code><$1 $2=\"$3\"></code>.",
+ "uploaded-setting-href-svg": "Выкарыстанне тэга \"set\" для дадання атрыбута \"href\" у бацькоўскі элемент заблакавана.",
"uploadscriptednamespace": "Гэты файл SVG утрымлівае недапушчальную прастору імёнаў \"$1\".",
"uploadinvalidxml": "Немагчыма прааналізаваць XML ва ўкладзеным файле.",
"uploadvirus": "Файл утрымлівае вірус! Падрабязнасці: $1",
"cannotlogin-title": "প্রবেশ করতে পারবেন না",
"cannotloginnow-title": "এখন প্রবেশ করা যাবে না",
"cannotloginnow-text": "$1 ব্যবহার করার সময় প্রবেশ করা সম্ভব নয়।",
+ "cannotcreateaccount-title": "অ্যাকাউন্ট তৈরি করা যাবে না",
"yourdomainname": "আপনার ডোমেইন:",
"password-change-forbidden": "আপনি এই উইকিতে পাসওয়ার্ড পরিবর্তন করতে পারবেন না।",
"externaldberror": "হয় কোন বহিঃস্থ যাচাইকরণ ডাটাবেজ ত্রুটি ঘটেছে অথবা আপনার বহিঃস্থ অ্যাকাউন্ট হালনাগাদ করার অনুমতি নেই।",
"apisandbox-retry": "পুনঃচেষ্টা করুন",
"apisandbox-loading": "\"$1\" এপিআই মডিউলের জন্য তথ্য লোড হচ্ছে...",
"apisandbox-load-error": "\"$1\" এপিআই মডিউলের জন্য তথ্য লোড করার সময় একটি ত্রুটি ঘটেছে: $2",
+ "apisandbox-no-parameters": "এই API মডিউলের কোন প্যারামিটার নেই।",
"apisandbox-helpurls": "সাহায্যকারী লিঙ্কসমূহ",
"apisandbox-examples": "উদাহরণ",
"apisandbox-dynamic-parameters": "অতিরিক্ত প্যারামিটার",
"tags-actions-header": "কার্যসমূহ",
"tags-active-yes": "হ্যাঁ",
"tags-active-no": "না",
- "tags-source-extension": "à¦\8fà¦\95à¦\9fি à¦\8fà¦\95à§\8dসà¦\9fà§\87নশন দ্বারা সংজ্ঞায়িত",
+ "tags-source-extension": "সফà¦\9fà¦\93য়à§\8dযার দ্বারা সংজ্ঞায়িত",
"tags-source-manual": "ব্যবহারকারী এবং বট দ্বারা ম্যানুয়ালি প্রয়োগ",
"tags-source-none": "আর ব্যবহার করা হচ্ছে না",
"tags-edit": "সম্পাদনা",
"tags-delete-submit": "অপরিবর্তনীয় এই ট্যাগ অপসারন করো",
"tags-delete-not-found": "\"$1\" ট্যাগ বিদ্যমান নয়।",
"tags-activate-title": "সক্রিয় ট্যাগ",
+ "tags-activate-question": "আপনি ট্যাগ \"$1\" সক্রিয় করতে চলেছেন।",
"tags-activate-reason": "কারণ:",
+ "tags-activate-not-allowed": "ট্যাগ \"$1\" সক্রিয় করা সম্ভব নয়।",
+ "tags-activate-not-found": "\"$1\" ট্যাগের অস্তিত্ব নেই।",
"tags-activate-submit": "চালু",
"tags-deactivate-title": "নিষ্ক্রিয় ট্যাগ",
+ "tags-deactivate-question": "আপনি ট্যাগ \"$1\" নিষ্ক্রিয় করতে চলেছেন।",
"tags-deactivate-reason": "কারণ:",
+ "tags-deactivate-not-allowed": "ট্যাগ \"$1\" নিষ্ক্রিয় করা সম্ভব নয়।",
"tags-deactivate-submit": "নিষ্ক্রিয়",
"tags-edit-title": "ট্যাগ সম্পাদনা করুন",
"tags-edit-manage-link": "ট্যাগ পরিচালনা করুন",
"authform-wrongtoken": "ভুল টোকেন",
"specialpage-securitylevel-not-allowed-title": "অনুমতি নেই",
"specialpage-securitylevel-not-allowed": "দুঃখিত, আপনি এই পাতা ব্যবহার করতে অনুমতিপ্রাপ্ত নন কারণ আপনার পরিচয় যাচাই করা যায়নি।",
+ "authpage-cannot-login": "প্রবেশ শুরু করা সম্ভন নয়।",
"cannotauth-not-allowed-title": "অনুমতি অস্বীকৃত",
"cannotauth-not-allowed": "আপনি এই পাতাটি ব্যবহার করতে অনুমতিপ্রাপ্ত নন।",
"changecredentials": "পরিচয়পত্র পরিবর্তন করুন",
"whatlinkshere-next": "{{PLURAL:$1|دیکە|$1ی تر}}",
"whatlinkshere-links": "← بەستەرەکان",
"whatlinkshere-hideredirs": "ڕەوانەکەرەکان $1",
- "whatlinkshere-hidetrans": "$1 ھێنانەناوەوەکان",
+ "whatlinkshere-hidetrans": "ھێنانەناوەوەکان $1",
"whatlinkshere-hidelinks": "$1 بەستەر",
"whatlinkshere-hideimages": "$1 بەستەرەکانی پەڕگە",
"whatlinkshere-filters": "پاڵێوکەکان",
"createacct-yourpasswordagain-ph": "Zadejte heslo ještě jednou",
"userlogin-remembermypassword": "Přihlásit trvale",
"userlogin-signwithsecure": "Používat zabezpečené připojení",
+ "cannotlogin-title": "Nelze se přihlásit",
+ "cannotlogin-text": "Přihlášení není možné.",
"cannotloginnow-title": "Momentálně se nelze přihlásit",
"cannotloginnow-text": "Přihlášení není možné, když se používají $1.",
+ "cannotcreateaccount-title": "Nelze zakládat uživatelské účty",
+ "cannotcreateaccount-text": "Přímé zakládání účtů není na této wiki povoleno.",
"yourdomainname": "Vaše doména",
"password-change-forbidden": "Na této wiki nemůžete měnit hesla.",
"externaldberror": "Buď nastala chyba externí autentizační databáze, nebo nemáte dovoleno měnit svůj externí účet.",
"botpasswords-updated-body": "Heslo pro bota jménem „$1“ {{GENDER:$2|uživatele|uživatelky}} „$2“ bylo aktualizováno.",
"botpasswords-deleted-title": "Heslo pro bota smazáno",
"botpasswords-deleted-body": "Heslo pro bota jménem „$1“ {{GENDER:$2|uživatele|uživatelky}} „$2“ bylo smazáno.",
- "botpasswords-newpassword": "Nové přihlašovací heslo pro bota <strong>$1</strong> je <strong>$2</strong>. <em>Zaznamenejte si je pro budoucí použití.</em>",
+ "botpasswords-newpassword": "Nové přihlašovací heslo pro bota <strong>$1</strong> je <strong>$2</strong>. <em>Zaznamenejte si je pro budoucí použití.</em> <br> (Pro staré boty, vyžadující, aby přihlašovací jméno bylo stejné jako následné uživatelské jméno, můžete také jako uživatelské jméno použít <strong>$3</strong> a jako heslo <strong>$4</strong>.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider není dostupný.",
"botpasswords-restriction-failed": "Toto přihlášení bylo zamítnuto omezením hesel pro boty.",
"botpasswords-invalid-name": "Uvedené uživatelské jméno neobsahuje oddělovač hesel pro boty („$1“).",
"invalid-content-data": "Obsažená data jsou chybná",
"content-not-allowed-here": "Obsah typu $1 není na stránce [[$2]] dovolen.",
"editwarning-warning": "Opuštěním této stránky se mohou veškeré provedené změny ztratit.\nPřihlášení uživatelé si mohou toto varování vypnout na záložce „{{int:prefs-editing}}“ v uživatelském nastavení.",
+ "editpage-invalidcontentmodel-title": "Nepodporovaný model obsahu",
+ "editpage-invalidcontentmodel-text": "Model obsahu „$1“ není podporován.",
"editpage-notsupportedcontentformat-title": "Nepodporovaný formát obsahu",
"editpage-notsupportedcontentformat-text": "Model obsahu $2 nepodporuje formát obsahu $1.",
"content-model-wikitext": "wikitext",
"tag-filter": "Filtr podle [[Special:Tags|značek]]:",
"tag-filter-submit": "Filtrovat",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Značka|Značky}}]]: $2)",
+ "tag-mw-contentmodelchange": "změna modelu obsahu",
+ "tag-mw-contentmodelchange-description": "Editace, které [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel mění obsah modelu] stránky",
"tags-title": "Značky",
"tags-intro": "Tato stránka obsahuje seznam značek, kterými může software označovat jednotlivé editace, a jejich významy.",
"tags-tag": "Název značky",
"tags-actions-header": "Akce",
"tags-active-yes": "Ano",
"tags-active-no": "Ne",
- "tags-source-extension": "Definována rozšířením",
+ "tags-source-extension": "Definována softwarem",
"tags-source-manual": "Přidávána ručně uživateli a boty",
"tags-source-none": "Už nepoužívána",
"tags-edit": "editovat",
"botpasswords-updated-body": "Das Botpasswort für den Botnamen „$1“ des Benutzers „$2“ wurde aktualisiert.",
"botpasswords-deleted-title": "Botpasswort gelöscht",
"botpasswords-deleted-body": "Das Botpasswort für den Botnamen „$1“ des Benutzers „$2“ wurde gelöscht.",
- "botpasswords-newpassword": "Das neue Passwort zur Anmeldung mit <strong>$1</strong> ist <strong>$2</strong>. <em>Bitte halte dies für die Zukunft fest.</em>",
+ "botpasswords-newpassword": "Das neue Passwort zur Anmeldung mit <strong>$1</strong> ist <strong>$2</strong>. <em>Bitte halte dies für die Zukunft fest.</em><br>Für alte Bots, die erfordern, dass der Anmeldename mit dem späteren Benutzernamen identisch ist, kannst du auch <strong>$3</strong> als Benutzernamen und <strong>$4</strong> als Passwort verwenden.",
"botpasswords-no-provider": "BotPasswordsSessionProvider ist nicht verfügbar.",
"botpasswords-restriction-failed": "Beschränkungen des Botpassworts verhindern diese Anmeldung.",
"botpasswords-invalid-name": "Der angegebene Benutzername enthält keinen Botpassworttrenner („$1“).",
"invalid-content-data": "Ungültige Inhaltsdaten",
"content-not-allowed-here": "Der Inhalt „$1“ ist auf der Seite [[$2]] nicht erlaubt",
"editwarning-warning": "Das Verlassen dieser Seite kann dazu führen, dass deine Änderungen verloren gehen.\nWenn du angemeldet bist, kannst du das Anzeigen dieser Warnung im Bereich „{{int:prefs-editing}}“ deiner Einstellungen abschalten.",
+ "editpage-invalidcontentmodel-title": "Das Inhaltsmodell wird nicht unterstützt.",
+ "editpage-invalidcontentmodel-text": "Das Inhaltsmodell „$1“ wird nicht unterstützt.",
"editpage-notsupportedcontentformat-title": "Das Inhaltsformat wird nicht unterstützt",
"editpage-notsupportedcontentformat-text": "Das Inhaltsformat $1 wird vom Inhaltsmodell $2 nicht unterstützt.",
"content-model-wikitext": "Wikitext",
"tag-filter": "[[Special:Tags|Markierungs]]-Filter:",
"tag-filter-submit": "Filter",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Markierung|Markierungen}}]]: $2)",
+ "tag-mw-contentmodelchange": "Änderung des Inhaltsmodells",
+ "tag-mw-contentmodelchange-description": "Bearbeitungen, die [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel das Inhaltsmodell einer Seite ändern]",
"tags-title": "Markierungen",
"tags-intro": "Diese Seite zeigt alle Markierungen, die für Bearbeitungen verwendet wurden, sowie deren Bedeutung. \n\nBei entsprechender Einstellung können die Missbrauchfilter beliebige Markierungen in die Versionsgeschichte setzen. Man kann die Versionsgeschichte dann nach den Markierungen filtern.",
"tags-tag": "Markierungsname",
"tags-actions-header": "Aktionen",
"tags-active-yes": "Ja",
"tags-active-no": "Nein",
- "tags-source-extension": "Definiert von einer Erweiterung",
+ "tags-source-extension": "Definiert von der Software",
"tags-source-manual": "Manuell von Benutzern und Bots eingesetzt",
"tags-source-none": "Nicht mehr in Verwendung",
"tags-edit": "bearbeiten",
"viewsourcelink": "çımey bıvêne",
"editsectionhint": "Leteyo ke bıvuriyo: $1",
"toc": "Sernameyê meselan",
- "showtoc": "bıasene",
+ "showtoc": "bımocne",
"hidetoc": "bınımne",
"collapsible-collapse": "Teng kı",
"collapsible-expand": "Hera ke",
"summary": "Xulasa:",
"subject": "Mewzu:",
"minoredit": "Vurriyayışo werdiyo",
- "watchthis": "Na pele seyr ke",
+ "watchthis": "Perrer bıpaw",
"savearticle": "Qeyd ke",
"savechanges": "Vurnayışan qeyd ke",
"publishpage": "Perer bıhesırne",
"rev-deleted-diff-view": "Jew timarkerdışê ena versiyon '''wedariyayo''.\nÎdarekarî şenê ena versiyon bivîne; belki tiya de [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} wedarnayişî] de teferruat esto.",
"rev-suppressed-diff-view": "Jew timarkerdışê ena versiyon '''Ploxneyış'' biyo.\nÎdarekarî eşkeno ena dif bivîne; belki tiya de [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ploxnayış] de teferruat esto.",
"rev-delundel": "bımocne/bınımne",
- "rev-showdeleted": "bıasene",
+ "rev-showdeleted": "bımocne",
"revisiondelete": "Çımraviyarnayışan bestere/peyser biya",
"revdelete-nooldid-title": "Çımraviyarnayışo waşte nêvêreno",
"revdelete-nooldid-text": "Şıma vıraştışê nê fonksiyoni rê ya yew çımraviyarnayışo waşte diyar nêkerdo, çımraviyarnayışo diyarkerde çıniyo, ya ki şıma wazenê ke çımraviyarnayışê nıkayêni bınımnê.",
"rcnotefrom": "Cêr de <strong>$2</strong> ra nata {{PLURAL:$5|vurnayışiyê}} asenê (tewr vêşi <strong>$1</strong> asenê) <strong>$3, $4</strong>",
"rclistfrom": "$3 $2 ra tepiya vurnayışanê neweyan bımocne",
"rcshowhideminor": "vurriyayışê werdi $1",
- "rcshowhideminor-show": "Bımocne",
+ "rcshowhideminor-show": "Bımusn",
"rcshowhideminor-hide": "Bınımne",
"rcshowhidebots": "botan $1",
"rcshowhidebots-show": "Bımocne",
"rcshowhidebots-hide": "Bınımne",
"rcshowhideliu": "karberê qeydbiyayeyi $1",
- "rcshowhideliu-show": "Bımocne",
+ "rcshowhideliu-show": "Bımusn",
"rcshowhideliu-hide": "Bınımne",
"rcshowhideanons": "karberê bênameyi $1",
"rcshowhideanons-show": "Bımocne",
"withoutinterwiki": "Pelê ke zıwananê binan rê gıreyê cı çıniyo",
"withoutinterwiki-summary": "Enê pelî ke versiyonê ziwanî binî ra link nidano.",
"withoutinterwiki-legend": "Verole",
- "withoutinterwiki-submit": "Bıasene",
+ "withoutinterwiki-submit": "Bımocne",
"fewestrevisions": "Pelê be senık çımraviyarnayışi",
"nbytes": "$1 {{PLURAL:$1|bayt|bayti}}",
"ncategories": "$1 {{PLURAL:$1|Kategori|Kategoriy}}",
"mostrevisions": "Pelan ke tewr zaf revizyonî biyê.",
"prefixindex": "Veroleya peley pêro",
"prefixindex-namespace": "Peleyê Veroleyıni ($1 cay nami)",
- "prefixindex-submit": "Bıasene",
+ "prefixindex-submit": "Bımocne",
"prefixindex-strip": "Listeya réz bıyayışi",
"shortpages": "Pelê kılmeki",
"longpages": "Pelê dergeki",
"usereditcount": "$1 {{PLURAL:$1|vurnayîş|vurnayîşî}}",
"usercreated": "$2 de $1 {{GENDER:$3|viraziya}}",
"newpages": "Pelê newey",
- "newpages-submit": "Bıasene",
+ "newpages-submit": "Bımocne",
"newpages-username": "Nameyê karberi:",
"ancientpages": "Pelê kehenêri",
"move": "Bıkırışe",
"specialloguserlabel": "Kerdoğ:",
"speciallogtitlelabel": "Meqsed (sername ya zi {{ns:user}}:karberi rê nameyê karberi):",
"log": "Qeydi",
- "logeventslist-submit": "Bıasene",
+ "logeventslist-submit": "Bımocne",
"all-logs-page": "Umumi qeydi pêro",
"alllogstext": "qey {{SITENAME}}i mocnayişê heme rocaneyani.\ntipa rocaneyi, nameyê karberi (herfa pil u qıci re hessas a), ya zi peli (reyna hessasiyê herfa pil u qıciyi) bıweçine u esayiş qıc kerê.",
"logempty": "Qeydan dı malumato unasin çıni yo.",
"cachedspecial-viewing-cached-ts": "Na pela raşt niya, şımayê enewke versiyonê verhafızada na pela vinenê.",
"cachedspecial-refresh-now": "Peyêni bıvin.",
"categories": "Kategoriy",
- "categories-submit": "Bıasene",
+ "categories-submit": "Bımocne",
"categoriespagetext": "{{PLURAL:$1|Kategoriya cêrene|Kategoriyanê cêrênan}} de peli ya zi medya estê.\n[[Special:UnusedCategories|Kategoriyê ke nêxebetiyenê]] tiya de nêmocniyayê.\n[[Special:WantedCategories|Kategoriyanê waşteyeyan]] de zi bıvêne.",
"categoriesfrom": "Kategoriyê ke be ninan dest pêkenê, bımocne:",
"deletedcontributions": "İştırakê karberi esterdi",
"linksearch-line": "$1, $2 ra link biya",
"linksearch-error": "jokeri têna nameyê makina ya serekini de aseni/eseni.",
"listusersfrom": "karber ê ke pey ıney detpêkeni ramocın:",
- "listusers-submit": "Bıasene",
+ "listusers-submit": "Bımocne",
"listusers-noresult": "karber nêdiyayo/a.",
"listusers-blocked": "(blok biy)",
"activeusers": "Listey karberan de aktivan",
"wlnote": "$3 saete $4 ra dıme {{PLURAL:$2|yew saete de|'''$2''' saetan de}} {{PLURAL:$1|vurnayışo peyên|vurnayışê '''$1''' peyêni}} cêrderê.",
"wlshowlast": "Peyni de $1 seata u $2 roca bıasne",
"watchlist-hide": "Bınımne",
- "watchlist-submit": "Bıasene",
+ "watchlist-submit": "Bımocne",
"wlshowtime": "Periyoda zemani asenayışi:",
"wlshowhideminor": "vurriyayışê werdi",
"wlshowhidebots": "boti",
"delete-confirm": "\"$1\" bestere",
"delete-legend": "Bestere",
"historywarning": "'''Teme:''' Pela ke şıma esterenê tede yew viyarte be teqriben $1 {{PLURAL:$1|versiyon esto|versiyoni estê}}:",
- "historyaction-submit": "Bıasene",
+ "historyaction-submit": "Bımocne",
"confirmdeletetext": "Tı ho yew pele u tarixê pele wederneno.\nTı ra rica keno, tı zani tı ho sekeno, tı zani neticeyanê eno wedarnayışi u tı zani tı ser [[{{MediaWiki:Policy-url}}|poliçe]] kar keno.",
"actioncomplete": "Kar bi temam",
"actionfailed": "kar nêbı",
"createacct-yourpasswordagain-ph": "आँजि पासवर्ड भरऽ",
"userlogin-remembermypassword": "मुलाई अघाडी झान्या काम गराइराख्या",
"userlogin-signwithsecure": "सुक्षित जडान प्रयोग गद्द्या",
- "cannotlogin-title": "लà¤\97à¤\87न à¤\85रिसà¤\95à¥\8dदà¥\88न",
+ "cannotlogin-title": "à¤\85à¤\88ल à¤à¤¿à¤¤à¤° à¤\9dान नाà¤\87à¤\81 पाà¤\88नà¥\8b",
"cannotlogin-text": "येइमी लगइन सम्भव नाइथिन।",
"cannotloginnow-title": "अईल भितर झान नाइँ पाईनो",
"cannotloginnow-text": "भितर जान असंभव छ जब प्रयोग $1|",
"userrights-groupsmember": "को सदस्य:",
"userrights-groupsmember-auto": "अंतर्निहित सदस्य:",
"userrights-reason": "कारण:",
+ "userrights-changeable-col": "तमले परिवर्तन गद्द सक्दया समूहअन",
"userrights-unchangeable-col": "तमीले परिवर्तन गद्द नसक्ने समूहहरू",
"userrights-conflict": "प्रयोगकर्ताको अधिकार परिवर्तनमी मतभेद भयो ! कृपया तमरो परिवर्तन पुनरावलोकन तथा पुष्टि गर ।",
"userrights-removed-self": "तमले सफलतापूर्वक आफनो अधिकारहरूलाई मेटाया । त्यै कारण तम आब यो पानो हेद्द नाइसक्दा ।",
"continue-editing": "Và int la zôna 'd mudéfica",
"previewconflict": "La vésta la cumbîna cun al tèst int la zôna 'd mudéfica tèst ché d'ed sōver e l'é cme la srà la pàgina s'ed decéd ed clichêr insém a \"Sêlva la pàgina\" in cól mumèint ché.",
"session_fail_preview": "A's în dispiêş. An n'é mìa stê pusébil registrêr la mudéfica perchè a 's în pêrsi al j infurmasiòun relatîvi a la sesiòun. Ét prés èser stê destachê. <strong>Contròla s' t'é incòra coleghê</strong>. Se al problēma 'l cunténva, a 's pōl pruvêr [[Special:UserLogout|ed coleghêres]] e fêr un ingrès nōv, contròla ânch se al tó navigadōr l' acèta i cookie da cól sît ché.",
- "session_fail_preview_html": "'''An n'é mìa stê pusébil registrêr la mudéfica perchè în andêdi persi al j infurmasiòun relatîvi a la sesiòun.'''\n\n''Pôst che in {{SITENAME}} a gh'é al permès ed druvêr l' HTML sèinsa lémit, an 's pōl mìa guardêr préma la pàgina mudifichêda; a 's trâta ed 'n'amzûra 'd sicurèsa cûntra j atâch JavaScript.''\n\n''' Se còst l'é un tentatîv legétim ed mudéfica, pruvêr incòra. Se al prublēma l'armâgn, a 's pōl pruvêr a [[Special:UserLogout|sarêr al colegamèint]] e fêr un nōv ingrès.'''",
+ "session_fail_preview_html": "A's în deispiêş. An n'é mìa stê pusébil registrêr la mudéfica perchè în andêdi persi al j infurmasiòun relatîvi a la sesiòun. \n\n<em> Dâto che {{SITENAME}} al gh'à un HTML grēz inviê a a 'ss è pêrs dal j infurmasiòun ed la sesiòun, la vésta préma ed salvêr l'è lughêda per prudèinsa cûntra j atâch JavaScript.</em>\n\n<strong>Se ' s trâta 'd un tentatîv normêl ed vèder còl che t'è fât préma 'd salvêrel, tōrna pruvêr.</strong>\nSe gh'è incòra al problēma, ét pō pruvêr a [[Special:UserLogout|scoleghêret]] e fêr un nōv ingrès, mó préma contròla che 'l tó navigadōr al tóga i cookie da cól sît ché.",
"token_suffix_mismatch": "'''La mudéfica an n'é mìa stêda salvêda perchè al ''client'' l'à fât vèder ed gestîr in môd e-sbaliê i carâter di pûn e dal virgûli int al ''token'' lighê a la mudéfica. Per schivşêr di pusébil erōr int al tèst ed la pàgina, è stê rifiutê tóta la mudéfica. Dla vôlti cla situasiòun ché la pōl sucēder quând a vînen druvê soquânt servési ''proxy'' sèinsa nòm via internèt che preşèinten di ''bug''.'''",
"edit_form_incomplete": "'''Soquânti pêrt dal môdul ed mudéfica în mìa rivêdi al ''server''; controlêr che al mudéfichi sién intâti e turnêr a pruvêr'''",
"editing": "Mudéfica ed $1",
"botpasswords-updated-body": "The bot password for bot name \"$1\" of user \"$2\" was updated.",
"botpasswords-deleted-title": "Bot password deleted",
"botpasswords-deleted-body": "The bot password for bot name \"$1\" of user \"$2\" was deleted.",
- "botpasswords-newpassword": "The new password to log in with <strong>$1</strong> is <strong>$2</strong>. <em>Please record this for future reference.</em>",
+ "botpasswords-newpassword": "The new password to log in with <strong>$1</strong> is <strong>$2</strong>. <em>Please record this for future reference.</em> <br> (For old bots which require the login name to be the same as the eventual username, you can also use <strong>$3</strong> as username and <strong>$4</strong> as password.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider is not available.",
"botpasswords-restriction-failed": "Bot password restrictions prevent this login.",
"botpasswords-invalid-name": "The username specified does not contain the bot password separator (\"$1\").",
"invalid-content-data": "Invalid content data",
"content-not-allowed-here": "\"$1\" content is not allowed on page [[$2]]",
"editwarning-warning": "Leaving this page may cause you to lose any changes you have made.\nIf you are logged in, you can disable this warning in the \"{{int:prefs-editing}}\" section of your preferences.",
+ "editpage-invalidcontentmodel-title": "Content model not supported",
+ "editpage-invalidcontentmodel-text": "The content model \"$1\" is not supported.",
"editpage-notsupportedcontentformat-title": "Content format not supported",
"editpage-notsupportedcontentformat-text": "The content format $1 is not supported by the content model $2.",
"content-model-wikitext": "wikitext",
"tag-filter": "[[Special:Tags|Tag]] filter:",
"tag-filter-submit": "Filter",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+ "tag-mw-contentmodelchange": "content model change",
+ "tag-mw-contentmodelchange-description": "Edits that [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel change the content model] of a page",
"tags-title": "Tags",
"tags-intro": "This page lists the tags that the software may mark an edit with, and their meaning.",
"tags-tag": "Tag name",
"tags-actions-header": "Actions",
"tags-active-yes": "Yes",
"tags-active-no": "No",
- "tags-source-extension": "Defined by an extension",
+ "tags-source-extension": "Defined by the software",
"tags-source-manual": "Applied manually by users and bots",
"tags-source-none": "No longer in use",
"tags-edit": "edit",
"ok": "Bone",
"retrievedfrom": "Elŝutita el \"$1\"",
"youhavenewmessages": "{{PLURAL:$3|Vi havas}} $1 ($2).",
- "youhavenewmessagesfromusers": "Riceviĝis $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).\n\nVi havas $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).",
+ "youhavenewmessagesfromusers": "Vi havas {{PLURAL:$1|mesaĝon|$1 mesaĝojn}} de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).",
"youhavenewmessagesmanyusers": "Riceviĝis $1 de multaj uzantoj ($2).",
"newmessageslinkplural": "{{PLURAL:$1|nova mesaĝo|999=novaj mesaĝoj}}",
"newmessagesdifflinkplural": "$1 {{PLURAL:$1|ŝanĝo|ŝanĝoj}}",
"createacct-yourpasswordagain-ph": "Retajpu pasvorton",
"userlogin-remembermypassword": "Memori mian ensaluton",
"userlogin-signwithsecure": "Uzu sekurigitan konekton",
+ "cannotlogin-title": "Ne eblas ensaluti",
+ "cannotlogin-text": "Ensaluto estas neebla.",
"cannotloginnow-title": "Nuntempe ne eblas ensaluti",
"cannotloginnow-text": "Ne eblas ensaluti dum uzado de $1.",
+ "cannotcreateaccount-title": "Ne eblas krei konton",
+ "cannotcreateaccount-text": "Senpera kreo de uzantokonto ne estas enŝaltita en ĉi tiu vikio.",
"yourdomainname": "Via domajno",
"password-change-forbidden": "Ve ne povas ŝanĝi pasvortojn en ĉi tiu vikio.",
"externaldberror": "Aŭ estis datenbaza eraro rilate al ekstera aŭtentikigado, aŭ vi ne rajtas ĝisdatigi vian eksteran konton.",
"action-applychangetags": "aldoni etikedojn al viaj propraj ŝanĝoj",
"action-changetags": "aldoni kaj forigi arbitrajn etikedojn ĉe unuopaj revizioj kaj protokoleroj",
"action-deletechangetags": "Forigi etikedojn de la datenbazo.",
+ "action-purge": "malplenigi servilan kaŝmemoron",
"nchanges": "$1 {{PLURAL:$1|ŝanĝo|ŝanĝoj}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ekde lasta vizito}}",
"enhancedrc-history": "historio",
"file-thumbnail-no": "La dosiernomo komencas kun <strong>$1</strong>.\nĜi ŝajnas kiel bildo de malgrandigita grandeco ''(thumbnail)''.\nSe vi havas ĉi tiun bildon en plena distingivo, alŝutu ĉi tiun, alikaze bonvolu ŝanĝi la dosieran nomon.",
"fileexists-forbidden": "Dosiero kun ĉi tiu nomo jam ekzistas kaj ne povas anstataŭigi ĝin.\nSe vi ankoraŭ volas alŝuti vian dosieron, bonvolu reprovi kun nova nomo.\n[[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Dosiero kun ĉi tia nomo jam ekzistas en la komuna dosierujo.\nSe vi ankoraŭ volas alŝuti vian dosieron, bonvolu retroigi kaj uzi novan nomon.[[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "La alŝutaĵo estas preciza kopio de la nuna versio de <strong>[[:$1]]</strong>.",
+ "fileexists-duplicate-version": "La alŝutaĵo estas preciza kopio de {{PLURAL:$2|malnova versio|malnovaj versioj}} de <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "Ĉi tiu dosiero estas duplikato de la {{PLURAL:$1|jena dosiero|jenaj dosieroj}}:",
"file-deleted-duplicate": "Duplikata dosiero de ĉi tiu dosiero ([[:$1]]) estis antaŭe forigita. Vi legu la forigan historion de tiu dosiero antaŭ provi realŝuti ĝin.",
"file-deleted-duplicate-notitle": "Dosiero identa al ĉi tiu dosiero estis forigita antaŭ nelonge kaj la titolo estis subpremita.\nVi demandu iun, kiu havas la eblecon, rigardi la subpremitajn dosierajn datojn, por kontroli la situacion antaŭ rea alŝutado.",
"upload-http-error": "HTTP-eraro okazis: $1",
"upload-copy-upload-invalid-domain": "Kopio-alŝutoj ne disponiĝas el ĉi tiu domajno.",
"upload-foreign-cant-upload": "Tiu vikio ne estas agorita por alŝuti alŝutitan dosieron al la petita fora dosierdeponejo.",
- "upload-foreign-cant-load-config": "La ŝarĝado de agordo pri dosieran alŝuton malsukcesis por la fora dosiera deponejo.",
+ "upload-foreign-cant-load-config": "Malsukcesis ŝargi la agordon por dosier-alŝutoj al ekstera dosier-deponejo.",
"upload-dialog-disabled": "Alŝutoj de dosiero per ĉi tiun dialogon estas malfunkciigita sur ĉi tiu vikio.",
"upload-dialog-title": "Alŝuti dosieron",
"upload-dialog-button-cancel": "Nuligi",
"createacct-yourpasswordagain-ph": "Repite la contraseña",
"userlogin-remembermypassword": "Mantener mi sesión iniciada",
"userlogin-signwithsecure": "Usar conexión segura",
+ "cannotlogin-title": "No se puede iniciar sesión",
"cannotloginnow-title": "No se puede iniciar sesión ahora",
"cannotloginnow-text": "No se puede iniciar sesión cuando se usa $1.",
+ "cannotcreateaccount-title": "No se pueden crear cuentas",
+ "cannotcreateaccount-text": "La creación directa de cuentas no está activada en este wiki.",
"yourdomainname": "Tu dominio:",
"password-change-forbidden": "No puedes cambiar las contraseñas en este wiki.",
"externaldberror": "Hubo un error de autenticación en la base de datos, o bien no tienes autorización para actualizar tu cuenta externa.",
"usercreated": "{{GENDER:$3|Registrado|Registrada}} el $1 a las $2",
"newpages": "Páginas nuevas",
"newpages-submit": "Mostrar",
- "newpages-username": "Nombre de usuario",
+ "newpages-username": "Nombre de usuario:",
"ancientpages": "Páginas más antiguas",
"move": "Trasladar",
"movethispage": "Trasladar esta página",
"pageinfo-article-id": "Identificador de la página",
"pageinfo-language": "Idioma de la página",
"pageinfo-content-model": "Modelo de contenido de la página",
+ "pageinfo-content-model-change": "cambiar",
"pageinfo-robot-policy": "Indización por robots",
"pageinfo-robot-index": "Permitido",
"pageinfo-robot-noindex": "No permitido",
"allmessagesdefault": "متن پیشفرض پیغام",
"allmessagescurrent": "متن کنونی پیغام",
"allmessagestext": "این فهرستی از پیغامهای سامانهای موجود در فضای نام مدیاویکی است.\nچنانچه مایل به مشارکت در محلیسازی مدیاویکی هستید لطفاً [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation محلیسازی مدیاویکی] و [https://translatewiki.net translatewiki.net] را ببینید.",
- "allmessagesnotsupportedDB": "این صفحه نمیتواند استفاده شود به این دلیل که <bdi>'''$wgUseDatabaseMessages'''</bdi> غیرفعال شدهاست.",
+ "allmessagesnotsupportedDB": "این صفحه نمیتواند استفاده شود به این دلیل که <strong>$wgUseDatabaseMessages</strong> غیرفعال شده است.",
"allmessages-filter-legend": "پالایه",
"allmessages-filter": "پالودن بر اساس وضعیت شخصیسازی:",
"allmessages-filter-unmodified": "تغییر نیافته",
"Matma Rex",
"Dcausse",
"Lucas",
- "Mabroukb"
+ "Mabroukb",
+ "Pymouss"
]
},
"tog-underline": "Soulignement des liens :",
"prefs-emailconfirm-label": "Confirmation du courriel :",
"youremail": "Courriel :",
"username": "{{GENDER:$1|Nom d'utilisateur|Nom d'utilisatrice}} :",
- "prefs-memberingroups": "{{GENDER:$2|Membre}} {{PLURAL:$1|du groupe|des groupes}} :",
+ "prefs-memberingroups": "{{GENDER:$2|Membre}} {{PLURAL:$1|du groupe|des groupes}}:",
"prefs-registration": "Date d'inscription :",
"yourrealname": "Nom réel :",
"yourlanguage": "Langue :",
"seconds-ago": "$1 {{PLURAL:$1|સેકંડ|સેકંડો}} ago",
"monday-at": "$1 પર સોમવાર",
"tuesday-at": "$1 પર મંગળવાર",
- "wednesday-at": "$1 પર બુધવાર",
+ "wednesday-at": "બુધવારે $1 વાગ્યે",
"thursday-at": "$1 પર ગુરુવાર",
"friday-at": "$1 પર શુક્રવાર",
"saturday-at": "$1 પર શનિવાર",
"botpasswords-updated-body": "ססמת הבוט עבור בוט בשם \"$1\" של המשתמש \"$2\" עודכנה.",
"botpasswords-deleted-title": "ססמת הבוט נמחקה",
"botpasswords-deleted-body": "ססמת הבוט עבור בוט בשם \"$1\" של המשתמש \"$2\" נמחקה.",
- "botpasswords-newpassword": "×\94סס×\9e×\94 ×\94×\97×\93ש×\94 ×\9c×\9b× ×\99ס×\94 <strong>$1</strong> ×\94×\99×\90 <strong>$2</strong>. <em>× ×\90 ×\9cש×\9e×\95ר ×\9e×\99×\93×¢ ×\96×\94 ×\9cצ×\95ר×\9a ×¢×\99×\95×\9f עת×\99×\93×\99.</em>",
+ "botpasswords-newpassword": "×\94ס×\99ס×\9e×\94 ×\94×\97×\93ש×\94 ×\9c×\9b× ×\99ס×\94 ×\9c×\97ש×\91×\95×\9f <strong>$1</strong> ×\94×\99×\90 <strong>$2</strong>. <em>× ×\90 ×\9cש×\9e×\95ר ×\9e×\99×\93×¢ ×\96×\94 ×\9cצ×\95ר×\9a ×¢×\99×\95×\9f עת×\99×\93×\99.</em> <br> (×¢×\91×\95ר ×\91×\95×\98×\99×\9d ×\99×©× ×\99×\9d ש×\93×\95רש×\99×\9d שש×\9d ×\94×\9eשת×\9eש ×\91×\9b× ×\99ס×\94 ×\9c×\97ש×\91×\95×\9f ×\99×\94×\99×\94 ×\96×\94×\94 ×\9cש×\9d ×\94×\9eשת×\9eש ש×\90×\99ת×\95 ×\94×\9d ×\99פע×\9c×\95, × ×\99ת×\9f ×\9c×\94שת×\9eש ×\92×\9d ×\91ש×\9d ×\94×\9eשת×\9eש <strong>$3</strong> ×¢×\9d ×\94ס×\99ס×\9e×\94 <strong>$4</strong>.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider אינו זמין.",
"botpasswords-restriction-failed": "כניסה זו נמנעה בשל הגבלות על ססמאות בוט.",
"botpasswords-invalid-name": "שם המשתמש שניתן אינו מכיל את תו הפרדת ססמאות הבוט (\"$1\").",
"invalid-content-data": "מידע שגוי על התוכן",
"content-not-allowed-here": "תוכן מסוג \"$1\" אינו מותר בדף [[$2]]",
"editwarning-warning": "עזיבת הדף הזה עלולה לגרום לך לאבד את כל השינויים שביצעת.\nאם יש לך חשבון באתר, באפשרותך לבטל את האזהרה הזאת בחלק \"{{int:prefs-editing}}\" שבהעדפות שלך.",
+ "editpage-invalidcontentmodel-title": "מודל התוכן אינו נתמך",
+ "editpage-invalidcontentmodel-text": "מודל התוכן \"$1\" אינו נתמך.",
"editpage-notsupportedcontentformat-title": "סוג התוכן אינו נתמך",
"editpage-notsupportedcontentformat-text": "תוכן מסוג $1 אינו נתמך על־ידי מודל התוכן $2.",
"content-model-wikitext": "קוד ויקי",
"tag-filter": "מסנן [[Special:Tags|תגיות]]:",
"tag-filter-submit": "סינון",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|תגית|תגיות}}]]: $2)",
+ "tag-mw-contentmodelchange": "שינוי מודל התוכן",
+ "tag-mw-contentmodelchange-description": "עריכות ש[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel משנות את מודל התוכן] של דף",
"tags-title": "תגיות",
"tags-intro": "דף זה מכיל רשימה של תגיות שהתוכנה יכולה לסמן איתן עריכה, ומשמעויותיהן.",
"tags-tag": "שם התגית",
"tags-actions-header": "פעולות",
"tags-active-yes": "כן",
"tags-active-no": "לא",
- "tags-source-extension": "×\94×\95×\92×\93ר ×¢×\9cÖ¾×\99×\93×\99 ×\94ר×\97×\91ה",
+ "tags-source-extension": "×\94×\95×\92×\93ר ×¢×\9cÖ¾×\99×\93×\99 ×\94ת×\95×\9b× ה",
"tags-source-manual": "מוחל באופן ידני על־ידי משתמשים ובוטים",
"tags-source-none": "אינו בשימוש כעת",
"tags-edit": "עריכה",
"undelete_short": "Isubli ti pannakaikkat {{PLURAL:$1|ti maysa a naurnos|dagiti $1 a naurnos}}",
"viewdeleted_short": "Kitaen {{PLURAL:$1|ti maysa a naikkat a naurnos|dagiti $1 a naikkat a naurnos}}",
"protect": "Salakniban",
- "protect_change": "sukatan",
+ "protect_change": "baliwan",
"protectthispage": "Salakniban daytoy a panid",
"unprotect": "Sukatan ti salaknib",
"unprotectthispage": "Sukatan ti salaknib daytoy a panid",
"createacct-yourpasswordagain-ph": "Ikabil manen ti kontrasenias",
"userlogin-remembermypassword": "Taginayonennak nga iserrek",
"userlogin-signwithsecure": "Usaren ti natalged a koneksion",
+ "cannotlogin-title": "Saan a makastrek",
+ "cannotlogin-text": "Saan a mabalin ti panagserrek.",
"cannotloginnow-title": "Saan a mabalin itan iti sumrek",
"cannotloginnow-text": "Saan a mabalin ti sumrek no agus-usar iti $1.",
+ "cannotcreateaccount-title": "Saan a makapartuat kadagiti pakabilangan",
+ "cannotcreateaccount-text": "Saan a napakabaelan ti dagus a panagpartuat iti pakabilangan iti daytoy a wiki.",
"yourdomainname": "Ti bukodmo a dominio:",
"password-change-forbidden": "Saanmo a mabaliwan dagiti kontrasenias iti daytoy a wiki.",
"externaldberror": "Mabalin nga adda biddut iti pannakapasingked ti database wenno saanka a mapalubosan a mangpabaro ti akinruar a pakabilangam.",
"botpasswords-updated-body": "Napabaro ti kontrasenias ti bot para iti nagan ti bot iti \"$1\" ni agar-aramat \"$2\".",
"botpasswords-deleted-title": "Naikkat ti kontrasenias ti bot",
"botpasswords-deleted-body": "Naikkat ti kontrasenias ti bot para iti nagan ti bot iti \"$1\" ni agar-aramat \"$2\".",
- "botpasswords-newpassword": "Ti baro a kontrasenias iti panagserrek iti <strong>$1</strong> ket <strong>$2</strong>. <em>Pangngaasi nga irekord daytoy para iti masakbayan a reperensia.</em>",
+ "botpasswords-newpassword": "Ti baro a kontrasenias iti panagserrek iti <strong>$1</strong> ket <strong>$2</strong>. <em>Pangngaasi nga irekord daytoy para iti masakbayan a reperensia.</em> <br> (Para kadagiti daan a bot a makasapul iti nagan iti panagserrek a kapada koma ti kanungpalan a nagan ti agar-aramat, mabalinmo pay ti agusar ti <strong>$3</strong> a kas nagan ti <strong>$4</strong> a kas kontrasenias.)",
"botpasswords-no-provider": "Saan a magun-od ti BotPasswordsSessionProvider.",
"botpasswords-restriction-failed": "Ti panangigawid ti kontrasenias ti bot ket nangpawil iti daytoy a panagserrek.",
"botpasswords-invalid-name": "Ti naibaga a nagan ti agar-aramat ket saan nga aglaon iti panangisina ti kontrasenias ti bot (\"$1\").",
"invalid-content-data": "Imbalido a datos ti linaon",
"content-not-allowed-here": "Ti \"$1\" a linaon ket saan a maipalubos iti panid ti [[$2]]",
"editwarning-warning": "Ti ipapanaw iti daytoy a panid ket makapataud ti pannakapukaw kadagiti ania man a binalbaliwam.\nNo nakastrekka, mabalinmo nga ibaldado daytoy a ballaag iti \"{{int:prefs-editing}}\" a seksion kadagiti kakaykayatam.",
+ "editpage-invalidcontentmodel-title": "Saan a masuportaran ti modelo ti linaon",
+ "editpage-invalidcontentmodel-text": "Saan a nasuportaran ti modelo ti linaon ti \"$1\".",
"editpage-notsupportedcontentformat-title": "Ti pormat ti linaon ket saan a nasuportaran",
"editpage-notsupportedcontentformat-text": "Ti pormat ti linaon ti $1 ket saan a nasuportaran babaen ti modelo ti linaon ti $2.",
"content-model-wikitext": "wikitext",
"file-thumbnail-no": "Ti nagan ti papeles ket mangrugi iti <strong>$1</strong>.\nKasla ti ladawan a napabassit ti kadakkel <em>(thumbnail)</em>.\nNo addaanka iti daytoy a ladawan iti napno a resolusion ikargam dayta, no saan pangngaasi a sukatam ti nagan ti papeles.",
"fileexists-forbidden": "Daytoy a nagan ti papeles ket addan, ken saan a mabalin a masuratan manen.\nNo kayatmo pay latta nga ikarga ti papelesmo, pangngaasi nga agsublika ken agusar iti baro a nagan.\n[[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Ti papeles iti daytoy a nagan ket addan iti pagbingayan a repositorio ti papeles.\nNo kayatmo pay latta nga ikarga ti papeles, pangngaasi nga agsublika ken agusar iti baro a nagan.\n[[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "Ti karga ket maysa nga eksakto a duplikado ti agdama a bersion ti <strong>[[:$1]]</strong>.",
+ "fileexists-duplicate-version": "Ti karga ket maysa nga eksakto a duplikado {{PLURAL:$2|ti maysa a daan a bersion|dagiti daan a bersion}} ti <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "Daytoy a papeles ket duplikado kadagiti sumaganad a {{PLURAL:$1|papeles|pappapeles}}:",
"file-deleted-duplicate": "Ti papeles a kapadpada ti papeles a ([[:$1]]) ket dati a naikkat.\nKitaem koma ti pakasaritaan a pannakaikkat ti papeles sakbay a mangirugika a mangikarga manen.",
"file-deleted-duplicate-notitle": "Ti papales a kapada iti daytoy a papeles ket dati a naikkat, ken nalapdan ti titulo.\nNasken nga agdamagka iti sabali nga addaan iti abilidad a mangrepaso ti nalapdan a datos ti papeles tapno marepaso ti kasasaad sakbay a mapan nga agikarga manen iti daytoy.",
"filerevert-submit": "Isubli",
"filerevert-success": "Ti <strong>[[Media:$1|$1]]</strong> ket naipasubli iti [$4 bersion manipud idi $3, $2].",
"filerevert-badversion": "Awan ti dati a lokal a bersion iti daytoy a papeles a naited ti dayta nga oras ken petsa.",
+ "filerevert-identical": "Ti agdama a bersion ti papeles ket kapadan iti maysa a napili.",
"filedelete": "Ikkaten ti $1",
"filedelete-legend": "Ikkaten ti papeles",
"filedelete-intro": "Mangrugrugika nga agikkat ti <strong>[[Media:$1|$1]]</strong> ken mairaman amin a pakasaritaanna.",
"rollbacklinkcount-morethan": "agisubli ti ad-adu ngem $1 {{PLURAL:$1|nga inurnos|nga inur-urnos}}",
"rollbackfailed": "Napaay ti panangisubli",
"rollback-missingparam": "Awan dagiti nasken a parametro iti kiddaw.",
+ "rollback-missingrevision": "Saan a maikarga ti datos ti rebision.",
"cantrollback": "Saan a maisubli ti panagurnos;\nti naudi a nakaaramid ket iti laeng nagsurat iti daytoy a panid.",
"alreadyrolled": "Saan a maipasubli ti kinaudi a panagurnos iti [[:$1]] babaen ni [[User:$2|$2]] ([[User talk:$2|tungtungan]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nadda sabali a naurnos wenno nagipasubli ti panid.\n\nTi kinaudi a panagurnos ti daytoy a panid ket babaen ni [[User:$3|$3]] ([[User talk:$3|tungtungan]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
"editcomment": "Ti pakabuklan idi ti panagurnos ket: <em>$1</em>.",
"pageinfo-article-id": "ID ti panid",
"pageinfo-language": "Pagsasao ti naglaon a panid",
"pageinfo-content-model": "Modelo ti linaon ti panid",
+ "pageinfo-content-model-change": "baliwan",
"pageinfo-robot-policy": "Panagpasurot babaen dagiti robot",
"pageinfo-robot-index": "Maipalubos",
"pageinfo-robot-noindex": "Saan a maipalubos",
"confirmemail_body_set": "Addaan, baka sika met laeng, manipud ti IP a pagtaengan ti $1,\nket nangikabil ti esurat a pagtaengan ti pakabilangan ti \"$2\" iti daytoy a pagtaengan idiay {{SITENAME}}\n\nTapno mapasingkedan daytoy a pakabilangan ket agpayso a kukuam ken \npakabaelan dagiti esurat a langa idiay {{SITENAME}}, lukatam daytoy a silpo idiay pabasabasam:\n\n$3\n\nNo daytoy a pakabilangan ket *saanmo* a kukua, surutem daytoy a silpo\ntapno ukasen ti panagpasingked ti esurat a pagtaengan:\n\n$5\n\nDaytoy a panagpasingked ti kodigo ket agpaso intono $4.",
"confirmemail_invalidated": "Naukas ti pammasingked ti esurat a pagtaengam",
"invalidateemail": "Ukasen ti pammasingked ti esurat",
+ "notificationemail_subject_changed": "Nabaliwanen ti nairehistro nga adres ti esurat ti {{SITENAME}}",
+ "notificationemail_subject_removed": "Naikkaten ti nairehistro nga adres ti esurat ti {{SITENAME}}",
+ "notificationemail_body_changed": "Adda maysa a tao, mabalin a sika, manipud iti adres ti IP ti $1,\nket nangbaliw ti adres ti esurat ti pakabilangan ti \"$2\" iti \"$3\" iti {{SITENAME}}.\n\nNo saan a sika daytoy, dagus a kontaken ti administrador ti sitio.",
+ "notificationemail_body_removed": "Adda maysa a tao, mabalin a sika, manipud iti adres ti IP ti $1,\nket nangikkat ti adres ti esurat ti pakabilangan ti \"$2\" iti {{SITENAME}}.\n\nNo saan a sika daytoy, dagus a kontaken ti administrador ti sitio.",
"scarytranscludedisabled": "[Nabaldado ti Interwiki panagiraman]",
"scarytranscludefailed": "[Napaay ti panagala ti plantilia para iti $1]",
"scarytranscludefailed-httpstatus": "[Napaay ti panagala ti plantilia para iti $1: HTTP $2]",
"tag-filter": "Sagat ti [[Special:Tags|etiketa]]:",
"tag-filter-submit": "Sagat",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etiketa|Et-etiketa}}]]: $2)",
+ "tag-mw-contentmodelchange": "panagbaliw ti modelo ti linaon",
+ "tag-mw-contentmodelchange-description": "Dagiti panagurnos a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel mangbaliw ti modelo ti linaon] ti panid",
"tags-title": "Dagiti etiketa",
"tags-intro": "Daytoy a panid ket ilistana dagiti etiketa a mablin nga usaren ti sopwer a mangmarka iti inurnos, ken dagiti kaibuksilanda.",
"tags-tag": "Nagan ti etiketa",
"tags-actions-header": "Dagiti aramid",
"tags-active-yes": "Wen",
"tags-active-no": "Saan",
- "tags-source-extension": "Naipalawag babaen ti maysa a pagpaatiddog",
+ "tags-source-extension": "Naipalawag babaen ti sopwer",
"tags-source-manual": "Manual a naipakat babaen dagiti agar-aramat ken dagiti bot",
"tags-source-none": "Saan a maus-usar",
"tags-edit": "urnosen",
"feedback-useragent": "Ahente ti agar-aramat:",
"searchsuggest-search": "Biruken",
"searchsuggest-containing": "naglaon ti...",
+ "api-error-autoblocked": "Automatiko a naserraan ti IP nga adresmo, gapu ta inusar babaen ti naseraan nga agar-aramat.",
"api-error-badaccess-groups": "Saanka mapalubosan nga agikarga kadagiti papeles iti daytoy a wiki.",
"api-error-badtoken": "Akin-uneg a biddut: Dakes a tandaan.",
"api-error-blocked": "Naserraankan manipud iti panagurnos.",
"linkaccounts-submit": "Isilpo dagiti pakabilangan",
"unlinkaccounts": "Ikkaten ti silpo dagiti pakabilangan",
"unlinkaccounts-success": "Ti pakabilangan ket naikkat iti pannakaisilpo.",
- "authenticationdatachange-ignored": "Saan a natengngel ti panagbaliw ti datos ti pammasingked. Mabalin nga awan ti nakompigura a mangited?"
+ "authenticationdatachange-ignored": "Saan a natengngel ti panagbaliw ti datos ti pammasingked. Mabalin nga awan ti nakompigura a mangited?",
+ "userjsispublic": "Pangngaasi a laglagipen: Dagiti subpanid ti JavaScript ket nasken a saan nga aglaon iti datos a nailemed gapu ta makita dagitoy babaen dagiti sabali nga agar-aramat.",
+ "usercssispublic": "Pangngaasi a laglagipen: Dagiti subpanid ti CSS ket nasken a saan nga aglaon iti datos a nailemed gapu ta makita dagitoy babaen dagiti sabali nga agar-aramat."
}
"botpasswords-updated-body": "La password per il bot di nome \"$1\" dell'utente \"$2\" è stata aggiornata.",
"botpasswords-deleted-title": "Password bot cancellata",
"botpasswords-deleted-body": "La password per il bot di nome \"$1\" dell'utente \"$2\" è stata cancellata.",
- "botpasswords-newpassword": "La nuova password per accedere con <strong>$1</strong> è <strong>$2</strong>. <em>Registratelo per consultazioni future.</em>",
+ "botpasswords-newpassword": "La nuova password per accedere con <strong>$1</strong> è <strong>$2</strong>. <em>Registratelo per consultazioni future.</em> <br> (Per i vecchi bot che richiedono che il nome per accedere sia lo stesso del nome utente, puoi utilizzare <strong>$3</strong> come nome utente e <strong>$4</strong> come password.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider non è disponibile.",
"botpasswords-restriction-failed": "Le restrizioni di password bot impediscono questo accesso.",
"botpasswords-invalid-name": "Il nome utente indicato non contiene il separatore per password bot (\"$1\").",
"invalid-content-data": "Dati contenuti non validi",
"content-not-allowed-here": "Contenuto in \"$1\" non consentito nella pagina [[$2]]",
"editwarning-warning": "Lasciare questa pagina potrebbe causare la perdita di tutte le modifiche fatte.\nSe hai effettuato l'accesso, puoi disattivare questo avviso nella sezione \"{{int:prefs-editing}}\" delle tue preferenze.",
+ "editpage-invalidcontentmodel-title": "Modello di contenuto non supportato",
+ "editpage-invalidcontentmodel-text": "Il modello di contenuto \"$1\" non è supportato.",
"editpage-notsupportedcontentformat-title": "Formato contenuto non supportato",
"editpage-notsupportedcontentformat-text": "Il formato del contenuto $1 non è supportato dal modello di contenuto $2.",
"content-model-wikitext": "wikitesto",
"october-gen": "10월",
"november-gen": "11월",
"december-gen": "12월",
- "jan": "1월",
- "feb": "2월",
- "mar": "3월",
- "apr": "4월",
- "may": "5월",
- "jun": "6월",
- "jul": "7월",
- "aug": "8월",
- "sep": "9월",
- "oct": "10월",
- "nov": "11월",
- "dec": "12월",
+ "jan": "1",
+ "feb": "2",
+ "mar": "3",
+ "apr": "4",
+ "may": "5",
+ "jun": "6",
+ "jul": "7",
+ "aug": "8",
+ "sep": "9",
+ "oct": "10",
+ "nov": "11",
+ "dec": "12",
"january-date": "1월 $1일",
"february-date": "2월 $1일",
"march-date": "3월 $1일",
"cannotloginnow-title": "Aloggen ass elo net méiglech",
"cannotloginnow-text": "Aloggen ass net méiglech wann dir $1 benotzt.",
"cannotcreateaccount-title": "Benotzerkont kënnen net opgemaach ginn",
+ "cannotcreateaccount-text": "D'direkt Uleeë vu Benotzerkonten ass an dëser Wiki net aktivéiert.",
"yourdomainname": "Ären Domän:",
"password-change-forbidden": "Dir däerft op dëser Wiki Passwierder net änneren.",
"externaldberror": "Entweder ass e Feeler bei der externer Authentifizéierung geschitt, oder Dir däerft Ären externe Benotzerkont net aktualiséieren.",
"tag-filter": "[[Special:Tags|Markéierungs]]-Filter:",
"tag-filter-submit": "Filter",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+ "tag-mw-contentmodelchange": "Ännerung vum Modell vum Inhalt",
"tags-title": "Markéierungen",
"tags-intro": "Op dëser Säit stinn all déi Taggen, déi vun dëser Software fir Ännerungen unzeweise benotzt ginn, an hir Bedeitung.",
"tags-tag": "Numm vun der Markéierung",
"tags-actions-header": "Aktiounen",
"tags-active-yes": "Jo",
"tags-active-no": "Neen",
- "tags-source-extension": "Duerch eng Erweiderung definéiert",
+ "tags-source-extension": "Duerch d'Software definéiert",
"tags-source-manual": "Manuell vu Benotzer a vu Botten agesat",
"tags-source-none": "Gëtt net méi gebraucht",
"tags-edit": "änneren",
"tags-edit-revision-submit": "Ännerungen op {{PLURAL:$1|dës Versioun|$1 Versiounen}} uwennen",
"tags-edit-success": "D'Ännerunge goufen applizéiert.",
"tags-edit-failure": "D'Ännerunge konnten net applizéiert ginn: $1",
+ "tags-edit-nooldid-title": "Net-valabel Zilversioun",
"tags-edit-none-selected": "Sicht mindestens eng Markéierung eraus déi dir dobäisetzen oder ewechhuele wëllt.",
"comparepages": "Säite vergläichen",
"compare-page1": "Säit 1",
"tagline": "Da {{SITENAME}}",
"help": "Agiùtto",
"search": "Çerca",
+ "search-ignored-headings": " #<!-- lascia questa riga esattamente comm'a l'è --> <pre>\n# Elenco de intestaçioin che saian ignoræ da-a riçerca.\n# E modifiche a questa paggina saian effettive non apen-a a paggina a saiâ indiçizâ.\n# Ti poeu forçâ a re-indiçizzaçion de 'na paggina effettoando una modifica nulla.\n# A scintasci a l'è a seguente:\n# * Tutto da-o carattere \"#\" a-a fin da riga o l'è un commento\n# * Tutte e righe non voeue son e intestaçioin esatte da ignorâ, maiuscolo/minuscolo e tutto\nNotte\nVoxe correlæ\nCollegamenti esterni\n #</pre> <!-- lascia questa riga esattamente comm'a l'è -->",
"searchbutton": "Çerca",
"go": "Vanni",
"searcharticle": "Vanni",
"createacct-yourpasswordagain-ph": "Conferma a password un'atra votta",
"userlogin-remembermypassword": "Mantegnime collegou",
"userlogin-signwithsecure": "Adoeuvia una conescion segua",
+ "cannotlogin-title": "Imposcibbile intrâ",
"cannotloginnow-title": "Aoa no se poeu intrâ",
"cannotloginnow-text": "Quande s'adoeuvia $1 no se poeu intrâ.",
+ "cannotcreateaccount-title": "Imposcibbile creâ di utençe",
"yourdomainname": "Indirisso do scito:",
"password-change-forbidden": "No ti peu cangiâ poula segretta in questa wiki.",
"externaldberror": "Gh'è stæto un aro co-o server de aotenticaçion esterno, oppû no ti g'hæ i aotorizzaçioin pe aggiornâ o to accesso esterno.",
"botpasswords-updated-body": "A password pe-o bot de nomme \"$1\" de l'utente \"$2\" a l'è stæta aggiornâ.",
"botpasswords-deleted-title": "Password bot scassâ",
"botpasswords-deleted-body": "A password pe-o bot de nomme \"$1\" de l'utente \"$2\" a l'è stæta scassâ.",
- "botpasswords-newpassword": "A noeuva password pe accede con <strong>$1</strong> a l'è <strong>$2</strong>. <em>Marchitelo pe rifeimento futuo.</em>",
+ "botpasswords-newpassword": "A noeuva password pe accede con <strong>$1</strong> a l'è <strong>$2</strong>. <em>Marchitelo pe rifeimento futuo.</em><br> (Pe-i vegi bot che g'han de besoeugno che o nomme pe accede o segge o mæximo che o nomme utente, ti poeu doeuviâ <strong>$3</strong> comme nomme utente e <strong>$4</strong> comme password.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider o no l'è disponibbile.",
"botpasswords-restriction-failed": "E restriçioin de password bot impediscian questo accesso.",
"botpasswords-invalid-name": "O nomme utente indicou o no conten o separatô pe-o password bot (\"$1\").",
"invalid-content-data": "Dæti contegnui non vallidi",
"content-not-allowed-here": "Contegnuo in \"$1\" non consentio inta paggina [[$2]]",
"editwarning-warning": "Lasciâ sta paggina porriæ caosâ a perdia de tutte e modiffiche fæte.\nSe ti t'hê introu, ti peu disattivâ st'aviso inta seçion \"{{int:prefs-editing}}\" de teu preferençe.",
+ "editpage-invalidcontentmodel-title": "Modello de contegnuo non supportou",
+ "editpage-invalidcontentmodel-text": "O modello de contegnuo \"$1\" o no l'è supportou.",
"editpage-notsupportedcontentformat-title": "Formato contegnuo non supportou",
"editpage-notsupportedcontentformat-text": "O formato do contegnuo $1 o no l'è supportou da-o modello de contegnuo $2.",
"content-model-wikitext": "wikitesto",
"grant-group-high-volume": "Esegue açioin mascive",
"grant-group-customization": "Personalizzaçion e preferençe",
"grant-group-administration": "Esegue açioin amministrative",
+ "grant-group-private-information": "O l'accede a-i dæti privæ sciu de ti",
"grant-group-other": "Attivitæ varrie",
"grant-blockusers": "Blocca e sblocca utenti",
"grant-createaccount": "Crea un'utença",
"grant-highvolume": "Modiffiche mascive",
"grant-oversight": "Asconde i utenti e soprimme e revixoin",
"grant-patrol": "Marca e modifiche a-e paggine comme veificæ",
+ "grant-privateinfo": "O l'accede a de informaçioin privæ",
"grant-protect": "Proteze e sproteze e paggine",
"grant-rollback": "Rollback de modifiche a-e pagine",
"grant-sendemail": "Manda di email a di atri utenti",
"action-applychangetags": "appricâ di etichette a-e to modiffiche",
"action-changetags": "Azonze e levâ de specifiche etichette sciu scingole verscioin o voxe de registro",
"action-deletechangetags": "scassâ i etichette da-o database",
+ "action-purge": "aggiornâ questa paggina",
"nchanges": "$1 {{PLURAL:$1|modiffica|modiffiche}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|da l'urtima vixita}}",
"enhancedrc-history": "cronologia",
"file-thumbnail-no": "O nomme do file comença con <strong>$1</strong>; pâ ch'o segge un'inmaggine de dimenscioin redute ''(miniatua)''.\nSe ti dispon-i del'immaggine inta risoluçion originale, carreghila. Sedunque, pe piaxei, cangighe o nomme.",
"fileexists-forbidden": "Un file con questo nomme o l'existe za e o no poeu ese soviascrito. Se ti voeu caregâ o to file, torna inderê e dagghe un atro nomme. [[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Un file con questo nomme o l'esiste za inte l'archivio de risorse multimediæ condivise. Se ti dexiddei ancon caregâ o file, torna inderê e modifica o nomme co-o quæ caregâ o file. [[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "O file caregou o l'è un duplicou esatto de l'attoale verscion de <strong>[[:$1]]</strong>.",
+ "fileexists-duplicate-version": "O file caregou o l'è un duplicou esatto de {{PLURAL:$2|'na verscion precedente|verscioin precedente}} de <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "Questo file o l'è un dupricou {{PLURAL:$1|do seguente|di seguenti}} file:",
"file-deleted-duplicate": "Un file identico a questo ([[:$1]]) o l'è stæto scassou into passou. Verifica a cronologia de scassatue primma de caregâlo torna.",
"file-deleted-duplicate-notitle": "Un file identico a questo o l'è stæto scassou into passou, e o tittolo o l'è stæto soppresso. Domanda a quarcun ch'o g'ha a poscibilitæ de vedde i file soppresci de esaminâ a scituaçion primma de procede torna a-o caregamento.",
"filerevert-submit": "Ripristina",
"filerevert-success": "'''O file [[Media:$1|$1]]''' o l'è stæto ripristinou a-a [$4 verscion do $2, $3].",
"filerevert-badversion": "No gh'è de verscioin locali precedenti do file co-o timestamp provisto.",
+ "filerevert-identical": "A verscion attoale do file a l'è za identica a quella seleçionâ.",
"filedelete": "Scassa \"$1\"",
"filedelete-legend": "Scassa o file",
"filedelete-intro": "Ti stæ pe scassâ o file '''[[Media:$1|$1]]''' con tutta a so cronologia.",
"watchnologin": "Accesso non effettuou",
"addwatch": "Azonzi a-a lista sotta öservaçion",
"addedwatchtext": "\"[[:$1]]\" e a so paggina de discuscion son stæte azonte a-a proppia [[Special:Watchlist|lista di öservæ]].",
+ "addedwatchtext-talk": "\"[[:$1]]\" e a so paggina associâ son stæte azonte a-a to [[Special:Watchlist|lista di öservæ]].",
"addedwatchtext-short": "A pagina \"$1\" a l'è stæata azonta a-a proppia lista di öservæ.",
"removewatch": "Rimoeuvi da-i öservæ speciali",
"removedwatchtext": "\"[[:$1]]\" e a so paggina de discuscion son stæte rimosse da-a proppia [[Special:Watchlist|lista di öservæ]].",
+ "removedwatchtext-talk": "\"[[:$1]]\" e a so paggina associâ son stæte rimosse da-a to [[Special:Watchlist|lista di öservæ]].",
"removedwatchtext-short": "A pagina \"$1\" a l'è stæata rimossa da-a proppia lista di öservæ.",
"watch": "Metti sotta oservaçion",
"watchthispage": "Vigilâ 'sta paggina",
"rollbacklinkcount-morethan": "rollback de ciù de {{PLURAL:$1|una modiffica|$1 modiffiche}}",
"rollbackfailed": "Rollback fallio",
"rollback-missingparam": "Parammetri obrigatoi mancanti inta recesta.",
+ "rollback-missingrevision": "Imposcibile caregâ i dæti da verscion.",
"cantrollback": "No se peu tornâ inderê; l'utente ch'o l'ha fæto quelle modiffiche o l'è stæto l'unico contribuente.",
"alreadyrolled": "No l'è poscibbile annullâ e modiffiche apportæ a-a pagina [[:$1]] da parte de [[User:$2|$2]] ([[User talk:$2|discuscion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); un atro utente o l'ha zà modificou a pagina oppù o l'ha effettuou o rollback.\n\nA modifica ciù reçente a.a paggina a l'è stæta apportâ da [[User:$3|$3]] ([[User talk:$3|discuscion]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
"editcomment": "L'ogetto da modiffica o l'ea: <em>$1</em>.",
"undeletehistorynoadmin": "Questa pagina a l'è stæta scassâ.\nO motivo da scassatua o l'è mostrou chì sotta, insemme a-i detaggi de l'utente ch'o l'ha modificou questa pagina primma da scassatua.\nO testo contegnuo inte verscioin scassæ o l'è disponibile solo a-i amministratoî.",
"undelete-revision": "Verscion scassâ da pagina $1, inseia o $4 a $5 da $3:",
"undeleterevision-missing": "Verscion errâ o mancante. O collegamento o l'è errou o dunque a verscion a l'è stæta zà ripristinâ ò eliminâ da l'archivvio.",
+ "undeleterevision-duplicate-revid": "No s'è posciuo ripristinâ {{PLURAL:$1|una verscion|$1 verscioin}}, percose {{PLURAL:$1|o so}} <code>rev_id</code> o l'ea za in doeuvia.",
"undelete-nodiff": "No l'è stæto trovou nisciun-a verscion precedente.",
"undeletebtn": "Ristorâ",
"undeletelink": "fanni védde/repìggia",
"pageinfo-article-id": "ID da paggina",
"pageinfo-language": "Lengua do contegnuo da paggina",
"pageinfo-content-model": "Modello do contegnuo da paggina",
+ "pageinfo-content-model-change": "cangia",
"pageinfo-robot-policy": "Indiçizzaçion pe-i robot",
"pageinfo-robot-index": "Consentio",
"pageinfo-robot-noindex": "Non consentio",
"tag-filter": "Filtra pe [[Special:Tags|etichetta]]:",
"tag-filter-submit": "Filtro",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etichetta|Etichette}}]]: $2)",
+ "tag-mw-contentmodelchange": "cangio a-o modello di contegnui",
"tags-title": "Etichette",
"tags-intro": "Questa pagina a l'elenca i etichette che o software o poriæ associâ a 'na modiffica e o so scignificou.",
"tags-tag": "Nomme de l'etichetta",
"tags-actions-header": "Açioin",
"tags-active-yes": "Sci",
"tags-active-no": "No",
- "tags-source-extension": "Definio da 'n'estenscion",
+ "tags-source-extension": "Definio da-o programma",
"tags-source-manual": "Appricou manoalmente da utenti e bot",
"tags-source-none": "No ciù in doeuvia",
"tags-edit": "cangia",
"createacct-yourpasswordagain-ph": "Įveskite slaptažodį dar kartą",
"userlogin-remembermypassword": "Įsiminti mane",
"userlogin-signwithsecure": "Naudoti saugią jungtį",
+ "cannotlogin-title": "Negalima prisijungti",
+ "cannotlogin-text": "Prisijungti neįmanoma.",
"cannotloginnow-title": "Dabar negalima prisijungti",
"cannotloginnow-text": "Prisijungimas negalimas, kai naudojama $1.",
+ "cannotcreateaccount-title": "Negali kurti paskyrų",
+ "cannotcreateaccount-text": "Tiesioginis paskyros kūrimas nėra įgalintas šioje viki.",
"yourdomainname": "Jūsų domenas:",
"password-change-forbidden": "Jus negalite keisti slaptažodžių šioje wiki.",
"externaldberror": "Yra arba išorinė autorizacijos duomenų bazės klaida arba jums neleidžiama atnaujinti jūsų išorinės paskyros.",
"file-thumbnail-no": "Failo pavadinimas prasideda <strong>$1</strong>.\nAtrodo, kad yra sumažinto dydžio paveikslėlis ''(miniatiūra)''.\nJei jūs turite šį paveisklėlį pilna raiška, įkelkite šitą, priešingu atveju prašome pakeisti failo pavadinimą.",
"fileexists-forbidden": "Failas tokiu pačiu vardu jau egzistuoja ir negali būti perrašytas;\nprašome eiti atgal ir įkelti šį failą kitu vardu. [[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Failas tokiu vardu jau egzistuoja bendrojoje failų saugykloje;\nJei visvien norite įkelti savo failą, prašome eiti atgal ir įkelti šį failą kitu vardu. [[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "Įkėlimas yra <strong>[[:$1]]</strong> dabartinės versijos tikslus dublikatas.",
+ "fileexists-duplicate-version": "Įkėlimas yra <strong>[[:$1]]</strong> {{PLURAL:$2|senesnės versijos|senesnių versijų}} tikslus dublikatas.",
"file-exists-duplicate": "Šis failas yra {{PLURAL:$1|šio failo|šių failų}} dublikatas:",
"file-deleted-duplicate": "Failas, identiškas šiam failui ([[:$1]]), seniau buvo ištrintas. Prieš įkeldami jį vėl patikrinkite šio failo ištrynimo istoriją.",
"file-deleted-duplicate-notitle": "Rinkmena, visiškai atitinkanti šią, anksčiau buvo ištrinta, o jos pavadinimas uždraustas. Jums reiktų paprašyti kieno nors, turinčio galimybę peržiūrėti uždraustą rinkmeną, kad jis išaiškintų padėtį, prieš bandant vėl kelti rinkmeną.",
"filerevert-submit": "Grąžinti",
"filerevert-success": "<span class=\"plainlinks\">'''[[Media:$1|$1]]''' buvo sugrąžintas į versiją $4 ($2, $3).</span>",
"filerevert-badversion": "Nėra jokių ankstesnių vietinių šio failo versijų su pateiktu laiku.",
+ "filerevert-identical": "Dabartinė failo versija jau yra identiška pasirinktajai.",
"filedelete": "Trinti $1",
"filedelete-legend": "Trinti rinkmeną",
"filedelete-intro": "Jūs ketinate ištrinti failą '''[[Media:$1|$1]]''' su visa istorija.",
"pageinfo-article-id": "Puslapio ID",
"pageinfo-language": "Puslapio turinio kalba",
"pageinfo-content-model": "Puslapio turinio modelis",
+ "pageinfo-content-model-change": "keisti",
"pageinfo-robot-policy": "Robotų indeksavimas",
"pageinfo-robot-index": "Leidžiama",
"pageinfo-robot-noindex": "Neleidžiama",
"pagecategories": "{{PLURAL:$1|श्रेणी|श्रेणीसभ}}",
"category_header": "श्रेणी \"$1\" मे पन्ना सभ",
"subcategories": "उपश्रेणी",
- "category-media-header": "शà¥\8dरà¥\87णà¥\80 \"$1\" मà¥\87 मà¥\80डिया",
+ "category-media-header": "शà¥\8dरà¥\87णà¥\80 \"$1\" मà¥\87 मिडिया",
"category-empty": "<em>ई श्रेणीमे ई समय कोनो पृष्ठ या मिडिया नै अछि।</em>",
"hidden-categories": "{{PLURAL:$1|नुकाएल श्रेणी|नुकाएल श्रेणीसभ}}",
"hidden-category-category": "नुकाएल श्रेणीसभ",
"broken-file-category": "पन्नासभ जाइमे फाइल लिङ्कसभ टूटल हुअए",
"about": "क विषयमे",
"article": "सामग्री लेख",
- "newwindow": "(नव à¤\96िडà¤\95à¥\80सà¤\81 à¤\96à¥\81à¤\9cà¥\88à¤\9b)",
+ "newwindow": "(नव विनà¥\8dडà¥\8bमà¥\87 à¤\96à¥\81à¤\9cत)",
"cancel": "रद्द करी",
"moredotdotdot": "आर...",
"morenotlisted": "ई पुरा सूची नै छी।",
"otherlanguages": "अन्य भाषासभमे",
"redirectedfrom": "($1सँ पुनर्निर्देशित)",
"redirectpagesub": "पृष्ठ पुनर्निर्देशित करी",
- "redirectto": "क अनुप्रेषित:",
- "lastmodifiedat": "à¤\88 पà¥\83षà¥\8dठà¤\95 पहिनà¥\81à¤\95ा बदलाव $1 à¤\95à¥\87 $2 बà¤\9cà¥\87 à¤à¤\8fल छल।",
+ "redirectto": "कऽ अनुप्रेषित:",
+ "lastmodifiedat": "à¤\88 पà¥\83षà¥\8dठà¤\95 पहिनà¥\81à¤\95ा बदलाव $1 à¤\95à¥\87 $2 बà¤\9cà¥\87 à¤à¥\87ल छल।",
"viewcount": "ई पृष्ठ {{PLURAL:$1|एक|$1}} बेर देखल गेल छल।",
"protectedpage": "सुरक्षित पृष्ठ",
"jumpto": "एतय जाए:",
"yourpasswordagain": "कुटशब्द फेरसँ टाइप करी:",
"createacct-yourpasswordagain": "कुटशब्द जाँच करी",
"createacct-yourpasswordagain-ph": "कुटशब्द पुनः लिखी",
- "remembermypassword": "ई ब्राउजर पर हमर सम्प्रवेश याद राखी (अधिकतम $1 {{PLURAL:$1|दिन|दिनधरि}}क लेल)",
"userlogin-remembermypassword": "हमरा सम्प्रवेशित राखी",
"userlogin-signwithsecure": "सुरक्षित कनेक्शनक प्रयोग करी",
"cannotloginnow-title": "अखन प्रवेश नै भऽ रहल अछि",
"gotaccountlink": "सम्प्रवेश",
"userlogin-resetlink": "अपन सम्प्रवेश विवरण बिसरि गेलौ?",
"userlogin-resetpassword-link": "अपन कूटशब्द बिसरि गेलौ?",
- "userlogin-helplink2": "सम्प्रवेशित करवाकलेल मदत",
+ "userlogin-helplink2": "सम्प्रवेशित करवाक लेल मदति",
"userlogin-loggedin": "अहाँ {{GENDER:$1|$1}}क रूपमे पहिनेसँ सम्प्रवेशित छी।\nकोनो दोसर सदस्यक रुपमे सम्प्रवेशित करवाक लेल देल गेल फारमके प्रयोग करी।",
"userlogin-reauth": "अहाँ {{GENDER:$1|$1}} छी, एहि लेल अहाँक एक बेर आर खातामे प्रवेश करै पडत।",
"userlogin-createanother": "दोसर खाता बनाबी",
"createaccountreason": "कारण:",
"createacct-reason": "कारण:",
"createacct-reason-ph": "अहा इगो आर दोसर खाता कियाक बनउने जा रहल छि",
- "createacct-submit": "à¤\85पन à¤\96ाता बनाà¤\89",
+ "createacct-submit": "à¤\85पन à¤\96ाता बनाबà¥\80",
"createacct-another-submit": "खाता बनाबी",
- "createacct-benefit-heading": "{{SITENAME}} à¤\85हाà¤\81 à¤\9cà¥\8bà¤\95ा लà¥\8bà¤\97सà¤à¤¦à¥\8dवारा बनाà¤\8fल à¤\97à¤\8fल अछि।",
+ "createacct-benefit-heading": "{{SITENAME}} à¤\85हाà¤\81 à¤\9cà¥\8bà¤\95ा लà¥\8bà¤\97सà¤à¤¦à¥\8dवारा बनाà¤\8fल à¤\97à¥\87ल अछि।",
"createacct-benefit-body1": "$1 {{PLURAL:$1|सम्पादन|सम्पादनसभ}}",
"createacct-benefit-body2": "{{PLURAL:$1|पन्ना|पन्नासभ}}",
"createacct-benefit-body3": "सन्निकट {{PLURAL:$1|योगदानकर्ता|योगदानकर्तासभ}}",
"sectioneditnotsupported-text": "ई पृष्ठ पर अनुभाग सम्पादन समर्थित नै अछि",
"permissionserrors": "आज्ञा गल्ती",
"permissionserrorstext": "अहाँके ऐ लेल अनुमति नै अछि, ऐ ले {{PLURAL:$1|कारण|कारणसभ}}:",
- "permissionserrorstext-withaction": "अहाँके अनुमति नै अछि $2 लेल, ऐ लेल {{PLURAL:$1|कारण|कारणसभ}}सँ:",
+ "permissionserrorstext-withaction": "अहाँक अनुमति नै अछि $2 लेल, एकर लेल {{PLURAL:$1|कारण|कारणसभ}}सँ:",
"recreate-moveddeleted-warn": "'''चेतौनी''': अहाँ फेरसँ ओ पन्ना बना रहल छी जे पहिने मेटा देल गेल छै।'''\n\nअहाँ विचारू जे की ई सम्पादन केनाइ उचित अछि।\nऐ पन्नाक मेटाएल बला आ हटाएल वृत्तलेख एतए सुविधा लेल देल जा रहल अछि:",
- "moveddeleted-notice": "ई पन्ना मेटा देल गेल अछि।\nऐ पन्ना लेल मेटाएल आ हटाएल बला वृत्तलेख सन्दर्भ लेल नीचाँ देल गेल अछि।",
+ "moveddeleted-notice": "ई पन्ना मेटाएल गेल अछि।\nई पन्ना लेल मेटाएल आ स्थानान्तरणक लग सन्दर्भ लेल नीचाँ देल गेल अछि।",
"log-fulllog": "सभटा वृत्तलेख देखी",
"edit-hook-aborted": "सम्पादन नोकसीसँ खतम भेल।\nई कोनो कारण नै देलक।",
"edit-gone-missing": "पन्ना अद्यतन नै भऽ सकल।\nलगैए जे ई मेटा देल गेल अछि।",
"revertmerge": "नै मिज्झर",
"mergelogpagetext": "नीचाँ एक पन्ना इतिहासक दोसरमे अद्यतन मिश्रणक सूची अछि।",
"history-title": "\"$1\" क संशोधन इतिहास",
- "difference-title": "\"$1\" à¤\95à¥\87 à¤\85वतरणसà¤à¤®à¥\87 à¤\85à¤\82तर",
+ "difference-title": "\"$1\" à¤\95à¥\87 à¤\85वतरणसà¤à¤®à¥\87 à¤\85नà¥\8dतर",
"difference-title-multipage": "\"$1\" आर \"$2\" पृष्ठसभ मे अंतर",
"difference-multipage": "(पन्ना सभक बीचमे अन्तर)",
"lineno": "पंक्त्ति $1:",
"next-page": "अगला पृष्ठ",
"prevn-title": "पहिलुका $1 {{PLURAL:$1|परिणाम|परिणामसभ}}",
"nextn-title": "आगाँ $1 {{PLURAL:$1|परिणाम|परिणामसभ}}",
- "shown-title": "पà¥\8dरति पनà¥\8dना $1 {{PLURAL:$1|परिणाम|परिणामसà¤}} दà¥\87à¤\96ाà¤\89",
+ "shown-title": "पà¥\8dरति पनà¥\8dना $1 {{PLURAL:$1|परिणाम|परिणामसà¤}} दà¥\87à¤\96ाबà¥\80",
"viewprevnext": "देखी ($1 {{int:pipe-separator}} $2) ($3)",
"searchmenu-exists": "<strong>ऐ विकीपर एकटा पन्ना अछि \"[[:$1]]\" नामसँ।<strong>{{PLURAL:$2|0=|अन्य भेटल परिणामसभ सेहो देखी}}",
"searchmenu-new": "''' पन्ना निर्माण \"[[:$1]]\" ऐ विकीपर !'''",
"enhancedrc-history": "इतिहास",
"recentchanges": "लगक परिवर्तनसभ",
"recentchanges-legend": "नव परिवर्तन सम्बन्धी विकल्प",
- "recentchanges-summary": "ई पन्नापर विकीमे भेल सभसँ अद्यतन परिवर्तनपर नजरि राखू।",
+ "recentchanges-summary": "ई पन्नापर विकीमे भेल सभ सँ अद्यतन परिवर्तनपर नजरि राखी।",
"recentchanges-noresult": "इ अवधिके दौरान इ मापदंडके पूर्ण करेत समय कोनो परिवर्तन नै केएल गेल अछि।",
"recentchanges-feed-description": "ई सूचना-तंत्रांशमे विकीमे भेल सभसँ लगक परिवर्तन ताकी।",
"recentchanges-label-newpage": "ई सम्पादन एकटा नव पन्नाक निर्माण केलक।",
"recentchanges-label-minor": "ई एकटा लघु सम्पादन छी",
"recentchanges-label-bot": "ई सम्पादन यान्त्रिक छल।",
"recentchanges-label-unpatrolled": "ऐ सम्पादनक पुनरीक्षण अखन धरि नै कएल गेल अछि।",
- "recentchanges-label-plusminus": "पन्नाके आकार इ बाइट संख्यासे बदलल गेल",
+ "recentchanges-label-plusminus": "पन्ना आकार ई बाइट सङ्ख्या सँ बदलल गेल",
"recentchanges-legend-heading": "<strong>कुञ्जी:</strong>",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नव पन्नसभक सूची]] सेहो देखी)",
"rcnotefrom": "नीचाँमे '''$2''' सँ भेल परिवर्तन अछि ('''$1''' धरि देखाएल)।",
"rc_categories": "संवर्ग सीमित (\"|\" सँ हटाउ)",
"rc_categories_any": "कोनो",
"rc-change-size": "$1",
- "rc-change-size-new": "बदललाक बाद $1 {{PLURAL:$1|बाइट}}",
+ "rc-change-size-new": "परिवरà¥\8dतनक बाद $1 {{PLURAL:$1|बाइट}}",
"newsectionsummary": "/* $1 */ नव अनुभाग",
"rc-enhanced-expand": "वर्णन देखाउ (जावास्क्रिप्ट चाही)",
"rc-enhanced-hide": "विस्तृत जानकारी नुकाबी",
"listfiles-summary": "ई विशिष्ट पन्ना सभटा उपारोपित संचिका देखबैए।\nप्रयोक्ता द्वारा चुनलापर अन्तिम उपारोपित संचिका देखबैत अछि।",
"listfiles_search_for": "ऐ दृश्य-श्रव्य नामले ताकू:",
"listfiles-userdoesnotexist": "प्रयोक्ता खाता \"$1\" पंजीकृत नै अछि।",
- "imgfile": "सà¤\82चिका",
+ "imgfile": "सà¤\9eà¥\8dचिका",
"listfiles": "संचिका सूची",
"listfiles_thumb": "लघुचित्र",
"listfiles_date": "तिथि",
"filehist-filesize": "संचिका आकार",
"filehist-comment": "समीक्षा",
"imagelinks": "फाइलक उपयोग",
- "linkstoimage": "à¤\90 {{PLURAL:$1|पनà¥\8dनाà¤\95 लाà¤\97ि |$1 पनà¥\8dनाà¤\95 लाà¤\97ि}} à¤\90 फाà¤\87लसà¤\81:",
+ "linkstoimage": "à¤\88 {{PLURAL:$1|पà¥\83षà¥\8dठ|$1 पनà¥\8dनासà¤}}मà¥\87 à¤\88 फाà¤\87लà¤\95 लिà¤\99à¥\8dà¤\95 à¤\85à¤\9bि:",
"linkstoimage-more": "$1 सँ बेसी {{PLURAL:$1|page links|पन्ना सभक लागि}} ऐ संचिकाक।\nई सूची देखबैए {{PLURAL:$1|first page link|first $1 page links}} मात्र ऐ संचिकाक।\nएकटा [[Special:WhatLinksHere/$2|पूर्ण सूची]] उपलब्ध अछि।",
- "nolinkstoimage": "à¤\8fà¤\95à¥\8bà¤\9fा पनà¥\8dना नà¥\88 à¤\85à¤\9bि à¤\9cà¤\95र लाà¤\97ि à¤\90 सà¤\82à¤\9aिà¤\95ासà¤\81 हà¥\81à¤\85ए।",
+ "nolinkstoimage": "à¤\8fà¤\95à¥\8bà¤\9fा पनà¥\8dना नà¥\88 à¤\85à¤\9bि à¤\9cà¥\87 à¤\88 सà¤\9eà¥\8dà¤\9aिà¤\95ा सà¤\81 à¤\9cà¥\81डल हà¥\8bए।",
"morelinkstoimage": "देखू [[Special:WhatLinksHere/$1|आर लागि]] ऐ संचिकाक।",
"linkstoimage-redirect": "$1 (संचिका घुमौआ) $2",
"duplicatesoffile": "ऐ संचिकाक {{PLURAL:$1|file is a duplicate|$1 संचिका सभ द्वितीयक अछि}} अछि ([[Special:FileDuplicateSearch/$2|आर वर्णन]]):",
"shared-repo-from": "$1 सँ",
"shared-repo": "एकटा साझी बखारी",
"shared-repo-name-wikimediacommons": "सामान्य विकीमीडिया",
- "upload-disallowed-here": "à¤\85पनà¥\87 यà¥\80 फ़ाà¤\87लà¤\95à¥\87 à¤\85धिलà¥\87à¤\96ित नà¥\88 à¤\95à¥\88रऽ सà¤\95à¥\88 à¤\9bि।",
+ "upload-disallowed-here": "à¤\85हाà¤\81 à¤\88 फाà¤\87लà¤\95à¥\87 à¤\85धिलà¥\87à¤\96ित नà¥\88 à¤\95रि सà¤\95à¥\88त à¤\9bà¥\80।",
"filerevert": "$1 लग घुरु",
"filerevert-legend": "घुराएल संचिका",
"filerevert-intro": "अहाँ संचिका घुराबैले छी '''[[Media:$1|$1]]''' केँ [$4 संस्करण $3, $2 केँ] लग।",
"removewatch": "साकांक्ष सूचीसँ हटाबी",
"removedwatchtext": "अहाँक [[Special:Watchlist|ध्यानसूची]]सँ \"[[:$1]]\" आ एकर चर्चा पृष्ठ हटाएल गेल अछि।",
"removedwatchtext-short": "इ पृष्ठ \"$1\" अहाँ के साकांक्ष सूची मे राखल गेल अछि।",
- "watch": "धà¥\8dयान राà¤\96à¥\81",
+ "watch": "धà¥\8dयान राà¤\96à¥\80",
"watchthispage": "ऐ पृष्ठपर ध्यान राखू",
"unwatch": "छोडी",
"unwatchthispage": "देखनाइ छोडी",
"deleting-backlinks-warning": "'''चेतौनी:''' जे पृष्ठ अहाँ हटावए लेल जा रहल छी वोकरा में [[Special:WhatLinksHere/{{FULLPAGENAME}}|अन्य पृष्ठ]] जुड़एत अछि अथवा वोकरा ट्रान्सक्ल्युड करएत अछि।",
"rollback": "प्रत्यावर्तित सम्पादन",
"rollbacklink": "प्रत्यावर्तन",
- "rollbacklinkcount": "$1 {{PLURAL:$1|समà¥\8dपादन}} पà¥\82रà¥\8dववत à¤\95रà¥\82",
+ "rollbacklinkcount": "$1 {{PLURAL:$1|समà¥\8dपादन}} पà¥\82रà¥\8dववत à¤\95रà¥\80",
"rollbacklinkcount-morethan": "$1 सँ अधिक {{PLURAL:$1|सम्पादन}} पूर्ववत करू",
"rollbackfailed": "प्रत्यावर्तन असफल",
"cantrollback": "सम्पादन आपस नै भऽ सकै अछि;\nअन्तिम योगदान दैबला ऐ पन्नाक एकमात्र लेखक छी।",
"invert": "उनटा चयन",
"tooltip-invert": "ऐ बक्साकेँ सही करू पन्ना परिवर्तनकेँ नुकेबा लेल चयनित नामस्थानक भीतर (आ संग लागल नामस्थान जँ सही कएल अछि तखन)",
"namespace_association": "सम्बद्ध चेन्हासी",
- "tooltip-namespace_association": "à¤\90 बà¤\95à¥\8dसाà¤\95à¥\87à¤\81 सहà¥\80 à¤\95रà¥\82 जइसँ वार्ता आ विषय नामस्थान समाहित कएल जा सकए चुनल नामस्थानमे",
+ "tooltip-namespace_association": "à¤\88 बà¤\95à¥\8dसाà¤\95à¥\87à¤\81 सहà¥\80 à¤\95रà¥\80 जइसँ वार्ता आ विषय नामस्थान समाहित कएल जा सकए चुनल नामस्थानमे",
"blanknamespace": "(मुख्य)",
"contributions": "{{GENDER:$1|प्रयोगकर्ता}} योगदान",
"contributions-title": "$1 लेल प्रयोक्ताक अवदान",
"nocontribs": "कोनो परिवर्तन ऐ सँ मेल नै खाइए।",
"uctop": "(शिखर)",
"month": "माससँ (आ पहिने)",
- "year": "à¤\90 साल (आ पहिने)",
+ "year": "à¤\88 साल (आ पहिने)",
"sp-contributions-newbies": "मात्र नव खाताक योगदान देखाबी",
"sp-contributions-newbies-sub": "नब प्रयोक्ताकऽ लेल",
"sp-contributions-newbies-title": "नब प्रयोक्ताकऽ योगदान",
"sp-contributions-newonly": "मात्र ओइ सम्पादन देखाउ जे पृष्ठ निर्मित भेल अछि",
"sp-contributions-submit": "ताकू",
"whatlinkshere": "एतय कोन लिङ्क अछि",
- "whatlinkshere-title": "\"$1\" सँ सम्बन्धित पन्ना सभ",
+ "whatlinkshere-title": "\"$1\" सँ सम्बन्धित पन्नासभ",
"whatlinkshere-page": "पन्ना:",
"linkshere": "ई सभ पन्ना सम्बन्धित अछि '''[[:$1]]''':",
"nolinkshere": "'''[[:$1]]''' पर कोनो पन्नाक लागि नै अछि।",
"nolinkshere-ns": "कोनो पन्नाक लागि '''[[:$1]]''' चुनल नामगाममे नै अछि।",
- "isredirect": "पनà¥\8dनाà¤\95à¥\87à¤\81 à¤\98à¥\81राà¤\89",
+ "isredirect": "पà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन पà¥\83षà¥\8dठ",
"istemplate": "परागत",
- "isimage": "फाइलकऽ जडी",
+ "isimage": "फाइल लिङ्क",
"whatlinkshere-prev": "{{PLURAL:$1|पहिलुका|पहिलुका $1}}",
"whatlinkshere-next": "{{PLURAL:$1|अगुलका|अगुलका $1}}",
"whatlinkshere-links": "← जडीसभ",
- "whatlinkshere-hideredirs": "$1 बदलà¥\87न नà¥\81à¤\95ाबà¥\80",
- "whatlinkshere-hidetrans": "$1 पराà¤\97त",
- "whatlinkshere-hidelinks": "$1 समà¥\8dबनà¥\8dध सà¤",
+ "whatlinkshere-hideredirs": "$1 पà¥\81नरà¥\8dनिरà¥\8dदà¥\87श",
+ "whatlinkshere-hidetrans": "$1 à¤\9fà¥\8dरानà¥\8dसà¥\8dà¤\95à¥\8dलà¥\8dयà¥\81à¤\9cनà¥\8dस",
+ "whatlinkshere-hidelinks": "$1 लिà¤\99à¥\8dà¤\95",
"whatlinkshere-hideimages": "$1 फाइल जडी सभ",
- "whatlinkshere-filters": "चलनी सभ",
+ "whatlinkshere-filters": "चलनीसभ",
"autoblockid": "स्वतःप्रतिबन्धित #$1",
"block": "प्रयोक्ताकेँ प्रतिबन्धित करू",
"unblock": "प्रयोक्ताकेँ प्रतिबन्धसँ हटाउ",
"movepage-page-moved": "पन्ना $1 केँ $2 लग घसका देल गेल अछि।",
"movepage-page-unmoved": "पन्ना $1 केँ $2 लग नै घसकाएल जा सकैए।",
"movepage-max-pages": "बेसी सें बेसी $1 पृष्ठ बदलि के {{PLURAL:$1| क देल गेल अछि|क देल गेल अछि}}, आब आर पृष्ठ अपने आप नहि बदलत.",
- "movelogpage": "वà¥\83तà¥\8dतलà¥\87à¤\96 हà¤\9fाà¤\89",
+ "movelogpage": "सà¥\8dथानानà¥\8dतरण लà¤\97",
"movelogpagetext": "नाम बदलल गेल लेख कऽ सूचि नीचां देल गेल अछि",
"movesubpage": "{{PLURAL:$1|उप पन्ना|उप पन्ना}}",
"movesubpagetext": "नीचां $1 {{PLURAL:$1| पन्ना देखाओल गएल अछि, जे अहि पन्नाकऽ उप पन्ना अछि|पन्ना देखावोल गएल अछि, जे अहि पन्नाकऽ उप पन्ना अछि}}।",
"tooltip-pt-mytalk": "{{GENDER:|अहाँक}} वार्ता पृष्ठ",
"tooltip-pt-anontalk": "ऐ अनिकेतसँ भेल सम्पादनक वार्ता",
"tooltip-pt-preferences": "{{GENDER:|अहाँक}} अभिरुचीसभ",
- "tooltip-pt-watchlist": "पन्ना सभ जकर परिवर्त्तन पर अहाँक नजरि अछि",
+ "tooltip-pt-watchlist": "पन्नासभ जेकर परिवर्तन पर अहाँक नजरि अछि",
"tooltip-pt-mycontris": "{{GENDER:|अहाँक}} योगदानक सूची",
- "tooltip-pt-login": "à¤\85हाà¤\81à¤\95 à¤\96ाता à¤\96à¥\8bलà¤\95 लà¥\87ल पà¥\8dरà¥\8bतà¥\8dसाहित à¤\95à¥\87ल à¤\9cाà¤\8fत अछि; मुदा ई अनिवार्य नै अछि",
+ "tooltip-pt-login": "à¤\85हाà¤\81à¤\95 à¤\96ाता à¤\96à¥\8bलà¤\95 लà¥\87ल पà¥\8dरà¥\8bतà¥\8dसाहित à¤\95à¤\8fल à¤\9cाà¤\87त अछि; मुदा ई अनिवार्य नै अछि",
"tooltip-pt-logout": "फेर आयब",
- "tooltip-pt-createaccount": "à¤\85हाà¤\81à¤\95 à¤\96ाता à¤\96à¥\8bलà¤\95 लà¥\87ल पà¥\8dरà¥\8bतà¥\8dसाहित à¤\95à¥\87ल à¤\9cाà¤\8fत à¤\85à¤\9bि; मà¥\81दा à¤\88 à¤\85निवारà¥\8dय नà¥\88 à¤\9bà¥\88",
+ "tooltip-pt-createaccount": "à¤\85हाà¤\81à¤\95 à¤\96ाता à¤\96à¥\8bलà¤\95 लà¥\87ल पà¥\8dरà¥\8bतà¥\8dसाहित à¤\95à¤\8fल à¤\9cाà¤\87त à¤\85à¤\9bि; मà¥\81दा à¤\88 à¤\85निवारà¥\8dय नà¥\88 à¤\85à¤\9bि",
"tooltip-ca-talk": "विषयसूचीक पन्नाक सम्बन्धमे वर्त्तालाप",
"tooltip-ca-edit": "ई पन्नाक सम्पादित करी",
"tooltip-ca-addsection": "नव खण्ड शुरू करी",
- "tooltip-ca-viewsource": "à¤\90 पनà¥\8dनापर वरदहसà¥\8dत à¤\9bà¥\88।\nà¤\85हाà¤\81 à¤\8fà¤\95र à¤\9cड़ि दà¥\87à¤\96 सà¤\95à¥\88 à¤\9bà¥\80।",
+ "tooltip-ca-viewsource": "à¤\88 पनà¥\8dना सà¤\82रà¤\95à¥\8dषित à¤\85à¤\9bि ।\nà¤\85हाà¤\81 à¤\8fà¤\95र सà¥\8dरà¥\8bत दà¥\87à¤\96 सà¤\95à¥\88 à¤\9bà¥\80 ।",
"tooltip-ca-history": "ई पृष्ठक पुरान अवतरण",
"tooltip-ca-protect": "ऐ पन्नाकेँ बचाउ",
"tooltip-ca-unprotect": "ऐ पन्नाक रक्षा कवच बदलू",
"tooltip-ca-delete": "ऐ पन्नाकेँ मेटाउ",
"tooltip-ca-undelete": "ई पन्ना मेटेबासँ पहिने भेल सम्पादन वापस करू",
- "tooltip-ca-move": "à¤\90 पà¥\83षà¥\8dठà¤\95à¥\87à¤\81 हà¤\9fाà¤\89",
+ "tooltip-ca-move": "à¤\88 पà¥\83षà¥\8dठसà¥\8dथानानतरित à¤\95रà¥\80",
"tooltip-ca-watch": "ई पन्नाकेँ अपन साकांक्षसूचीमे राखी",
"tooltip-ca-unwatch": "ऐ पन्नाकेँ हमर साकांक्ष सूचीसँ हटाउ",
"tooltip-search": "{{SITENAME}}मे ताकी",
"tooltip-n-currentevents": "लगक घटनाक विषयमे आधार सूचना प्राप्त करी।",
"tooltip-n-recentchanges": "विकिमे लगक परिवर्तनक सूची",
"tooltip-n-randompage": "कोनो अनिर्धारित पन्ना लोड करी",
- "tooltip-n-help": "पता लà¤\97ावà¤\8f वाला स्थान",
+ "tooltip-n-help": "पता लà¤\97ावà¥\88वाला स्थान",
"tooltip-t-whatlinkshere": "सभ विकी-पन्नाक सूची जकर एतय लिङ्क अछि",
"tooltip-t-recentchangeslinked": "ई पृष्ठक लगक पन्नामे भेल नव परिवर्तनसभ",
"tooltip-feed-rss": "ऐ पन्ना लेल आर.एस.एस. सूचना",
"tooltip-t-print": "ई पृष्ठक छपैबला रूप",
"tooltip-t-permalink": "पृष्ठक ई संस्करणक स्थायी लिङ्क",
"tooltip-ca-nstab-main": "सामग्री वाला पृष्ठ देखी",
- "tooltip-ca-nstab-user": "प्रयोक्ता पन्नाकेँ देखू",
+ "tooltip-ca-nstab-user": "प्रयोक्ता पन्ना देखी",
"tooltip-ca-nstab-media": "मीडिया पृष्ठ देखू",
"tooltip-ca-nstab-special": "ई एकटा विशिष्ट पन्ना छी, आ अहाँ एकरा सम्पादित नै कऽ सकै छी",
- "tooltip-ca-nstab-project": "परियà¥\8bà¤\9cना पनà¥\8dना दà¥\87à¤\96à¥\82",
+ "tooltip-ca-nstab-project": "परियà¥\8bà¤\9cना पनà¥\8dना दà¥\87à¤\96à¥\80",
"tooltip-ca-nstab-image": "सञ्चिकाक पृष्ठ देखी",
"tooltip-ca-nstab-mediawiki": "प्रणालीक सन्देश देखी",
- "tooltip-ca-nstab-template": "नमà¥\82ना दà¥\87à¤\96à¥\82",
+ "tooltip-ca-nstab-template": "नमà¥\82ना दà¥\87à¤\96à¥\80",
"tooltip-ca-nstab-help": "सहायता पृष्ठ देखू",
- "tooltip-ca-nstab-category": "सà¤\82वरà¥\8dà¤\97 पनà¥\8dना दà¥\87à¤\96à¥\82",
+ "tooltip-ca-nstab-category": "शà¥\8dरà¥\87णà¥\80 पनà¥\8dना दà¥\87à¤\96à¥\80",
"tooltip-minoredit": "एकरा मामली सम्पादन चिन्हित करू",
- "tooltip-save": "à¤\85पन परिवरà¥\8dतà¥\8dतनà¤\95à¥\87 सà¥\81रà¤\95à¥\8dषित à¤\95रà¥\82",
- "tooltip-preview": "परिवरà¥\8dतà¥\8dतनà¤\95 पà¥\8dरदरà¥\8dशन, सà¤\82à¤\9cà¥\8bà¤\97बाà¤\95 पहिनà¥\87 à¤\8fà¤\95र पà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\82!",
- "tooltip-diff": "दà¥\87à¤\96ाà¤\8a à¤\9cà¥\87 परिवरà¥\8dतà¥\8dतन à¤\85हाà¤\81 à¤\8fहि लà¥\87à¤\96मà¥\87 à¤\95à¤\8fलहà¥\81à¤\81।",
+ "tooltip-save": "à¤\85पन परिवरà¥\8dतन सà¥\81रà¤\95à¥\8dषित à¤\95रà¥\80",
+ "tooltip-preview": "परिवरà¥\8dतनà¤\95 पà¥\8dरदरà¥\8dशन, सà¤\82रà¤\95à¥\8dषण सà¤\81 पहिनà¥\87 à¤\8fà¤\95र पà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\80!",
+ "tooltip-diff": "à¤\88 पाठमà¥\87 à¤\85हाà¤\81दà¥\8dवारा à¤\95à¤\8fल परिवरà¥\8dतन दà¥\87à¤\96à¥\80।",
"tooltip-compareselectedversions": "ऐ पन्नाक दू टा चयन कएल संशोधनक बीचक अन्तर देखू",
"tooltip-watch": "ऐ पन्नाकेँ अपन साकांक्ष सूचीमे जोड़ू",
"tooltip-watchlistedit-normal-submit": "शीर्षक सभकेँ हटाउ",
"file-info-size": "$1 × $2 चित्राणु, फाइल आकार: $3, माइम प्रकार: $4",
"file-info-size-pages": "$1 × $2 चित्रकण, संचिका आकार : $3, माइम प्रकार: $4, $5 {{PLURAL:$5|पन्ना|पन्ना सभ}}",
"file-nohires": "ऐसँ बेशी आनन्तर्य उपलब्ध नै अछि।",
- "svg-long-desc": "एस.वी.जी. फाइल, मामूली रूपमे $1 × $2 चित्रकण, फाइलक आकार: $3",
+ "svg-long-desc": "एसभिजी फाइल, मामूली रूपमे $1 × $2 चित्रकण, फाइलक आकार: $3",
"svg-long-desc-animated": "एनिमेटेड एस.वी.जी. फाइल,$1 × $2 चित्रकण, फाइलक आकार: $3",
"svg-long-error": "अमान्य एस॰वी॰जी फ़ाइल: $1",
"show-big-image": "पूर्ण आनन्तर्य",
"exif-referenceblackwhite": "कारी आ उज्जर सन्दर्भ मूल्यक जोड़ा",
"exif-datetime": "संचिका परिवर्तन तिथि आ समए",
"exif-imagedescription": "चित्र शीर्षक",
- "exif-make": "à¤\95à¥\88मरा निर्माता",
+ "exif-make": "à¤\95à¥\8dयामरा निर्माता",
"exif-model": "क्यामरा मोडल",
- "exif-software": "पà¥\8dरयà¥\81à¤\95à¥\8dत तà¤\82तà¥\8dराà¤\82श",
+ "exif-software": "पà¥\8dरयà¥\8bà¤\97 à¤\95à¤\8fल सफà¥\8dà¤\9fवà¥\87यर",
"exif-artist": "लिखैबला",
"exif-copyright": "सर्वाधिकारी",
"exif-exifversion": "एक्जिफ संस्करण",
"exif-flashpixversion": "फ्लैशपिक्स संस्करण समर्थित",
- "exif-colorspace": "रà¤\82गक स्थान",
+ "exif-colorspace": "रà¤\99à¥\8dगक स्थान",
"exif-componentsconfiguration": "सभ घटकक अर्थ",
"exif-compressedbitsperpixel": "चित्र संकुचन अवस्था",
"exif-pixelxdimension": "तस्वीरक चौडाई",
"exif-pixelydimension": "तस्वीरक ऊँचाई",
"exif-usercomment": "सदस्यक टिप्पणी",
"exif-relatedsoundfile": "संबंधित ध्वनि फ़ाईल",
- "exif-datetimeoriginal": "डाà¤\9fा बनाबà¥\88à¤\95 तारà¥\80ख आ समय",
- "exif-datetimedigitized": "à¤\85à¤\82à¤\95à¥\80à¤\95रण à¤\95à¥\87 तारà¥\80ख आ समय",
+ "exif-datetimeoriginal": "डाà¤\9fा बनाबà¥\88à¤\95 तारिख आ समय",
+ "exif-datetimedigitized": "à¤\85à¤\99à¥\8dà¤\95à¥\80à¤\95रणà¤\95 तारिख आ समय",
"exif-subsectime": "दिनांकसमयक उपसेकंड",
"exif-subsectimeoriginal": "मूलदिनांकसमयक उपसेकंड",
"exif-subsectimedigitized": "मूलदिनांकअंकीकरणक उपसेकंड",
"logentry-import-upload": "$1 {{GENDER:$2|आयात केल गेल}} $3 संचिका उपारोपन के माध्यम सँ",
"logentry-import-interwiki": "$1 {{GENDER:$2|आयात केल गेल}} $3 कोनो और विकि सँ",
"logentry-merge-merge": "$1 {{GENDER:$2|विलय केल गेल}} $3 के $4 में (संशोधन $5 धरि)",
- "logentry-move-move": "$1 हटाएल पन्ना $3 सँ $4",
+ "logentry-move-move": "$1द्वारा $3 पृष्ठ $4 पर {{GENDER:$2|स्थानान्तरित}} कएलक",
"logentry-move-move-noredirect": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआकेँ बिना छोड़ने",
"logentry-move-move_redir": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतिरिक्त",
"logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतितिक्त घुमौआकेँ बिना छोड़ने",
"botpasswords-updated-body": "Лозинката на ботот со име „$1“ на корисникот „$2“ е изменета.",
"botpasswords-deleted-title": "Лозинка на ботот е избришана",
"botpasswords-deleted-body": "Лозинката на ботот со име „$1“ на корисникот „$2“ е избришана.",
- "botpasswords-newpassword": "Новата лозинка за најава <strong>$1</strong> е <strong>$2</strong>. <em>Запишете си ја за во иднина.</em>",
+ "botpasswords-newpassword": "Новата лозинка за најава <strong>$1</strong> е <strong>$2</strong>. <em>Запишете си ја за во иднина.</em> <br> (За стари ботови што бараат најавното име да биде исто како подоцнежното корисничко име, можете да ги употребите и <strong>$3</strong> како корисничко име и <strong>$4</strong> како лозинка.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider е недостапен.",
"botpasswords-restriction-failed": "Не можете да се најавите поради ограничувањата за лозинки на ботови.",
"botpasswords-invalid-name": "Укажаното корисничко име не го содржи одделувачот ботовска лозинка („$1“).",
"invalid-content-data": "Неважечки податоци од содржината",
"content-not-allowed-here": "Содржините од моделот „$1“ не се допуштени на страницата [[$2]]",
"editwarning-warning": "Ако ја напуштите страницата ќе ги изгубите сите промени кои сте ги направиле.\nАко сте најавени, можете да го исклучите ова предупредување во одделот „{{int:prefs-editing}}“ во вашите нагодувања.",
+ "editpage-invalidcontentmodel-title": "Содржинскиот модел не е поддржан",
+ "editpage-invalidcontentmodel-text": "Содржинскиот модел „$1“ не е поддржан.",
"editpage-notsupportedcontentformat-title": "Форматот на содржината не е поддржан",
"editpage-notsupportedcontentformat-text": "Форматот $1 is не е поддржан од содржинскиот модел $2.",
"content-model-wikitext": "викитекст",
"tag-filter": "[[Special:Tags|Филтер за ознаки]]:",
"tag-filter-submit": "Филтер",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Ознака|Ознаки}}]]: $2)",
+ "tag-mw-contentmodelchange": "измена на содржинскиот модел",
+ "tag-mw-contentmodelchange-description": "Уредувања што го [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel менуваат содржинскиот модел] на една страница",
"tags-title": "Ознаки",
"tags-intro": "На оваа страница е даден список на ознаки со кои програмската опрема може да ги означи измените и нивното значење.",
"tags-tag": "Име на ознака",
"tags-actions-header": "Дејства",
"tags-active-yes": "Да",
"tags-active-no": "Не",
- "tags-source-extension": "Ð\9eдÑ\80едени од додаÑ\82ок",
+ "tags-source-extension": "Ð\9eдÑ\80едени од пÑ\80огÑ\80амоÑ\82",
"tags-source-manual": "Применети рачно од корисници и ботови",
"tags-source-none": "Вон употреба",
"tags-edit": "уреди",
"backend-fail-delete": "Bô-hoat-tō· kā tóng-àn \"$1\" thâi tiāu",
"license": "Siū-khoân:",
"license-header": "Siū-khoân",
+ "imgfile": "tóng-àn",
"listfiles": "Iáⁿ-siōng lia̍t-toaⁿ",
"listfiles_date": "Ji̍t-kî",
"listfiles_name": "Miâ",
"withoutinterwiki-legend": "Prefiks",
"withoutinterwiki-submit": "Vis",
"fewestrevisions": "Sidene med færrast endringar",
- "nbytes": "$1 {{PLURAL:$1|byte|byte}}",
+ "nbytes": "$1 {{PLURAL:$1|byte}}",
"ncategories": "$1 {{PLURAL:$1|kategori|kategoriar}}",
"ninterwikis": "{{PLURAL:$1|éin interwiki|$1 interwikiar}}",
"nlinks": "{{PLURAL:$1|Éi lenkje|$1 lenkjer}}",
"cannotloginnow-title": "W tej chwili nie można się teraz zalogować",
"cannotloginnow-text": "Podczas korzystania z $1 nie można się zalogować.",
"cannotcreateaccount-title": "Nie można utworzyć kont",
+ "cannotcreateaccount-text": "Bezpośrednie tworzenie konta nie jest włączone na tej wiki.",
"yourdomainname": "Twoja domena:",
"password-change-forbidden": "Nie można zmieniać haseł na tej wiki.",
"externaldberror": "Wystąpił błąd autentyfikacyjnej bazy danych lub nie posiadasz uprawnień koniecznych do aktualizacji zewnętrznego konta.",
"file-thumbnail-no": "Nazwa pliku zaczyna się od <strong>$1</strong>.\nWydaje się, że jest to pomniejszona grafika ''(miniaturka)''.\nJeśli posiadasz tę grafikę w pełnym rozmiarze – prześlij ją. Jeśli chcesz wysłać tę – zmień nazwę przesyłanego obecnie pliku.",
"fileexists-forbidden": "Plik o tej nazwie już istnieje i nie może zostać nadpisany.\nJeśli chcesz przesłać plik cofnij się i prześlij go pod inną nazwą. [[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Plik o tej nazwie już istnieje we współdzielonym repozytorium plików.\nCofnij się i załaduj plik pod inną nazwą. [[File:$1|thumb|center|$1]]",
+ "fileexists-duplicate-version": "{{PLURAL:$2|Przesłany plik jest dokładną kopią starszej wersji pliku|Przesłane pliki są dokładnymi kopiami starszych wersji plików}} <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "Ten plik jest kopią {{PLURAL:$1|pliku|następujących plików}}:",
"file-deleted-duplicate": "Identyczny do tego plik ([[:$1]]) został wcześniej usunięty.\nSprawdź historię usunięć tamtego pliku zanim prześlesz go ponownie.",
"file-deleted-duplicate-notitle": "Plik jest identyczny z plikiem, który został wcześniej usunięty, a jego nazwa została ukryta. Należy poprosić kogoś z możliwością przeglądania ukrytych danych, aby przeanalizował sytuację przed przystąpieniem do jego ponownego przesłania.",
"undeletedrevisions": "odtworzono {{PLURAL:$1|1 wersję|$1 wersje|$1 wersji}}",
"undeletedrevisions-files": "odtworzono $1 {{PLURAL:$1|wersję|wersje|wersji}} i $2 {{PLURAL:$2|plik|pliki|plików}}",
"undeletedfiles": "odtworzył $1 {{PLURAL:$1|plik|pliki|plików}}",
- "cannotundelete": "Odtworzenie nie powiodło się:\n$1",
+ "cannotundelete": "Niektóre lub wszystkie odtworzenia nie powiodły się:\n$1",
"undeletedpage": "'''Odtworzono stronę $1.'''\n\nZobacz [[Special:Log/delete|rejestr usunięć]], jeśli chcesz przejrzeć ostatnie operacje usuwania i odtwarzania stron.",
"undelete-header": "Zobacz [[Special:Log/delete|rejestr usunięć]], aby sprawdzić ostatnio usunięte strony.",
"undelete-search-title": "Przeszukiwanie usuniętych stron",
"pageinfo-article-id": "Identyfikator strony",
"pageinfo-language": "Język zawartości strony",
"pageinfo-content-model": "Model zawartości",
+ "pageinfo-content-model-change": "zmień",
"pageinfo-robot-policy": "Indeksowanie przez roboty",
"pageinfo-robot-index": "Dozwolone",
"pageinfo-robot-noindex": "Niedozwolone",
"createacct-yourpasswordagain-ph": "پټنوم مو بيا وټاپئ",
"userlogin-remembermypassword": "غونډال کې مې ننوتلی وساته",
"userlogin-signwithsecure": "خوندي اړيکتيا کارول",
+ "cannotcreateaccount-title": "گڼونونه نه شي جوړېدای",
"yourdomainname": "ستاسې شپول:",
"password-change-forbidden": "تاسې په دې ويکي باندې خپل پټنوم نه شی بدلولی.",
"login": "ننوتل",
"createacct-yourpasswordagain-ph": "Digite a senha novamente",
"userlogin-remembermypassword": "Mantenha-me conectado",
"userlogin-signwithsecure": "Use a conexão segura",
+ "cannotlogin-title": "Não é possível entrar com sua conta",
+ "cannotlogin-text": "Não é possível conectar-se.",
"cannotloginnow-title": "Não é possível iniciar a sessão agora",
"cannotloginnow-text": "Não é possível autenticar usando $1.",
+ "cannotcreateaccount-title": "Não é possível criar uma conta",
+ "cannotcreateaccount-text": "A criação direta de contas não está habilitada nessa wiki.",
"yourdomainname": "Seu domínio:",
"password-change-forbidden": "Você não pode alterar senhas nessa wiki.",
"externaldberror": "Ocorreu ou um erro no banco de dados durante a autenticação ou não lhe é permitido atualizar a sua conta externa.",
"botpasswords-updated-body": "A senha de robô para o robô de nome \"$1\" do usuário \"$2\" foi atualizada.",
"botpasswords-deleted-title": "Senha de bot apagada",
"botpasswords-deleted-body": "A senha de robô para o robô de nome \"$1\" do usuário \"$2\" foi apagada.",
- "botpasswords-newpassword": "A nova senha para se autenticar com <strong>$1</strong> é <strong>$2</strong>. <em>Por favor, guarde isto para referência futura.",
+ "botpasswords-newpassword": "A nova senha para se autenticar com <strong>$1</strong> é <strong>$2</strong>. <em>Por favor, guarde isto para referência futura.</em> <br> (para bots antigos que requisitam que o nome da conta seja o mesmo que o eventual nome de usuário, Você também pode usar <strong>$3</strong>como nome de usuário e <strong>$4</strong> como senha.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider não está disponível.",
"botpasswords-restriction-failed": "Restrições de senha de robô evitam esta autenticação.",
"botpasswords-invalid-name": "O nome de usuário especificado não contém o separador de senha de robô (\"$1\").",
"invalid-content-data": "Dados de conteúdo inválidos",
"content-not-allowed-here": "Conteúdo do tipo \"$1\" não é permitido na página [[$2]]",
"editwarning-warning": "Abandonar esta página pode fazer com que você perca todas as alterações que fez.\nSe você estiver autenticado, você pode desabilitar este aviso na seção {{int:prefs-editing}}\" de suas preferências.",
+ "editpage-invalidcontentmodel-title": "Modelo do conteúdo não suportado",
+ "editpage-invalidcontentmodel-text": "O modelo do conteúdo \"$1\" não é suportado.",
"editpage-notsupportedcontentformat-title": "Formato do conteúdo não suportado",
"editpage-notsupportedcontentformat-text": "O formato de conteúdo $1 não é suportando pelo modelo de conteúdo $2.",
"content-model-wikitext": "wikitexto",
"file-thumbnail-no": "O nome do arquivo começa com <strong>$1</strong>.\nIsso faz parecer se tratar de uma imagem de tamanho reduzido (''miniatura'', ou ''thumbnail'').\nSe você tem esta imagem em sua resolução completa, envie-a no lugar desta. Caso contrário, altere o nome de arquivo.",
"fileexists-forbidden": "Já existe um arquivo com este nome e ele não pode ser sobrescrito.\nSe ainda pretende enviar seu arquivo, volte e use um novo nome.\n[[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Já existe um arquivo com este nome no repositório de arquivos compartilhados.\nSe você ainda quer enviar seu arquivo, volte e use um novo nome.\n[[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "O arquivo carregado é uma duplicata exata da versão atual de <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "Este arquivo é uma duplicata do seguinte {{PLURAL:$1|arquivo|arquivos}}:",
"file-deleted-duplicate": "Um arquivo idêntico a este ([[:$1]]) foi eliminado anteriormente.\nVerifique o histórico de eliminação de tal arquivo antes de tentar re-enviar.",
"file-deleted-duplicate-notitle": "Um arquivo idêntico a este foi anteriormente excluído, e o título foi suprimido. Você deve comunicar com alguém capaz de visualizar dados suprimidos, para verificar a situação antes de enviá-lo novamente.",
"Josep Maria Roca Peña",
"Luan",
"Gato Preto",
- "Jdforrester"
+ "Jdforrester",
+ "Mansil"
]
},
"tog-underline": "Sublinhar ligações:",
"botpasswords-newpassword": "A nova palavra-passe para iniciar sessão com <strong>$1</strong> é <strong>$2</strong>. Por favor, recorde-se dela para futura referência.</em>",
"botpasswords-no-provider": "BotPasswordsSessionProvider não está disponível.",
"botpasswords-restriction-failed": "Restrições de senha de robô evitam esta autenticação.",
- "botpasswords-invalid-name": "O nome de usuário especificado não contém o separador de senha de robô (\"$1\").",
+ "botpasswords-invalid-name": "O nome de utilizador especificado não contém o separador de palavra-passe de robô (\"$1\").",
"botpasswords-not-exist": "O usuário \"$1\" não possui uma senha de robô \"$2\".",
"resetpass_forbidden": "Não é possível alterar palavras-passe",
"resetpass_forbidden-reason": "As palavras-passe não podem ser alteradas: $1",
"passwordreset-emailerror-capture2": "O envio do correio {{GENDER:$2|ao usuário|à usuária}} falhou: $1 {{PLURAL:$3|O nome de usuário e senha são mostradas abaixo|A lista de nomes de usuários e senhas é mostrada abaixo}}.",
"passwordreset-nocaller": "Um interlocutor deve ser fornecido",
"passwordreset-nosuchcaller": "A pessoa que chama não existe: $1",
- "passwordreset-ignored": "A redefinição de senha não foi realizada. Talvez o provedor não tenha sido configurado, sim?",
+ "passwordreset-ignored": "A reposição de palavra-passe não foi realizada. Talvez não tenha sido configurado o provedor?",
"passwordreset-invalideamil": "Correio eletrónico inválido",
"passwordreset-nodata": "Não foram fornecidos nome de utilizador(a) nem endereço de correio eletrónico",
"changeemail": "Alterar ou remover o endereço de correio eletrónico",
"apisandbox-loading-results": "A receber resultados da API...",
"apisandbox-request-url-label": "URL do pedido:",
"apisandbox-request-time": "Tempo de processamento: {{PLURAL:$1|$1 ms}}",
- "apisandbox-results-fixtoken": "Corrija o identificador e envie-o novamente",
- "apisandbox-results-fixtoken-fail": "Não foi possível recuperar o identificador \"$1\".",
+ "apisandbox-results-fixtoken": "Corrija o identificador e volte a submete-lo",
+ "apisandbox-results-fixtoken-fail": "Não foi possível obter o identificador \"$1\".",
"apisandbox-alert-page": "Os campos nesta página não são válidos.",
"apisandbox-alert-field": "O valor deste campo não é válido.",
"booksources": "Fontes bibliográficas",
"authpage-cannot-login-continue": "Não é possível continuar a iniciar sessão. A sua sessão pode ter expirado.",
"authpage-cannot-create": "Não é possível iniciar a criação da conta.",
"authpage-cannot-create-continue": "Não é possível continuar a criação da conta. A sua sessão pode ter expirado.",
- "authpage-cannot-link": "Não se pode iniciar a vinculação da conta.",
+ "authpage-cannot-link": "Não é possível iniciar a associação da conta.",
"authpage-cannot-link-continue": "Não é possível continuar a criação da conta. A sua sessão pode ter expirado.",
"cannotauth-not-allowed-title": "Permissão negada",
"cannotauth-not-allowed": "Não possui permissão para utilizar esta página",
"botpasswords-updated-body": "Success message when a bot password is updated. Parameters:\n* $1 - Bot name\n* $2 - User name",
"botpasswords-deleted-title": "Title of the success page when a bot password is deleted.",
"botpasswords-deleted-body": "Success message when a bot password is deleted. Parameters:\n* $1 - Bot name\n* $2 - User name",
- "botpasswords-newpassword": "Success message to display the new password when a bot password is created or updated. Parameters:\n* $1 - User name to be used for login.\n* $2 - Password to be used for login.",
+ "botpasswords-newpassword": "Success message to display the new password when a bot password is created or updated. Parameters:\n* $1 - User name to be used for login.\n* $2 - Password to be used for login.\n* $3, $4 - an alternative version of the user name and password, respectively, which is less preferred, but more compatible with old bots.",
"botpasswords-no-provider": "Error message when login is attempted but the BotPasswordsSessionProvider is not included in <code>$wgSessionProviders</code>.",
"botpasswords-restriction-failed": "Error message when login is rejected because the configured restrictions were not satisfied.",
"botpasswords-invalid-name": "Error message when a username lacking the separator character is passed to BotPassword. Parameters:\n* $1 - The separator character.",
"invalid-content-data": "Error message indicating that the page's content can not be saved because it is invalid. This may occurr for content types with internal consistency constraints.",
"content-not-allowed-here": "Error message indicating that the desired content model is not supported in given localtion.\n* $1 - the human readable name of the content model: {{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}\n* $2 - the title of the page in question",
"editwarning-warning": "Uses {{msg-mw|Prefs-editing}}",
+ "editpage-invalidcontentmodel-title": "Title of error page shown when using an unrecognized content model on EditPage",
+ "editpage-invalidcontentmodel-text": "Error message shown when using an unrecognized content model on EditPage. $1 is the user's invalid input",
"editpage-notsupportedcontentformat-title": "Title of error page shown when using an incompatible format on EditPage.\n\nUsed as title for the following error message:\n* {{msg-mw|Editpage-notsupportedcontentformat-text}}.",
"editpage-notsupportedcontentformat-text": "Error message shown when using an incompatible format on EditPage.\n\nThe title for this error is {{msg-mw|Editpage-notsupportedcontentformat-title}}.\n\nParameters:\n* $1 - the format id\n* $2 - the content model name",
"content-model-wikitext": "Name for the wikitext content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
"tag-filter": "Caption of a filter shown on lists of changes (e.g. [[Special:Log]], [[Special:Contributions]], [[Special:Newpages]], [[Special:Recentchanges]], [[Special:Recentchangeslinked]], page histories)",
"tag-filter-submit": "Caption of the submit button displayed next to the tag filter on lists of changes (e.g. [[Special:Log]], [[Special:Contributions]], [[Special:Newpages]], [[Special:Recentchanges]], [[Special:Recentchangeslinked]], page histories)\n\n{{Identical|Filter}}",
"tag-list-wrapper": "Wrapper for the list of tags shown on recent changes, watchlists, history pages and diffs.\n\nParameters:\n* $1 - number of distinct tags for given edit\n* $2 - comma-separated list of tags for given edit",
+ "tag-mw-contentmodelchange": "Change tag for edits that change the content model of a page",
+ "tag-mw-contentmodelchange-description": "Description for \"content model change\" change tag",
"tags-title": "The title of [[Special:Tags]].\n{{Identical|Tag}}",
"tags-intro": "Explanation on top of [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
"tags-tag": "Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
"tags-actions-header": "Caption of a column in [[Special:Tags]]. The column contains action links like \"delete\". For more information on tags see [[mw:Manual:Tags|MediaWiki]].\n{{Identical|Action}}",
"tags-active-yes": "Table cell contents if given tag is \"active\".\n\nSee also:\n* {{msg-mw|Tags-active-no}}\n{{Identical|Yes}}",
"tags-active-no": "Table cell contents if given tag is not \"active\".\n\nSee also:\n* {{msg-mw|Tags-active-yes}}\n{{Identical|No}}",
- "tags-source-extension": "Table cell contents if given tag can be applied automatically by a software [[mw:Manual:Extensions|extension]].\n\nSee also:\n* {{msg-mw|Tags-source-manual}}\n* {{msg-mw|Tags-source-none}}",
+ "tags-source-extension": "Table cell contents if given tag can be applied automatically by the MediaWiki software.\n\nSee also:\n* {{msg-mw|Tags-source-manual}}\n* {{msg-mw|Tags-source-none}}",
"tags-source-manual": "\"Applied\" is not past tense, but an adjective that describes an action that sometimes happens, as in the sentence: \"(this tag is usually) applied by users and bots\".\n\nTable cell contents if given tag can be applied by users or bots.\n\nSee also:\n* {{msg-mw|Tags-source-extension}}\n* {{msg-mw|Tags-source-none}}",
"tags-source-none": "Table cell contents if given tag is no longer in use. (It was applied in the past, but it is currently not applied.)\n\nSee also:\n* {{msg-mw|Tags-source-extension}}\n* {{msg-mw|Tags-source-manual}}",
"tags-edit": "Used on [[Special:Tags]]. Verb. Used as display text on a link to create/edit a description.\n{{Identical|Edit}}",
"botpasswords-updated-body": "Пароль бота для бота «$1» участника «$2» был обновлён.",
"botpasswords-deleted-title": "Пароль бота удалён",
"botpasswords-deleted-body": "Пароль бота для бота «$1» участника «$2» был удалён.",
- "botpasswords-newpassword": "Новый пароль для входа под <strong>$1</strong> — <strong>$2</strong>. <em>Запишите его для последующего использования.</em>",
+ "botpasswords-newpassword": "Новый пароль для входа под <strong>$1</strong> — <strong>$2</strong>. <em>Запишите его для последующего использования.</em> <br /> (Для старых ботов, которые требуют, чтоб логин участника был таким же, как имя потенциального участника, вы можете также использовать <strong>$3</strong> как имя участника и <strong>$4</strong> в качестве пароля.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider недоступен.",
"botpasswords-restriction-failed": "Из-за ограничений, связанных с паролем бота, вход не произведён.",
"botpasswords-invalid-name": "Указанное имя участника не содержит разделителя для пароля бота («$1»).",
"invalid-content-data": "Недопустимые данные",
"content-not-allowed-here": "Содержимое \"$1\" недопустимо на странице [[$2]]",
"editwarning-warning": "Переход на другую страницу может привести к потере внесённых вами изменений.\nЕсли вы зарегистрированы в системе, то вы можете отключить это предупреждение в разделе «{{int:prefs-editing}}» ваших настроек.",
+ "editpage-invalidcontentmodel-title": "Модель содержимого не поддерживается",
+ "editpage-invalidcontentmodel-text": "Модель содержимого «$1» не поддерживается.",
"editpage-notsupportedcontentformat-title": "Формат содержимого не поддерживается",
"editpage-notsupportedcontentformat-text": "Формат содержимого $1 не поддерживается моделью содержимого $2.",
"content-model-wikitext": "вики-текст",
"createacct-yourpasswordagain-ph": "Ange lösenordet igen",
"userlogin-remembermypassword": "Håll mig inloggad",
"userlogin-signwithsecure": "Använd säker anslutning",
+ "cannotlogin-title": "Kan inte logga in",
+ "cannotlogin-text": "Det går inte att logga in.",
"cannotloginnow-title": "Kan inte logga in nu",
"cannotloginnow-text": "Det går inte att logga in med $1.",
+ "cannotcreateaccount-title": "Kan inte skapa konton",
+ "cannotcreateaccount-text": "Direkt kontoregistrering är inte aktiverat på denna wiki.",
"yourdomainname": "Din domän",
"password-change-forbidden": "Du kan inte ändra lösenord på denna wiki.",
"externaldberror": "Antingen inträffade autentiseringsproblem med en extern databas, eller så får du inte uppdatera ditt externa konto.",
"randomincategory-category": "زمرہ:",
"randomincategory-submit": "جانا",
"statistics": "اعداد و شمار",
- "statistics-header-pages": "اØصائÛ\92 صÙ\81Øات",
- "statistics-header-edits": "اØصائÛ\92 تدÙ\88Û\8cÙ\86",
+ "statistics-header-pages": "صÙ\81Øات Ú©Û\92 اعداد Ù\88 Ø´Ù\85ار",
+ "statistics-header-edits": "ترÙ\85Û\8cÙ\85Û\8c اعداد Ù\88 Ø´Ù\85ار",
"statistics-header-users": "ارکان کے اعداد و شمار",
- "statistics-header-hooks": "اØصائÛ\92 دÛ\8cÚ¯ر",
+ "statistics-header-hooks": "دÛ\8cگر اعداد Ù\88 Ø´Ù\85ار",
"statistics-articles": "مندرج صفحات",
"statistics-pages": "صفحات",
"statistics-pages-desc": "(ویکی اقتباسات کے کل صفحات، بشمولِ تبادلۂ خیال، رجوع مکررات وغیرہ۔)",
- "statistics-files": "زبراثÙ\82اÙ\84 شدÛ\81 Ù\85Ù\84Ù\81ات",
- "statistics-edits": "ویکی اقتباسات کے آغاز سے کل صفحاتی ترمیم",
+ "statistics-files": "اپÙ\84Ù\88Ú\88 کردÛ\81 Ù\81ائÙ\84Û\8cÚº",
+ "statistics-edits": "{{SITENAME}} کے آغاز سے کل صفحاتی ترامیم",
"statistics-edits-average": "فی صفحہ اوسط ترامیم",
"statistics-users": "مندرج [[خاص:فہرست صارفین، صارف فہرست|صارفین]]",
"statistics-users-active": "متحرک صارفین",
"createacct-another-username-ph": "请输入用户名",
"yourpassword": "密码:",
"userlogin-yourpassword": "密码",
- "userlogin-yourpassword-ph": "请输入你的密码",
+ "userlogin-yourpassword-ph": "请输入您的密码",
"createacct-yourpassword-ph": "请输入密码",
"yourpasswordagain": "请再次输入密码:",
"createacct-yourpasswordagain": "确认密码",
"tooltip-ca-nstab-help": "查看帮助页面",
"tooltip-ca-nstab-category": "查看分类页面",
"tooltip-minoredit": "标记本编辑为小编辑",
- "tooltip-save": "保存你的更改",
+ "tooltip-save": "保存您的更改",
"tooltip-publish": "发布您的更改",
"tooltip-preview": "预览您的更改。请在保存前使用此功能。",
"tooltip-diff": "显示您对该文字所做的更改",
"Reke",
"Kly",
"Cosine02",
- "一個正常人"
+ "一個正常人",
+ "Wehwei"
]
},
"tog-underline": "底線標示連結:",
"createacct-yourpasswordagain-ph": "再次輸入密碼",
"userlogin-remembermypassword": "記住我的登入狀態",
"userlogin-signwithsecure": "使用安全連線",
+ "cannotlogin-title": "無法登入",
+ "cannotlogin-text": "無法登入",
"cannotloginnow-title": "現在無法登入",
"cannotloginnow-text": "使用 $1 時無法登入。",
+ "cannotcreateaccount-title": "無法建立帳號",
"yourdomainname": "您的網域:",
"password-change-forbidden": "您不可變更此 Wiki 上的密碼。",
"externaldberror": "這可能是由於資料庫驗證錯誤,或是不允許您更新外部帳號。",
"pageinfo-article-id": "頁面 ID",
"pageinfo-language": "頁面內容語言",
"pageinfo-content-model": "頁面內容模型",
+ "pageinfo-content-model-change": "變更",
"pageinfo-robot-policy": "由機器人建立索引",
"pageinfo-robot-index": "允許",
"pageinfo-robot-noindex": "不允許",
"tags-actions-header": "操作",
"tags-active-yes": "是",
"tags-active-no": "否",
- "tags-source-extension": "由擴充套件定義",
+ "tags-source-extension": "由軟體定義",
"tags-source-manual": "由使用者與機器人手動套用",
"tags-source-none": "不再使用",
"tags-edit": "編輯",
$rtl = true;
$namespaceNames = [
- NS_MEDIA => 'Ù\88سÛ\8cØ·',
+ NS_MEDIA => 'Ù\85Û\8cÚ\88Û\8cا',
NS_SPECIAL => 'خاص',
NS_TALK => 'تبادلۂ_خیال',
NS_USER => 'صارف',
NS_USER_TALK => 'تبادلۂ_خیال_صارف',
NS_PROJECT_TALK => 'تبادلۂ_خیال_$1',
- NS_FILE => 'Ù\85Ù\84Ù\81',
- NS_FILE_TALK => 'تبادÙ\84Û\82_Ø®Û\8cاÙ\84_Ù\85Ù\84Ù\81',
+ NS_FILE => 'Ù\81ائÙ\84',
+ NS_FILE_TALK => 'تبادÙ\84Û\82_Ø®Û\8cاÙ\84_Ù\81ائÙ\84',
NS_MEDIAWIKI => 'میڈیاویکی',
NS_MEDIAWIKI_TALK => 'تبادلۂ_خیال_میڈیاویکی',
NS_TEMPLATE => 'سانچہ',
];
$namespaceAliases = [
+ 'وسیط' => NS_MEDIA,
'زریعہ' => NS_MEDIA,
'تصویر' => NS_FILE,
'تبادلۂ_خیال_تصویر' => NS_FILE_TALK,
+ 'ملف' => NS_FILE,
+ 'تبادلۂ_خیال_ملف' => NS_FILE_TALK,
'میڈیاوکی' => NS_MEDIAWIKI,
'تبادلۂ_خیال_میڈیاوکی' => NS_MEDIAWIKI_TALK,
];
'Ancientpages' => [ 'قدیم_صفحات' ],
'Badtitle' => [ 'خراب_عنوان' ],
'Blankpage' => [ 'خالی_صفحہ' ],
- 'Block' => [ 'پابندی', 'آئی_پی_پتہ_پابندی،_پابندی_بر_صارف' ],
+ 'Block' => [ 'پابندی', 'آئی_پی_پتہ_پابندی', 'پابندی_بر_صارف' ],
'Booksources' => [ 'کتابی_وسائل' ],
'BrokenRedirects' => [ 'شکستہ_رجوع_مکررات' ],
'Categories' => [ 'زمرہ_جات' ],
'DoubleRedirects' => [ 'دوہرے_رجوع_مکررات' ],
'EditWatchlist' => [ 'ترمیم_زیر_نظر' ],
'Emailuser' => [ 'صارف_ڈاک' ],
- 'Export' => [ 'برآمدگی' ],
+ 'Export' => [ 'برآمد', 'برآمدگی' ],
'Fewestrevisions' => [ 'کم_نظر_ثانی_شدہ' ],
- 'FileDuplicateSearch' => [ 'دہری_ملف_تلاش' ],
- 'Filepath' => [ 'راہ_ملف' ],
- 'Import' => [ 'درآمدگی' ],
+ 'FileDuplicateSearch' => [ 'تÙ\84اش_دÙ\88Û\81رÛ\8c_Ù\81ائÙ\84', 'دÛ\81رÛ\8c_Ù\85Ù\84Ù\81_تÙ\84اش' ],
+ 'Filepath' => [ 'راÛ\81_Ù\81ائÙ\84', 'راÛ\81_Ù\85Ù\84Ù\81' ],
+ 'Import' => [ 'درآمد', 'درآمدگی' ],
'Invalidateemail' => [ 'ڈاک_تصدیق_منسوخ' ],
'JavaScriptTest' => [ 'تجربہ_جاوا_اسکرپٹ' ],
'BlockList' => [ 'فہرست_ممنوع', 'فہرست_دستور_شبکی_ممنوع' ],
'LinkSearch' => [ 'تلاش_روابط' ],
'Listadmins' => [ 'فہرست_منتظمین' ],
'Listbots' => [ 'فہرست_روبہ_جات' ],
- 'Listfiles' => [ 'فہرست_املاف', 'فہرست_تصاویر' ],
+ 'Listfiles' => [ 'فائلوں_کی_فہرست', 'فہرست_تصاویر' ],
'Listgrouprights' => [ 'فہرست_اختیارات_گروہ', 'صارفی_گروہ_اختیارات' ],
'Listredirects' => [ 'فہرست_رجوع_مکررات' ],
- 'Listusers' => [ 'فہرست_صارفین،_صارف_فہرست' ],
+ 'Listusers' => [ 'فہرست_صارفین' ],
'Log' => [ 'نوشتہ', 'نوشتہ_جات' ],
'Lonelypages' => [ 'یتیم_صفحات' ],
'Longpages' => [ 'طویل_صفحات' ],
'MergeHistory' => [ 'ضم_تاریخچہ' ],
'Movepage' => [ 'منتقلی_صفحہ' ],
- 'Mycontributions' => [ 'میرا_حصہ' ],
+ 'Mycontributions' => [ 'میری_شراکتیں', 'میرا_حصہ' ],
'Mypage' => [ 'میرا_صفحہ' ],
'Mytalk' => [ 'میری_گفتگو' ],
- 'Myuploads' => [ 'میرے_زبراثقالات' ],
- 'Newimages' => [ 'جدید_املاف', 'جدید_تصاویر' ],
+ 'Myuploads' => [ 'Ù\85Û\8cرÛ\92_اپÙ\84Ù\88Ú\88', 'Ù\85Û\8cرÛ\92_زبراثÙ\82اÙ\84ات' ],
+ 'Newimages' => [ 'جدید_فائلیں', 'جدید_املاف', 'جدید_تصاویر' ],
'Newpages' => [ 'جدید_صفحات' ],
'PermanentLink' => [ 'مستقل_ربط' ],
'Preferences' => [ 'ترجیحات' ],
'Randomredirect' => [ 'تصادفی_رجوع_مکرر' ],
'Recentchanges' => [ 'حالیہ_تبدیلیاں' ],
'Recentchangeslinked' => [ 'متعلقہ_تبدیلیاں' ],
- 'Revisiondelete' => [ 'حذف_اعادہ' ],
+ 'Revisiondelete' => [ 'حذف_نظر_ثانی', 'حذف_اعادہ' ],
'Search' => [ 'تلاش' ],
'Shortpages' => [ 'مختصر_صفحات' ],
'Specialpages' => [ 'خصوصی_صفحات' ],
'Statistics' => [ 'شماریات' ],
- 'Tags' => [ 'ٹیگز' ],
+ 'Tags' => [ 'ٹیگ', 'ٹیگز' ],
'Unblock' => [ 'پابندی_ختم' ],
'Uncategorizedcategories' => [ 'غیر_زمرہ_بند_زمرہ_جات' ],
- 'Uncategorizedimages' => [ 'غیر_زمرہ_بند_املاف', 'غیر_زمرہ_بند_تصاویر' ],
+ 'Uncategorizedimages' => [ 'غیر_زمرہ_بند_فائلیں', 'غیر_زمرہ_بند_املاف', 'غیر_زمرہ_بند_تصاویر' ],
'Uncategorizedpages' => [ 'غیر_زمرہ_بند_صفحات' ],
'Uncategorizedtemplates' => [ 'غیر_زمرہ_بند_سانچے' ],
'Undelete' => [ 'بحال' ],
'Unusedcategories' => [ 'غیر_مستعمل_زمرہ_جات' ],
- 'Unusedimages' => [ 'غیر_مستعمل_املاف', 'غیر_مستعمل_تصاویر' ],
+ 'Unusedimages' => [ 'غیر_مستعمل_فائلیں', 'غیر_مستعمل_املاف', 'غیر_مستعمل_تصاویر' ],
'Unusedtemplates' => [ 'غیر_مستعمل_سانچے' ],
'Unwatchedpages' => [ 'نادیدہ_صفحات' ],
- 'Upload' => [ 'زبراثقال' ],
+ 'Upload' => [ 'اپÙ\84Ù\88Ú\88', 'زبراثÙ\82اÙ\84' ],
'Userlogin' => [ 'داخل_نوشتگی' ],
'Userlogout' => [ 'خارج_نوشتگی' ],
'Userrights' => [ 'صارفی_اختیارات' ],
- 'Version' => [ 'اخراجہ' ],
+ 'Version' => [ 'نسخہ', 'اخراجہ' ],
'Wantedcategories' => [ 'مطلوبہ_زمرہ_جات' ],
- 'Wantedfiles' => [ 'مطلوبہ_املاف' ],
+ 'Wantedfiles' => [ 'مطلوبہ_فائلیں', 'مطلوبہ_املاف' ],
'Wantedpages' => [ 'مطلوبہ_صفحات', 'شکستہ_روابط' ],
'Wantedtemplates' => [ 'مطلوبہ_سانچے' ],
'Watchlist' => [ 'زیر_نظر_فہرست' ],
- 'Whatlinkshere' => [ 'یہاں_کس_کا_رابطہ' ],
+ 'Whatlinkshere' => [ 'مربوط_صفحات', 'یہاں_کس_کا_رابطہ' ],
'Withoutinterwiki' => [ 'بدون_بین_الویکی' ],
];
return fgets( STDIN, 1024 );
}
+
+ /**
+ * Call this to set up the autoloader to allow classes to be used from the
+ * tests directory.
+ */
+ public static function requireTestsAutoloader() {
+ require_once __DIR__ . '/../tests/common/TestsAutoLoader.php';
+ }
}
/**
@echo "Run 'make man' to run the doxygen generation with man pages."
test:
- php tests/parserTests.php --quiet
+ php tests/parser/parserTests.php --quiet
doc:
php mwdocgen.php --all
// NOTE (phuedx, 2014-03-26) wgAutoloadClasses isn't set up
// by either of the dependencies at the top of the file, so
// require it here.
- require_once __DIR__ . '/../tests/TestsAutoLoader.php';
+ self::requireTestsAutoloader();
// If phpunit isn't available by autoloader try pulling it in
if ( !class_exists( 'PHPUnit_Framework_TestCase' ) ) {
// Commit and close up!
$factory = wfGetLBFactory();
$factory->commitMasterChanges( 'doMaintenance' );
-$factory->shutdown();
+$factory->shutdown( $factory::SHUTDOWN_NO_CHRONPROT );
],
'scripts' => 'resources/lib/jquery/jquery.appear.js',
],
- 'jquery.arrowSteps' => [
- 'scripts' => 'resources/src/jquery/jquery.arrowSteps.js',
- 'styles' => 'resources/src/jquery/jquery.arrowSteps.css',
- 'targets' => [ 'desktop', 'mobile' ],
- ],
'jquery.async' => [
'scripts' => 'resources/lib/jquery/jquery.async.js',
],
],
'dependencies' => [
'oojs-ui-core',
+ 'oojs-ui-widgets',
'oojs-ui-windows',
'oojs-ui.styles.icons-content',
'oojs-ui.styles.icons-editing-advanced',
// author : Werner Mollentze : https://github.com/wernerm
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('af', {
months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),
// author : Abdel Said : https://github.com/abdelsaid
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('ar-ma', {
months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
// author : Suhail Alkowaileet : https://github.com/xsoh
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '١',
// Native plural forms: forabi https://github.com/forabi
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '١',
// author : topchiyev : https://github.com/topchiyev
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var suffixes = {
1: '-inci',
// Author : Menelion Elensúle : https://github.com/Oire
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function plural(word, num) {
var forms = word.split('_');
// author : Krasen Borisov : https://github.com/kraz
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('bg', {
months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
// author : Kaushik Gandhi : https://github.com/kaushikgandhi
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '১',
// author : Thupten N. Chakrishar : https://github.com/vajradog
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '༡',
// author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function relativeTimeWithMutation(number, withoutSuffix, key) {
var format = {
// based on (hr) translation by Bojan Marković
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function translate(number, withoutSuffix, key) {
var result = number + ' ';
// author : Juan G. Hurtado : https://github.com/juanghurtado
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('ca', {
months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
// author : petrbela : https://github.com/petrbela
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),
monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');
// author : Anatoly Mironov : https://github.com/mirontoli
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('cv', {
months : 'кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав'.split('_'),
// author : Robert Allen
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('cy', {
months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),
// author : Ulrik Nielsen : https://github.com/mrbase
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('da', {
months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),
// author : Martin Groller : https://github.com/MadMG
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function processRelativeTime(number, withoutSuffix, key, isFuture) {
var format = {
// author: Menelion Elensúle: https://github.com/Oire
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function processRelativeTime(number, withoutSuffix, key, isFuture) {
var format = {
// author : Aggelos Karalias : https://github.com/mehiel
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('el', {
monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),
// locale : australian english (en-au)
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('en-au', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
// author : Jonathan Abourbih : https://github.com/jonbca
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('en-ca', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
// author : Chris Gedrim : https://github.com/chrisgedrim
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('en-gb', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
// Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('eo', {
months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),
// author : Julio Napurí : https://github.com/julionc
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),
monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
// improvements : Illimar Tambek : https://github.com/ragulka
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function processRelativeTime(number, withoutSuffix, key, isFuture) {
var format = {
// author : Eneko Illarramendi : https://github.com/eillarra
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('eu', {
months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),
// author : Ebrahim Byagowi : https://github.com/ebraminio
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '۱',
// author : Tarmo Aidantausta : https://github.com/bleadof
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),
numbersFuture = [
// author : Ragnar Johannesen : https://github.com/ragnar123
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('fo', {
months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
// author : Jonathan Abourbih : https://github.com/jonbca
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('fr-ca', {
months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
// author : John Fischer : https://github.com/jfroffice
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('fr', {
months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
// author : Juan G. Hurtado : https://github.com/juanghurtado
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('gl', {
months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'),
// author : Tal Ater : https://github.com/TalAter
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('he', {
months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),
// author : Mayank Singhal : https://github.com/mayanksinghal
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '१',
// based on (sl) translation by Robert Sedovšek
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function translate(number, withoutSuffix, key) {
var result = number + ' ';
// author : Adam Brunner : https://github.com/adambrunner
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
// author : Armendarabyan : https://github.com/armendarabyan
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function monthsCaseReplace(m, format) {
var months = {
// reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('id', {
months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),
// author : Hinrik Örn Sigurðsson : https://github.com/hinrik
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function plural(n) {
if (n % 100 === 11) {
// author: Mattia Larentis: https://github.com/nostalgiaz
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('it', {
months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),
// author : LI Long : https://github.com/baryon
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('ja', {
months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
// author : Irakli Janiashvili : https://github.com/irakli-janiashvili
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function monthsCaseReplace(m, format) {
var months = {
// author : Kruy Vanna : https://github.com/kruyvanna
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('km', {
months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
// - Kyungwook, Park : https://github.com/kyungw00k
// - Jeeeyul Lee <jeeeyul@gmail.com>
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('ko', {
months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
// and 'eifelerRegelAppliesToNumber' methods are meant for
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function processRelativeTime(number, withoutSuffix, key, isFuture) {
var format = {
// author : Mindaugas Mozūras : https://github.com/mmozuras
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var units = {
'm' : 'minutė_minutės_minutę',
// author : Kristaps Karlsons : https://github.com/skakri
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var units = {
'mm': 'minūti_minūtes_minūte_minūtes',
// author : Borislav Mickov : https://github.com/B0k0
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('mk', {
months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),
// author : Floyd Pink : https://github.com/floydpink
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('ml', {
months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),
// author : Harshad Kale : https://github.com/kalehv
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '१',
// author : Weldan Jamili : https://github.com/weldan
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('ms-my', {
months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
// author : Squar team, mysquar.com
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '၁',
// Sigurd Gartmann : https://github.com/sigurdga
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('nb', {
months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
// author : suvash : https://github.com/suvash
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var symbolMap = {
'1': '१',
// author : Joris Röling : https://github.com/jjupiter
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),
monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
// author : https://github.com/mechuwind
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('nn', {
months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
// author : Rafal Hirsz : https://github.com/evoL
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),
monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');
// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('pt-br', {
months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),
// author : Jefferson : https://github.com/jalex79
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('pt', {
months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),
// author : Valentin Agachi : https://github.com/avaly
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function relativeTimeWithPlural(number, withoutSuffix, key) {
var format = {
// Author : Menelion Elensúle : https://github.com/Oire
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function plural(word, num) {
var forms = word.split('_');
// based on work of petrbela : https://github.com/petrbela
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),
monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');
// author : Robert Sedovšek : https://github.com/sedovsek
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function translate(number, withoutSuffix, key) {
var result = number + ' ';
// author : Oerd Cukalla : https://github.com/oerd (fixes)
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('sq', {
months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),
// author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var translator = {
words: { //Different grammatical cases
// author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var translator = {
words: { //Different grammatical cases
// author : Jens Alm : https://github.com/ulmus
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('sv', {
months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),
// author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
/*var symbolMap = {
'1': '௧',
// author : Kridsada Thanabulpong : https://github.com/sirn
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('th', {
months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),
// author : Dan Hagman
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('tl-ph', {
months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),
// Burak Yiğit Kaya: https://github.com/BYK
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
var suffixes = {
1: '\'inci',
// author : Abdel Said : https://github.com/abdelsaid
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('tzm-latn', {
months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
// author : Abdel Said : https://github.com/abdelsaid
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('tzm', {
months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
// Author : Menelion Elensúle : https://github.com/Oire
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
function plural(word, num) {
var forms = word.split('_');
// author : Sardor Muminov : https://github.com/muminoff
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('uz', {
months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
// author : Bang Nguyen : https://github.com/bangnk
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('vi', {
months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),
// author : Zeno Zeng : https://github.com/zenozeng
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('zh-cn', {
months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
// author : Ben : https://github.com/ben-lin
(function (factory) {
- if (typeof define === 'function' && define.amd) {
+ // Comment out broken wrapper, see T145382
+ /*if (typeof define === 'function' && define.amd) {
define(['moment'], factory); // AMD
} else if (typeof exports === 'object') {
module.exports = factory(require('../moment')); // Node
} else {
factory((typeof global !== 'undefined' ? global : this).moment); // node or other global
- }
+ }*/
+ factory(this.moment);
}(function (moment) {
return moment.defineLocale('zh-tw', {
months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "SatyamMishra"
+ ]
+ },
+ "ooui-outline-control-move-down": "आइटम नीचे घसकाईं",
+ "ooui-outline-control-move-up": "आइटम ऊपर घसकाईं",
+ "ooui-outline-control-remove": "आइटम हटाईं",
+ "ooui-toolbar-more": "अउरी",
+ "ooui-toolgroup-expand": "अउरी",
+ "ooui-toolgroup-collapse": "कम",
+ "ooui-dialog-message-accept": "ओके",
+ "ooui-dialog-message-reject": "कैंसिल",
+ "ooui-dialog-process-error": "कुछ गड़बड़ी हो गइल",
+ "ooui-dialog-process-dismiss": "रद्द",
+ "ooui-dialog-process-retry": "दोबारा कोसिस करीं",
+ "ooui-dialog-process-continue": "जारी राखीं",
+ "ooui-selectfile-button-select": "एगो फाइल चुनीं",
+ "ooui-selectfile-not-supported": "फाइल के चुनाव के सपोर्ट नइखे",
+ "ooui-selectfile-placeholder": "कौनों फाइल नइखे चुनल गइल",
+ "ooui-selectfile-dragdrop-placeholder": "फाइल इहाँ ड्रॉप करीं"
+}
"ooui-toolgroup-expand": "Liyané",
"ooui-toolgroup-collapse": "Sacukupé",
"ooui-dialog-message-accept": "Ha'a",
- "ooui-dialog-message-reject": "Wurungaké",
+ "ooui-dialog-message-reject": "Wurung",
"ooui-dialog-process-error": "Ana sing klèru",
"ooui-dialog-process-dismiss": "Tutup",
"ooui-dialog-process-retry": "Jajal manèh",
"Vikassy",
"Nayvik",
"Omshivaprakash",
- "Pavanaja"
+ "Pavanaja",
+ "Yogesh"
]
},
"ooui-outline-control-move-down": "ವಸ್ತುವನ್ನು ಕೆಳಗೆ ಸರಿಸು",
"ooui-dialog-process-error": "ಏನೋ ಎಡವಟ್ಟಾಗಿದೆ....",
"ooui-dialog-process-dismiss": "ತೆಗೆದುಹಾಕು",
"ooui-dialog-process-retry": "ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ",
- "ooui-dialog-process-continue": "ಮುಂದುವರೆಸು"
+ "ooui-dialog-process-continue": "ಮುಂದುವರೆಸು",
+ "ooui-selectfile-button-select": "ಕಡತವನ್ನು ಆಯ್ಕೆಮಾಡಿ",
+ "ooui-selectfile-placeholder": "ಕಡತವು ಆಯ್ಕೆಯಾಗಿಲ್ಲ",
+ "ooui-selectfile-dragdrop-placeholder": "ಇಲ್ಲಿ ಕಡತವನ್ನು ಬಿಡಿ"
}
"ooui-toolgroup-collapse": "Mens",
"ooui-dialog-message-accept": "D'acòrdi",
"ooui-dialog-message-reject": "Anullar",
+ "ooui-dialog-process-error": "Quicòm a trucat",
"ooui-dialog-process-dismiss": "Regetar",
"ooui-dialog-process-retry": "Ensajatz tornamai",
"ooui-dialog-process-continue": "Contunhar",
- "ooui-selectfile-placeholder": "Cap de fichièr pas seleccionat"
+ "ooui-selectfile-button-select": "Seleccionar un fichièr",
+ "ooui-selectfile-not-supported": "Lo tipe de fichièr es pas compatible",
+ "ooui-selectfile-placeholder": "Cap de fichièr pas seleccionat",
+ "ooui-selectfile-dragdrop-placeholder": "Depausar lo fichièr aicí"
}
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "Saimawnkham"
+ ]
+ },
+ "ooui-outline-control-move-down": "ၶၢႆႉလူင်းၽၢႆႇတႂ်ႈ",
+ "ooui-outline-control-move-up": "ၶၢႆႉၶိုၼ်ႈၽၢႆႇၼိူဝ်",
+ "ooui-outline-control-remove": "ထွၼ်ပႅတ်ႈ ဢၼ်ၶဝ်ႈပႃး",
+ "ooui-toolbar-more": "ၼမ်ႉလိူဝ်",
+ "ooui-toolgroup-expand": "ၼမ်လိူဝ်",
+ "ooui-toolgroup-collapse": "ဢေႇလိူဝ်",
+ "ooui-dialog-message-accept": "ဢူဝ်ႇၶေႇ",
+ "ooui-dialog-message-reject": "ဢမ်ႇႁဵတ်း",
+ "ooui-dialog-process-error": "သေဢၼ်ဢၼ်ၽိတ်းပိူင်ႈဝႆႉ",
+ "ooui-dialog-process-dismiss": "လူတ်းၵၢၼ်",
+ "ooui-dialog-process-retry": "ၶတ်းၸႂ်ထႅင်ႈ",
+ "ooui-dialog-process-continue": "သိုပ်ႇၼႃႈ",
+ "ooui-selectfile-button-select": "လိူၵ်ႈၾၢႆႇ",
+ "ooui-selectfile-not-supported": "လွင်ႈလိူၵ်ႈၽၢႆႇၼႆႉ ဢမ်ႇၵမ်ႉထႅမ်ဝႆႉပၼ်",
+ "ooui-selectfile-placeholder": "ဢမ်ႇလႆႈလိူၵ်ႈ ၾၢႆႇသင်ဝႆႉ",
+ "ooui-selectfile-dragdrop-placeholder": "ဢဝ်ၾၢႆႇ သႂ်ႇတီႈၼႆႉ"
+}
"Shanmugamp7",
"Veeven",
"Visdaviva",
- "மதனாஹரன்"
+ "மதனாஹரன்",
+ "రహ్మానుద్దీన్"
]
},
+ "ooui-outline-control-move-down": "అంశాన్ని కిందికి కదుపు",
+ "ooui-outline-control-move-up": "అంశాన్ని పైకి కదుపు",
+ "ooui-outline-control-remove": "అంశాన్ని తీసివేయి",
"ooui-toolbar-more": "మరిన్ని",
"ooui-toolgroup-expand": "మరిన్ని",
"ooui-toolgroup-collapse": "కొన్ని",
"ooui-dialog-process-error": "ఏదో పొరపాటు జరిగింది",
"ooui-dialog-process-dismiss": "రద్దుచేయి",
"ooui-dialog-process-retry": "మళ్ళీ ప్రయత్నించు",
- "ooui-dialog-process-continue": "కొనసాగించు"
+ "ooui-dialog-process-continue": "కొనసాగించు",
+ "ooui-selectfile-button-select": "దస్త్రాన్ని ఎంచుకో",
+ "ooui-selectfile-not-supported": "దస్త్రపు ఎంపిక అందుబాటులో లేదు",
+ "ooui-selectfile-placeholder": "ఏ దస్త్రము ఎంపిక చేయలేదు",
+ "ooui-selectfile-dragdrop-placeholder": "దస్త్రాన్ని ఇక్కడ పడేయండి"
}
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "Muhammad Shuaib"
+ ]
+ },
+ "ooui-outline-control-move-down": "آئیٹم نیچے کھسکائیں",
+ "ooui-outline-control-move-up": "آئیٹم اوپر بڑھائیں",
+ "ooui-outline-control-remove": "آئیٹم حذف کریں",
+ "ooui-toolbar-more": "مزید",
+ "ooui-toolgroup-expand": "مزید",
+ "ooui-toolgroup-collapse": "کم کریں",
+ "ooui-dialog-message-accept": "ٹھیک",
+ "ooui-dialog-message-reject": "منسوخ کریں",
+ "ooui-dialog-process-error": "کچھ غلط ہو گیا ہے",
+ "ooui-dialog-process-dismiss": "ختم کریں",
+ "ooui-dialog-process-retry": "دوبارہ کوشش کریں",
+ "ooui-dialog-process-continue": "جاری رکھیں",
+ "ooui-selectfile-button-select": "فائل منتخب کریں",
+ "ooui-selectfile-not-supported": "فائل کا انتخاب معاونت شدہ نہیں",
+ "ooui-selectfile-placeholder": "کوئی فائل منتخب نہیں",
+ "ooui-selectfile-dragdrop-placeholder": "فائل یہاں چھوڑیں"
+}
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:48Z
+ * Date: 2016-09-13T18:30:02Z
*/
( function ( OO ) {
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
.oo-ui-element-hidden {
display: none !important;
/* stylelint-disable-line declaration-no-important */
}
+.oo-ui-buttonElement {
+ display: inline-block;
+ vertical-align: middle;
+}
.oo-ui-buttonElement > .oo-ui-buttonElement-button {
cursor: pointer;
display: inline-block;
text-align: center;
}
.oo-ui-buttonElement > .oo-ui-buttonElement-button {
- color: #333333;
+ color: #333;
}
.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
margin-left: 0;
}
.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
- color: #000000;
+ color: #000;
}
.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #333333;
+ color: #333;
}
.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
margin-left: 0.25em;
}
.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
padding-left: 0.25em;
- color: #333333;
+ color: #333;
}
.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:hover,
.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:focus {
- color: #000000;
+ color: #000;
}
.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
color: #087ecc;
opacity: 0.2;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
padding: 0.2em 0.8em;
-webkit-transition: border-color 100ms ease;
-moz-transition: border-color 100ms ease;
transition: border-color 100ms ease;
- background-color: #eeeeee;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #dddddd));
- background-image: -webkit-linear-gradient(top, #ffffff 0, #dddddd 100%);
- background-image: -moz-linear-gradient(top, #ffffff 0, #dddddd 100%);
- background-image: linear-gradient(to bottom, #ffffff 0, #dddddd 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+ background-color: #eee;
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
+ background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
+ background-image: -moz-linear-gradient(top, #fff 0, #ddd 100%);
+ background-image: linear-gradient(to bottom, #fff 0, #ddd 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#ffdddddd\' )';
}
.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
- border-color: #aaaaaa;
+ border-color: #aaa;
outline: none;
}
.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
- color: #000000;
+ color: #000;
border-color: #c9c9c9;
- background-color: #eeeeee;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #dddddd), color-stop(100%, #ffffff));
- background-image: -webkit-linear-gradient(top, #dddddd 0, #ffffff 100%);
- background-image: -moz-linear-gradient(top, #dddddd 0, #ffffff 100%);
- background-image: linear-gradient(to bottom, #dddddd 0, #ffffff 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
+ background-color: #eee;
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
+ background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
+ background-image: -moz-linear-gradient(top, #ddd 0, #fff 100%);
+ background-image: linear-gradient(to bottom, #ddd 0, #fff 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffdddddd\', endColorstr=\'#ffffffff\' )';
}
.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
margin-left: -0.5em;
background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
background-image: -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
background-image: linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffeaf4fa\', endColorstr=\'#ffb0d9ee\' )';
}
.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
background-image: -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
background-image: linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffb0d9ee\', endColorstr=\'#ffeaf4fa\' )';
}
.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
border: 1px solid #b8d892;
background-image: -webkit-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
background-image: -moz-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
background-image: linear-gradient(to bottom, #f0fbe1 0, #c3e59a 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff0fbe1', endColorstr='#ffc3e59a' )";
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff0fbe1\', endColorstr=\'#ffc3e59a\' )';
}
.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
background-image: -webkit-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
background-image: -moz-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
background-image: linear-gradient(to bottom, #c3e59a 0, #f0fbe1 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffc3e59a', endColorstr='#fff0fbe1' )";
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffc3e59a\', endColorstr=\'#fff0fbe1\' )';
}
.oo-ui-buttonElement-framed.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
color: #d45353;
opacity: 0.5;
-webkit-transform: translate3d(0, 0, 0);
box-shadow: none;
- color: #333333;
- background: #eeeeee;
- border-color: #cccccc;
+ color: #333;
+ background: #eee;
+ border-color: #ccc;
}
.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:hover,
.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:hover,
.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus,
.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus,
.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:focus {
- border-color: #cccccc;
+ border-color: #ccc;
box-shadow: none;
}
.oo-ui-clippableElement-clippable {
}
.oo-ui-fieldLayout:before,
.oo-ui-fieldLayout:after {
- content: " ";
+ content: ' ';
display: table;
}
.oo-ui-fieldLayout:after {
margin-right: 0;
}
.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-fieldLayout-messages {
list-style: none none;
}
.oo-ui-fieldsetLayout {
position: relative;
+ min-width: 0;
margin: 0;
- padding: 0;
border: 0;
+ padding: 0.01px 0 0 0;
+}
+body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
+ display: table-cell;
}
.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
display: block;
position: absolute;
}
.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
- display: inline-block;
+ color: inherit;
+ display: table;
+ box-sizing: border-box;
+ max-width: 100%;
+ padding: 0;
+ white-space: normal;
}
.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
float: right;
background-color: #a7dcff;
}
.oo-ui-optionWidget.oo-ui-widget-disabled {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-decoratedOptionWidget {
padding: 0.5em 2em 0.5em 3em;
opacity: 0.2;
}
.oo-ui-buttonWidget {
- display: inline-block;
- vertical-align: middle;
margin-right: 0.5em;
}
.oo-ui-buttonWidget:last-child {
overflow: hidden;
}
.oo-ui-popupWidget-popup {
- background-color: #ffffff;
- border: 1px solid #cccccc;
+ background-color: #fff;
+ border: 1px solid #ccc;
border-radius: 0.25em;
box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
}
}
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
- content: "";
+ content: '';
position: absolute;
width: 0;
height: 0;
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
bottom: -7px;
left: -6px;
- border-bottom-color: #aaaaaa;
+ border-bottom-color: #aaa;
border-width: 7px;
}
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
bottom: -7px;
left: -5px;
- border-bottom-color: #ffffff;
+ border-bottom-color: #fff;
border-width: 6px;
}
.oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
.oo-ui-inputWidget:last-child {
margin-right: 0;
}
-.oo-ui-buttonInputWidget {
- display: inline-block;
- vertical-align: middle;
-}
.oo-ui-buttonInputWidget > button,
.oo-ui-buttonInputWidget > input {
border: 0;
box-sizing: border-box;
}
.oo-ui-dropdownInputWidget select {
- background-color: #ffffff;
+ background-color: #fff;
height: 2.5em;
padding: 0.5em;
font-size: inherit;
outline: none;
}
.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
- color: #cccccc;
- border-color: #dddddd;
+ color: #ccc;
+ border-color: #ddd;
background-color: #f3f3f3;
}
.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
overflow: auto;
resize: none;
}
-.oo-ui-textInputWidget [type="number"] {
+.oo-ui-textInputWidget [type='number'] {
-moz-appearance: textfield;
}
-.oo-ui-textInputWidget [type="number"]::-webkit-outer-spin-button,
-.oo-ui-textInputWidget [type="number"]::-webkit-inner-spin-button {
+.oo-ui-textInputWidget [type='number']::-webkit-outer-spin-button,
+.oo-ui-textInputWidget [type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
-.oo-ui-textInputWidget [type="search"] {
+.oo-ui-textInputWidget [type='search'] {
-webkit-appearance: textfield;
}
-.oo-ui-textInputWidget [type="search"]::-ms-clear {
+.oo-ui-textInputWidget [type='search']::-ms-clear {
display: none;
}
-.oo-ui-textInputWidget [type="search"]::-webkit-search-decoration,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-cancel-button {
+.oo-ui-textInputWidget [type='search']::-webkit-search-decoration,
+.oo-ui-textInputWidget [type='search']::-webkit-search-cancel-button {
display: none;
}
.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
cursor: pointer;
}
+.oo-ui-textInputWidget.oo-ui-widget-disabled input,
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
display: block;
}
line-height: 1.275em;
font-size: inherit;
font-family: inherit;
- background-color: #ffffff;
- color: #000000;
- border: 1px solid #cccccc;
- box-shadow: 0 0 0 #ffffff, inset 0 0.1em 0.2em #dddddd;
+ background-color: #fff;
+ color: #000;
+ border: 1px solid #ccc;
+ box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
border-radius: 0.25em;
-webkit-transition: border-color 250ms ease, box-shadow 250ms ease;
-moz-transition: border-color 250ms ease, box-shadow 250ms ease;
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
outline: none;
border-color: #a7dcff;
- box-shadow: 0 0 0.3em #a7dcff, 0 0 0 #ffffff;
+ box-shadow: 0 0 0.3em #a7dcff, 0 0 0 #fff;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
- color: #777777;
+ color: #777;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
- background-color: #ffdddd;
+ background-color: #fdd;
}
.oo-ui-textInputWidget.oo-ui-widget-disabled input,
.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
- color: #cccccc;
- text-shadow: 0 1px 1px #ffffff;
- border-color: #dddddd;
+ color: #ccc;
+ text-shadow: 0 1px 1px #fff;
+ border-color: #ddd;
background-color: #f3f3f3;
}
.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
opacity: 0.2;
}
.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
- color: #dddddd;
- text-shadow: 0 1px 1px #ffffff;
+ color: #ddd;
+ text-shadow: 0 1px 1px #fff;
}
.oo-ui-textInputWidget.oo-ui-iconElement input,
.oo-ui-textInputWidget.oo-ui-iconElement textarea {
.oo-ui-textInputWidget > .oo-ui-labelElement-label {
padding: 0.4em;
line-height: 1.5em;
- color: #888888;
+ color: #888;
}
.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
margin-right: 2.0875em;
position: absolute;
width: 100%;
z-index: 4;
- background-color: #ffffff;
+ background-color: #fff;
margin-top: -1px;
- border: 1px solid #cccccc;
+ border: 1px solid #ccc;
border-radius: 0 0 0.25em 0.25em;
box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
}
.oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
display: none;
}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
- background-color: transparent;
-}
.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
display: block;
}
.oo-ui-menuSectionOptionWidget {
cursor: default;
padding: 0.33em 0.75em;
- color: #888888;
+ color: #888;
}
.oo-ui-dropdownWidget {
display: inline-block;
position: relative;
width: 100%;
max-width: 50em;
- background-color: #ffffff;
+ background-color: #fff;
margin-right: 0.5em;
}
.oo-ui-dropdownWidget-handle {
margin: 0 0.5em;
}
.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
- color: #cccccc;
- text-shadow: 0 1px 1px #ffffff;
- border-color: #dddddd;
+ color: #ccc;
+ text-shadow: 0 1px 1px #fff;
+ border-color: #ddd;
background-color: #f3f3f3;
}
.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
}
.oo-ui-comboBoxInputWidget {
display: inline-block;
- position: relative;
width: 100%;
max-width: 50em;
margin-right: 0.5em;
line-height: 1.5em;
}
.oo-ui-multioptionWidget.oo-ui-widget-disabled {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-checkboxMultioptionWidget {
cursor: default;
}
.oo-ui-progressBarWidget {
max-width: 50em;
- background-color: #ffffff;
- border: 1px solid #cccccc;
+ background-color: #fff;
+ border: 1px solid #ccc;
border-radius: 0.25em;
overflow: hidden;
}
.oo-ui-progressBarWidget-bar {
height: 1em;
- border-right: 1px solid #cccccc;
+ border-right: 1px solid #ccc;
-webkit-transition: width 250ms ease, margin-left 250ms ease;
-moz-transition: width 250ms ease, margin-left 250ms ease;
transition: width 250ms ease, margin-left 250ms ease;
background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
background-image: -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
background-image: linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffeaf4fa\', endColorstr=\'#ffb0d9ee\' )';
}
.oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
-webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
.oo-ui-element-hidden {
display: none !important;
/* stylelint-disable-line declaration-no-important */
}
+.oo-ui-buttonElement {
+ display: inline-block;
+ vertical-align: middle;
+}
.oo-ui-buttonElement > .oo-ui-buttonElement-button {
cursor: pointer;
display: inline-block;
margin-right: 0.25em;
margin-left: 0.46875em;
}
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+ -webkit-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+ -moz-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+ transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+}
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+ opacity: 0.87;
+ -webkit-transition: opacity 100ms;
+ -moz-transition: opacity 100ms;
+ transition: opacity 100ms;
+}
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon.oo-ui-image-invert,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator.oo-ui-image-invert {
+ opacity: 1;
+}
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-indicatorElement-indicator {
+ opacity: 0.73;
+}
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon.oo-ui-image-invert,
+.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-indicatorElement-indicator.oo-ui-image-invert {
+ opacity: 1;
+}
+.oo-ui-buttonElement.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+ opacity: 1;
+}
.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
margin-right: 0;
}
padding-left: 0.25em;
padding-right: 0.25em;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- box-shadow: inset 0 0 0 1px #347bff, 0 0 0 1px #347bff;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+ color: #222;
}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #555555;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
+ color: #444;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+ box-shadow: inset 0 0 0 1px #36c, 0 0 0 1px #36c;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #444444;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:active {
+ color: #000;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #347bff;
+ color: #36c;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
- color: #2962cc;
+ color: #447ff5;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #1f4999;
+ color: #2a4b8d;
box-shadow: none;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #347bff;
+ color: #36c;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
- color: #2962cc;
+ color: #447ff5;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #1f4999;
+ color: #2a4b8d;
box-shadow: none;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #d11d13;
+ color: #c33;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
- color: #8c130d;
+ color: #e53939;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
- color: #73100a;
+ color: #873636;
box-shadow: none;
}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+ opacity: 1;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button:hover > .oo-ui-indicatorElement-indicator {
+ opacity: 0.73;
+}
.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
- opacity: 0.2;
+ opacity: 0.51;
}
.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
min-width: 1em;
border-radius: 2px;
position: relative;
- -webkit-transition: background 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
- -moz-transition: background 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
- transition: background 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
}
.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
left: 0.2em;
}
.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
- background-color: #dddddd;
- color: #ffffff;
- border: 1px solid #dddddd;
+ background-color: #c8ccd1;
+ color: #fff;
+ border: 1px solid #c8ccd1;
}
.oo-ui-buttonElement-framed.oo-ui-widget-disabled + .oo-ui-widget-disabled > .oo-ui-buttonElement-button {
- border-left-color: #ffffff;
+ border-left-color: #fff;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
- color: #555555;
- background-color: #ffffff;
- border: 1px solid #cccccc;
+ background-color: #f8f9fa;
+ color: #222;
+ border: 1px solid #9aa0a7;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
- background-color: #ebebeb;
+ background-color: #fff;
+ color: #444;
+ border-color: #a2a9b1;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
background-color: #d9d9d9;
- border-color: #d9d9d9;
+ color: #000;
+ border-color: #72777d;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
- background-color: #999999;
- color: #ffffff;
- border-color: #999999;
+ background-color: #2a4b8d;
+ color: #fff;
+ border-color: #2a4b8d;
z-index: 3;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus {
- border-color: #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
- color: #347bff;
+ color: #36c;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
- background-color: #ebf2ff;
+ background-color: #fff;
border-color: #859dcc;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
- color: #1f4999;
- border-color: #1f4999;
- box-shadow: none;
-}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
- background-color: #999999;
- color: #ffffff;
+ background-color: #eff3fa;
+ color: #2a4b8d;
+ border-color: #2a4b8d;
+ box-shadow: none;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
- color: #347bff;
+ color: #36c;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
- background-color: #ebf2ff;
+ background-color: #fff;
border-color: #859dcc;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
- color: #1f4999;
- border-color: #1f4999;
- box-shadow: none;
-}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
- background-color: #999999;
- color: #ffffff;
+ background-color: #eff3fa;
+ color: #2a4b8d;
+ border-color: #2a4b8d;
+ box-shadow: none;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
- color: #d11d13;
+ color: #c33;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
- background-color: #fbe8e7;
+ background-color: #fff;
border-color: #b77c79;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
- color: #73100a;
- border-color: #73100a;
- box-shadow: none;
-}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
- background-color: #999999;
- color: #ffffff;
+ background-color: #fbf4f4;
+ color: #873636;
+ border-color: #873636;
+ box-shadow: none;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- border-color: #d11d13;
- box-shadow: inset 0 0 0 1px #d11d13;
+ border-color: #c33;
+ box-shadow: inset 0 0 0 1px #c33;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
- color: #ffffff;
- background-color: #347bff;
- border-color: #347bff;
+ color: #fff;
+ background-color: #36c;
+ border-color: #36c;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
- background-color: #2962cc;
- border-color: #2962cc;
+ background-color: #447ff5;
+ border-color: #447ff5;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
- color: #ffffff;
- background-color: #1f4999;
- border-color: #1f4999;
- box-shadow: none;
-}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
- background-color: #999999;
- color: #ffffff;
+ color: #fff;
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
+ box-shadow: none;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff, inset 0 0 0 2px #ffffff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
- color: #ffffff;
- background-color: #347bff;
- border-color: #347bff;
+ color: #fff;
+ background-color: #36c;
+ border-color: #36c;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
- background-color: #2962cc;
- border-color: #2962cc;
+ background-color: #447ff5;
+ border-color: #447ff5;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
- color: #ffffff;
- background-color: #1f4999;
- border-color: #1f4999;
- box-shadow: none;
-}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
- background-color: #999999;
- color: #ffffff;
+ color: #fff;
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
+ box-shadow: none;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff, inset 0 0 0 2px #ffffff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
- color: #ffffff;
- background-color: #d11d13;
- border-color: #d11d13;
+ color: #fff;
+ background-color: #c33;
+ border-color: #c33;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
- background-color: #8c130d;
- border-color: #8c130d;
+ background-color: #e53939;
+ border-color: #e53939;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
- color: #ffffff;
- background-color: #73100a;
- border-color: #73100a;
- box-shadow: none;
-}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
- background-color: #999999;
- color: #ffffff;
+ color: #fff;
+ background-color: #873636;
+ border-color: #873636;
+ box-shadow: none;
}
.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
- border-color: #d11d13;
- box-shadow: inset 0 0 0 1px #d11d13, inset 0 0 0 2px #ffffff;
+ border-color: #c33;
+ box-shadow: inset 0 0 0 1px #c33, inset 0 0 0 2px #fff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+ opacity: 1;
}
.oo-ui-clippableElement-clippable {
-webkit-box-sizing: border-box;
}
.oo-ui-fieldLayout:before,
.oo-ui-fieldLayout:after {
- content: " ";
+ content: ' ';
display: table;
}
.oo-ui-fieldLayout:after {
margin-right: 0;
}
.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-fieldLayout-messages {
list-style: none none;
}
.oo-ui-fieldsetLayout {
position: relative;
+ min-width: 0;
margin: 0;
- padding: 0;
border: 0;
+ padding: 0.01px 0 0 0;
+}
+body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
+ display: table-cell;
}
.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
display: block;
position: absolute;
}
.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
- display: inline-block;
+ color: inherit;
+ display: table;
+ box-sizing: border-box;
+ max-width: 100%;
+ padding: 0;
+ white-space: normal;
}
.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
float: right;
padding: 1.25em;
}
.oo-ui-panelLayout-framed {
- border: 1px solid #aaaaaa;
+ border: 1px solid #a2a9b1;
border-radius: 2px;
box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
}
.oo-ui-optionWidget {
position: relative;
display: block;
- padding: 0.25em 0.5em;
border: 0;
+ padding: 0.25em 0.5em;
}
.oo-ui-optionWidget.oo-ui-widget-enabled {
cursor: pointer;
text-overflow: ellipsis;
overflow: hidden;
}
-.oo-ui-optionWidget-highlighted {
- background-color: #eeeeee;
-}
.oo-ui-optionWidget .oo-ui-labelElement-label {
line-height: 1.5;
}
-.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
- background-color: #d0d0d0;
+.oo-ui-optionWidget-selected .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+ opacity: 1;
}
.oo-ui-optionWidget.oo-ui-widget-disabled {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-decoratedOptionWidget {
padding: 0.5em 2em 0.5em 3em;
}
.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
- opacity: 0.2;
+ opacity: 0.51;
}
.oo-ui-radioSelectWidget:focus {
outline: 0;
}
-.oo-ui-radioSelectWidget:focus .oo-ui-radioOptionWidget.oo-ui-optionWidget-selected .oo-ui-radioInputWidget [type="radio"] + span {
- border-width: 2px;
+.oo-ui-radioSelectWidget:focus [type='radio']:checked + span:before {
+ border-color: #fff;
}
.oo-ui-radioOptionWidget {
cursor: default;
line-height: 2.5;
}
.oo-ui-iconWidget.oo-ui-widget-disabled {
- opacity: 0.2;
+ opacity: 0.51;
}
.oo-ui-indicatorWidget {
display: inline-block;
margin: 0.46875em;
}
.oo-ui-indicatorWidget.oo-ui-widget-disabled {
- opacity: 0.2;
+ opacity: 0.51;
}
.oo-ui-buttonWidget {
- display: inline-block;
- vertical-align: middle;
margin-right: 0.5em;
}
.oo-ui-buttonWidget:last-child {
border-top-right-radius: 2px;
}
.oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement .oo-ui-buttonElement-button:focus {
- border-color: #347bff;
+ border-color: #36c;
z-index: 3;
}
.oo-ui-popupWidget {
overflow: hidden;
}
.oo-ui-popupWidget-popup {
- background-color: #ffffff;
- border: 1px solid #aaaaaa;
+ background-color: #fff;
+ border: 1px solid #a2a9b1;
border-radius: 2px;
box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
}
}
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
- content: "";
+ content: '';
position: absolute;
width: 0;
height: 0;
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
bottom: -10px;
left: -9px;
- border-bottom-color: #888888;
+ border-bottom-color: #888;
border-width: 10px;
}
.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
bottom: -10px;
left: -8px;
- border-bottom-color: #ffffff;
+ border-bottom-color: #fff;
border-width: 9px;
}
.oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
.oo-ui-inputWidget:last-child {
margin-right: 0;
}
-.oo-ui-buttonInputWidget {
- display: inline-block;
- vertical-align: middle;
-}
.oo-ui-buttonInputWidget > button,
.oo-ui-buttonInputWidget > input {
border: 0;
font: inherit;
vertical-align: middle;
}
-.oo-ui-checkboxInputWidget [type="checkbox"] {
- opacity: 0;
- z-index: 1;
+.oo-ui-checkboxInputWidget [type='checkbox'] {
position: relative;
- cursor: pointer;
- margin: 0;
+ max-width: none;
width: 1.6em;
height: 1.6em;
- max-width: none;
+ margin: 0;
+ opacity: 0;
+ z-index: 1;
}
-.oo-ui-checkboxInputWidget [type="checkbox"] + span {
- -webkit-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
- -moz-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
- transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+.oo-ui-checkboxInputWidget [type='checkbox'] + span {
+ background-color: #fff;
+ background-origin: border-box;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: 0 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
left: 0;
width: 1.6em;
height: 1.6em;
- background-color: #ffffff;
- background-image: url("themes/mediawiki/images/icons/check-constructive-deprecated.png");
- background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-constructive-deprecated.svg");
- background-image: linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-constructive-deprecated.svg");
- background-image: -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check-constructive-deprecated.png");
- background-repeat: no-repeat;
- background-position: center center;
- background-origin: border-box;
- background-size: 0 0;
- border: 1px solid #767676;
+ border: 1px solid #72777d;
border-radius: 2px;
}
-.oo-ui-checkboxInputWidget [type="checkbox"]:checked + span {
- background-size: 100% 100%;
+.oo-ui-checkboxInputWidget [type='checkbox']:checked + span {
+ background-image: url('themes/mediawiki/images/icons/check-invert.png');
+ background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-invert.svg');
+ background-image: linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-invert.svg');
+ background-image: -o-linear-gradient(transparent, transparent), url('themes/mediawiki/images/icons/check-invert.png');
+ background-size: 90% 90%;
}
-.oo-ui-checkboxInputWidget [type="checkbox"]:active + span {
- background-color: #767676;
- border-color: #767676;
+.oo-ui-checkboxInputWidget [type='checkbox']:disabled + span {
+ background-color: #c8ccd1;
+ border-color: #c8ccd1;
}
-.oo-ui-checkboxInputWidget [type="checkbox"]:focus + span {
- border-width: 2px;
+.oo-ui-checkboxInputWidget [type='checkbox']:disabled:hover + span {
+ background-color: #c8ccd1;
+ border-color: #c8ccd1;
}
-.oo-ui-checkboxInputWidget [type="checkbox"]:focus:hover + span,
-.oo-ui-checkboxInputWidget [type="checkbox"]:hover + span {
- border-bottom-width: 3px;
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox'] {
+ cursor: pointer;
}
-.oo-ui-checkboxInputWidget [type="checkbox"]:disabled {
- cursor: default;
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox'] + span {
+ cursor: pointer;
+ -webkit-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
+ -moz-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
+ transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
+}
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:hover + span,
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:focus:hover + span {
+ border-color: #36c;
+}
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:active + span {
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
+}
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:focus + span {
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
+}
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked + span {
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
}
-.oo-ui-checkboxInputWidget [type="checkbox"]:disabled + span {
- background-color: #dddddd;
- border-color: #dddddd;
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:hover + span,
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:focus:hover + span {
+ background-color: #36c;
+ border-color: #36c;
}
-.oo-ui-checkboxInputWidget [type="checkbox"]:disabled:checked + span {
- background-image: url("themes/mediawiki/images/icons/check-invert.png");
- background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-invert.svg");
- background-image: linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-invert.svg");
- background-image: -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check-invert.png");
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:active + span,
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:active:hover + span {
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
+}
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:focus + span {
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
+ box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
}
.oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout {
margin-bottom: 0;
box-sizing: border-box;
}
.oo-ui-dropdownInputWidget select {
- background-color: #ffffff;
+ background-color: #fff;
height: 2.275em;
font-size: inherit;
font-family: inherit;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
- border: 1px solid #cccccc;
+ border: 1px solid #9aa0a7;
border-radius: 2px;
padding-left: 1em;
vertical-align: middle;
}
.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
- border-color: #aaaaaa;
+ border-color: #a2a9b1;
outline: 0;
}
.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
- color: #cccccc;
- border-color: #dddddd;
- background-color: #f3f3f3;
+ color: #72777d;
+ border-color: #c8ccd1;
+ background-color: #eaecf0;
}
.oo-ui-radioInputWidget {
position: relative;
font: inherit;
vertical-align: middle;
}
-.oo-ui-radioInputWidget [type="radio"] {
- opacity: 0;
- z-index: 1;
+.oo-ui-radioInputWidget [type='radio'] {
position: relative;
- cursor: pointer;
- margin: 0;
+ max-width: none;
width: 1.6em;
height: 1.6em;
- max-width: none;
+ margin: 0;
+ opacity: 0;
+ z-index: 1;
}
-.oo-ui-radioInputWidget [type="radio"] + span {
- -webkit-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
- -moz-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
- transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+.oo-ui-radioInputWidget [type='radio'] + span {
+ background-color: #fff;
+ position: absolute;
+ left: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
- position: absolute;
- left: 0;
width: 1.6em;
height: 1.6em;
- background-color: #ffffff;
- background-image: url("themes/mediawiki/images/icons/circle-constructive-deprecated.png");
- background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-constructive-deprecated.svg");
- background-image: linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-constructive-deprecated.svg");
- background-image: -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/circle-constructive-deprecated.png");
- background-repeat: no-repeat;
- background-position: center center;
- background-origin: border-box;
- background-size: 0 0;
- border: 1px solid #767676;
+ border: 1px solid #72777d;
border-radius: 100%;
}
-.oo-ui-radioInputWidget [type="radio"]:checked + span {
- background-size: 100% 100%;
+.oo-ui-radioInputWidget [type='radio'] + span:before {
+ content: ' ';
+ position: absolute;
+ top: -4px;
+ left: -4px;
+ right: -4px;
+ bottom: -4px;
+ border: 1px solid transparent;
+ border-radius: 100%;
}
-.oo-ui-radioInputWidget [type="radio"]:active + span {
- background-color: #767676;
- border-color: #767676;
+.oo-ui-radioInputWidget [type='radio']:checked + span {
+ border-width: 0.4em;
}
-.oo-ui-radioInputWidget [type="radio"]:focus + span {
- border-width: 2px;
+.oo-ui-radioInputWidget [type='radio']:checked:hover + span,
+.oo-ui-radioInputWidget [type='radio']:checked:focus:hover + span {
+ border-width: 0.4em;
}
-.oo-ui-radioInputWidget [type="radio"]:focus:hover + span,
-.oo-ui-radioInputWidget [type="radio"]:hover + span {
- border-bottom-width: 3px;
+.oo-ui-radioInputWidget [type='radio']:disabled + span {
+ background-color: #c8ccd1;
+ border-color: #c8ccd1;
}
-.oo-ui-radioInputWidget [type="radio"]:disabled {
- cursor: default;
+.oo-ui-radioInputWidget [type='radio']:disabled:checked + span {
+ background-color: #fff;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio'] {
+ cursor: pointer;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio'] + span {
+ cursor: pointer;
+ -webkit-transition: background-color 100ms, border-color 100ms, border-width 100ms;
+ -moz-transition: background-color 100ms, border-color 100ms, border-width 100ms;
+ transition: background-color 100ms, border-color 100ms, border-width 100ms;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:hover + span {
+ border-color: #36c;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:active + span {
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked + span {
+ border-color: #2a4b8d;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:hover + span {
+ border-color: #36c;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:hover:focus + span {
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:active + span,
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:active:focus + span {
+ border-color: #2a4b8d;
+ box-shadow: inset 0 0 0 1px #2a4b8d;
}
-.oo-ui-radioInputWidget [type="radio"]:disabled + span {
- background-color: #dddddd;
- border-color: #dddddd;
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:focus + span {
+ box-shadow: inset 0 0 0 1px #36c;
}
-.oo-ui-radioInputWidget [type="radio"]:disabled:checked + span {
- background-image: url("themes/mediawiki/images/icons/circle-invert.png");
- background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-invert.svg");
- background-image: linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-invert.svg");
- background-image: -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/circle-invert.png");
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:focus + span:before {
+ border-color: #fff;
+ top: -3px;
+ right: -3px;
+ bottom: -3px;
+ left: -3px;
}
.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
margin-bottom: 0;
overflow: auto;
resize: none;
}
-.oo-ui-textInputWidget [type="number"] {
+.oo-ui-textInputWidget [type='number'] {
-moz-appearance: textfield;
}
-.oo-ui-textInputWidget [type="number"]::-webkit-outer-spin-button,
-.oo-ui-textInputWidget [type="number"]::-webkit-inner-spin-button {
+.oo-ui-textInputWidget [type='number']::-webkit-outer-spin-button,
+.oo-ui-textInputWidget [type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
-.oo-ui-textInputWidget [type="search"] {
+.oo-ui-textInputWidget [type='search'] {
-webkit-appearance: textfield;
}
-.oo-ui-textInputWidget [type="search"]::-ms-clear {
+.oo-ui-textInputWidget [type='search']::-ms-clear {
display: none;
}
-.oo-ui-textInputWidget [type="search"]::-webkit-search-decoration,
-.oo-ui-textInputWidget [type="search"]::-webkit-search-cancel-button {
+.oo-ui-textInputWidget [type='search']::-webkit-search-decoration,
+.oo-ui-textInputWidget [type='search']::-webkit-search-cancel-button {
display: none;
}
.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
cursor: pointer;
}
+.oo-ui-textInputWidget.oo-ui-widget-disabled input,
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
display: block;
}
margin: 0;
font-size: inherit;
font-family: inherit;
- background-color: #ffffff;
- color: #000000;
- border: 1px solid #cccccc;
+ background-color: #fff;
+ color: #000;
+ border: 1px solid #9aa0a7;
border-radius: 2px;
}
.oo-ui-textInputWidget textarea {
}
.oo-ui-textInputWidget.oo-ui-widget-enabled input,
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea {
- box-shadow: inset 0 0 0 0.1em #ffffff;
- -webkit-transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
- -moz-transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
- transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+ box-shadow: inset 0 0 0 0.1em #fff;
+ -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+ -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+ transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
}
.oo-ui-textInputWidget.oo-ui-widget-enabled input:hover,
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:hover {
- border-color: #aaaaaa;
+ border-color: #72777d;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
outline: 0;
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
- color: #777777;
- text-shadow: 0 1px 1px #ffffff;
+ color: #777;
+ text-shadow: 0 1px 1px #fff;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly]:hover,
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly]:hover {
- border-color: #cccccc;
+ border-color: #ccc;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly]:focus,
.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly]:focus {
- border-color: #cccccc;
- box-shadow: inset 0 0 0 0.1em #cccccc;
+ border-color: #ccc;
+ box-shadow: inset 0 0 0 0.1em #ccc;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled :-moz-placeholder {
- color: #595959;
+ color: #54595d;
opacity: 1;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled ::-moz-placeholder {
- color: #595959;
+ color: #54595d;
opacity: 1;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled :-ms-input-placeholder {
- color: #595959;
+ color: #54595d;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled ::-webkit-input-placeholder {
- color: #595959;
+ color: #54595d;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
- border-color: #ff0000;
+ border-color: #f00;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:hover,
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:hover {
- border-color: #ff0000;
+ border-color: #f00;
}
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:focus,
.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:focus {
- border-color: #ff0000;
- box-shadow: inset 0 0 0 0.1em #ff0000;
+ border-color: #f00;
+ box-shadow: inset 0 0 0 0.1em #f00;
}
.oo-ui-textInputWidget.oo-ui-widget-disabled input,
.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
- color: #cccccc;
- text-shadow: 0 1px 1px #ffffff;
- border-color: #dddddd;
- background-color: #f3f3f3;
+ background-color: #eaecf0;
+ color: #72777d;
+ text-shadow: 0 1px 1px #fff;
+ border-color: #c8ccd1;
}
.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
- opacity: 0.2;
+ opacity: 0.51;
}
.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
- color: #cccccc;
- text-shadow: 0 1px 1px #ffffff;
+ color: #72777d;
+ text-shadow: 0 1px 1px #fff;
}
.oo-ui-textInputWidget.oo-ui-iconElement input,
.oo-ui-textInputWidget.oo-ui-iconElement textarea {
.oo-ui-textInputWidget > .oo-ui-labelElement-label {
padding: 0.4em;
line-height: 1.5;
- color: #888888;
+ color: #888;
}
.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
margin-right: 2.0875em;
position: absolute;
width: 100%;
z-index: 4;
- background-color: #ffffff;
+ background-color: #fff;
margin-top: -1px;
- border: 1px solid #aaaaaa;
+ border: 1px solid #a2a9b1;
border-radius: 0 0 2px 2px;
box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
}
.oo-ui-menuOptionWidget {
position: relative;
padding: 0.5em 1em;
+ -webkit-transition: background-color 100ms, color 100ms;
+ -moz-transition: background-color 100ms, color 100ms;
+ transition: background-color 100ms, color 100ms;
}
.oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
display: none;
}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
- background-color: transparent;
-}
.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
display: block;
}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
+ background-color: #eaecf0;
+ color: #000;
+}
.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
- background-color: #d8e6fe;
- color: rgba(0, 0, 0, 0.8);
+ background-color: #eaf3ff;
+ color: #36c;
}
.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
display: none;
}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
- background-color: #eeeeee;
- color: #000000;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
- background-color: #d8e6fe;
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-pressed.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
+ background-color: rgba(41, 98, 204, 0.1);
+ color: #36c;
}
.oo-ui-menuSectionOptionWidget {
cursor: default;
padding: 0.33em 0.75em;
- color: #888888;
+ color: #888;
}
.oo-ui-dropdownWidget {
display: inline-block;
padding: 0.5em 0;
height: 2.275em;
line-height: 1.275;
- border: 1px solid #cccccc;
+ border: 1px solid #9aa0a7;
border-radius: 2px;
}
.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
margin: 0 1em;
}
.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
- background-color: #ffffff;
- -webkit-transition: border-color 100ms;
- -moz-transition: border-color 100ms;
- transition: border-color 100ms;
+ background-color: #f8f9fa;
+ color: #222;
+ -webkit-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+ -moz-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+ transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover {
+ background-color: #fff;
+ border-color: #a2a9b1;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover .oo-ui-iconElement-icon,
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover .oo-ui-indicatorElement-indicator {
+ opacity: 0.73;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:focus {
+ border-color: #36c;
+ outline: 0;
+ box-shadow: inset 0 0 0 1px #36c;
}
-.oo-ui-dropdownWidget.oo-ui-widget-enabled:hover .oo-ui-dropdownWidget-handle {
- border-color: #aaaaaa;
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon,
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+ opacity: 0.87;
+ -webkit-transition: opacity 100ms;
+ -moz-transition: opacity 100ms;
+ transition: opacity 100ms;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-enabled.oo-ui-dropdownWidget-open .oo-ui-dropdownWidget-handle {
+ background-color: #fff;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-enabled.oo-ui-dropdownWidget-open .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon,
+.oo-ui-dropdownWidget.oo-ui-widget-enabled.oo-ui-dropdownWidget-open .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+ opacity: 1;
}
.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
- color: #cccccc;
- text-shadow: 0 1px 1px #ffffff;
- border-color: #dddddd;
- background-color: #f3f3f3;
+ color: #72777d;
+ text-shadow: 0 1px 1px #fff;
+ border-color: #c8ccd1;
+ background-color: #eaecf0;
}
.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
outline: 0;
}
.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
- opacity: 0.2;
+ opacity: 0.15;
}
.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
margin-left: 3em;
}
.oo-ui-comboBoxInputWidget {
display: inline-block;
- position: relative;
- width: 100%;
- max-width: 50em;
- margin-right: 0.5em;
}
.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
cursor: pointer;
.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
pointer-events: none;
}
-.oo-ui-comboBoxInputWidget:last-child {
- margin-right: 0;
-}
.oo-ui-comboBoxInputWidget input,
.oo-ui-comboBoxInputWidget textarea {
height: 2.35em;
}
+.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover input,
+.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover textarea {
+ border-color: #a2a9b1;
+}
+.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover input:focus,
+.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover textarea:focus {
+ border-color: #36c;
+}
+.oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+ opacity: 0.15;
+}
.oo-ui-multioptionWidget {
position: relative;
display: block;
line-height: 1.5;
}
.oo-ui-multioptionWidget.oo-ui-widget-disabled {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-checkboxMultioptionWidget {
cursor: default;
}
.oo-ui-progressBarWidget {
max-width: 50em;
- background-color: #ffffff;
- border: 1px solid #cccccc;
+ background-color: #fff;
+ border: 1px solid #9aa0a7;
border-radius: 2px;
overflow: hidden;
}
.oo-ui-progressBarWidget-bar {
- background-color: #dddddd;
+ background-color: #ddd;
height: 1em;
-webkit-transition: width 200ms, margin-left 200ms;
-moz-transition: width 200ms, margin-left 200ms;
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:48Z
+ * Date: 2016-09-13T18:30:02Z
*/
( function ( OO ) {
// pick up dynamic state, like focus, value of form inputs, scroll position, etc.
state = cls.static.gatherPreInfuseState( $elem[ 0 ], data );
// rebuild widget
- // jscs:disable requireCapitalizedConstructors
obj = new cls( data );
- // jscs:enable requireCapitalizedConstructors
// now replace old DOM with this new DOM.
if ( top ) {
// An efficient constructor might be able to reuse the entire DOM tree of the original element,
* @class
*
* @constructor
- * @param {Object} [config] Configuration options
*/
-OO.ui.Theme = function OoUiTheme( config ) {
- // Configuration initialization
- config = config || {};
-};
+OO.ui.Theme = function OoUiTheme() {};
/* Setup */
// Properties
this.$button = null;
this.framed = null;
- this.active = false;
+ this.active = config.active !== undefined && config.active;
this.onMouseUpHandler = this.onMouseUp.bind( this );
this.onMouseDownHandler = this.onMouseDown.bind( this );
this.onKeyDownHandler = this.onKeyDown.bind( this );
keypress: this.menu.onKeyPressHandler,
blur: this.menu.clearKeyPressBuffer.bind( this.menu )
} );
- this.menu.connect( this, { select: 'onMenuSelect' } );
+ this.menu.connect( this, {
+ select: 'onMenuSelect',
+ toggle: 'onMenuToggle'
+ } );
// Initialization
this.$handle
this.setLabel( selectedLabel );
};
+/**
+ * Handle menu toggle events.
+ *
+ * @private
+ * @param {boolean} isVisible Menu toggle event
+ */
+OO.ui.DropdownWidget.prototype.onMenuToggle = function ( isVisible ) {
+ this.$element.toggleClass( 'oo-ui-dropdownWidget-open', isVisible );
+};
+
/**
* Handle mouse click events.
*
*/
OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) {
var elemRect, contRect,
- topEdgeInBounds = false,
leftEdgeInBounds = false,
bottomEdgeInBounds = false,
rightEdgeInBounds = false;
contRect = $container[ 0 ].getBoundingClientRect();
}
- if ( elemRect.top >= contRect.top && elemRect.top <= contRect.bottom ) {
- topEdgeInBounds = true;
- }
+ // For completeness, if we still cared about topEdgeInBounds, that'd be:
+ // elemRect.top >= contRect.top && elemRect.top <= contRect.bottom
if ( elemRect.left >= contRect.left && elemRect.left <= contRect.right ) {
leftEdgeInBounds = true;
}
// Initialization
this.$element
.addClass( 'oo-ui-fieldLayout' )
+ .toggleClass( 'oo-ui-fieldLayout-disabled', this.fieldWidget.isDisabled() )
.append( this.$help, this.$body );
this.$body.addClass( 'oo-ui-fieldLayout-body' );
this.$messages.addClass( 'oo-ui-fieldLayout-messages' );
this.$field
.addClass( 'oo-ui-fieldLayout-field' )
- .toggleClass( 'oo-ui-fieldLayout-disable', this.fieldWidget.isDisabled() )
.append( this.fieldWidget.$element );
this.setErrors( config.errors || [] );
// Mixin constructors
OO.ui.mixin.IconElement.call( this, config );
- OO.ui.mixin.LabelElement.call( this, config );
+ OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: $( '<legend>' ) } ) );
OO.ui.mixin.GroupElement.call( this, config );
if ( config.help ) {
// Initialization
this.$element
.addClass( 'oo-ui-fieldsetLayout' )
- .prepend( this.$help, this.$icon, this.$label, this.$group );
+ .prepend( this.$label, this.$help, this.$icon, this.$group );
if ( Array.isArray( config.items ) ) {
this.addItems( config.items );
}
OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.LabelElement );
OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.GroupElement );
+/* Static Properties */
+
+OO.ui.FieldsetLayout.static.tagName = 'fieldset';
+
/**
* FormLayouts are used to wrap {@link OO.ui.FieldsetLayout FieldsetLayouts} when you intend to use browser-based
* form submission for the fields instead of handling them in JavaScript. Form layouts can be configured with an
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:48Z
+ * Date: 2016-09-13T18:30:02Z
*/
( function ( OO ) {
} else if ( !isFramed && element.isDisabled() ) {
// Frameless disabled button, always use black icon regardless of flags
variants.invert = false;
- } else {
+ } else if ( !element.isDisabled() ) {
// Any other kind of button, use the right colored icon if available
variants.progressive = element.hasFlag( 'progressive' );
variants.constructive = element.hasFlag( 'constructive' );
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
.oo-ui-popupTool .oo-ui-popupWidget-popup,
.oo-ui-popupTool .oo-ui-popupWidget-anchor {
border-color: rgba(0, 0, 0, 0.1);
}
.oo-ui-toolGroup.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
- color: #000000;
+ color: #000;
}
.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
.oo-ui-barToolGroup > .oo-ui-labelElement-label {
border-color: rgba(0, 0, 0, 0.2);
box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
background-color: #f8fbfd;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #ffffff));
- background-image: -webkit-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
- background-image: -moz-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
- background-image: linear-gradient(to bottom, #f1f7fb 0, #ffffff 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
+ background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
+ background-image: -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
+ background-image: linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff1f7fb\', endColorstr=\'#ffffffff\' )';
}
.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
border-left-color: rgba(0, 0, 0, 0.1);
outline: 0;
}
.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
opacity: 0.2;
outline: 0;
}
.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
opacity: 0.2;
border-bottom-right-radius: 0;
box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
background-color: #f8fbfd;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #ffffff));
- background-image: -webkit-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
- background-image: -moz-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
- background-image: linear-gradient(to bottom, #f1f7fb 0, #ffffff 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
+ background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
+ background-image: -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
+ background-image: linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff1f7fb\', endColorstr=\'#ffffffff\' )';
}
.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
top: 2.5em;
margin: 0 -1px;
- border: 1px solid #cccccc;
- background-color: #ffffff;
+ border: 1px solid #ccc;
+ background-color: #fff;
box-shadow: 0 0.3125em 1.25em rgba(0, 0, 0, 0.25);
}
.oo-ui-popupToolGroup .oo-ui-tool-link {
line-height: 2em;
}
.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
- color: #888888;
+ color: #888;
}
.oo-ui-listToolGroup .oo-ui-tool {
display: block;
border-color: rgba(0, 0, 0, 0.1);
box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
background-color: #f8fbfd;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #ffffff));
- background-image: -webkit-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
- background-image: -moz-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
- background-image: linear-gradient(to bottom, #f1f7fb 0, #ffffff 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
+ background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
+ background-image: -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
+ background-image: linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff1f7fb\', endColorstr=\'#ffffffff\' )';
}
.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
border-top-color: rgba(0, 0, 0, 0.1);
opacity: 1;
}
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-accel {
- color: #dddddd;
+ color: #ddd;
}
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
opacity: 0.2;
}
.oo-ui-listToolGroup.oo-ui-widget-disabled {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
background-image: none;
}
.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
- background-image: url("themes/apex/images/icons/check.png");
- background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/apex/images/icons/check.svg");
- background-image: linear-gradient(transparent, transparent), /* @embed */ url("themes/apex/images/icons/check.svg");
- background-image: -o-linear-gradient(transparent, transparent), url("themes/apex/images/icons/check.png");
+ background-image: url('themes/apex/images/icons/check.png');
+ background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/apex/images/icons/check.svg');
+ background-image: linear-gradient(transparent, transparent), /* @embed */ url('themes/apex/images/icons/check.svg');
+ background-image: -o-linear-gradient(transparent, transparent), url('themes/apex/images/icons/check.png');
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
background-color: #e1f3ff;
}
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
opacity: 0.2;
}
.oo-ui-menuToolGroup.oo-ui-widget-disabled {
- color: #cccccc;
+ color: #ccc;
border-color: rgba(0, 0, 0, 0.05);
}
.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
line-height: 1;
position: relative;
}
-.oo-ui-toolbar-actions {
- float: right;
-}
-.oo-ui-toolbar-actions .oo-ui-toolbar {
- display: inline-block;
+.oo-ui-toolbar-tools,
+.oo-ui-toolbar-actions,
+.oo-ui-toolbar-shadow {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
}
.oo-ui-toolbar-tools {
display: inline;
.oo-ui-toolbar-tools .oo-ui-tool {
white-space: normal;
}
-.oo-ui-toolbar-tools,
-.oo-ui-toolbar-actions,
-.oo-ui-toolbar-shadow {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
+.oo-ui-toolbar-actions {
+ float: right;
+}
+.oo-ui-toolbar-actions .oo-ui-toolbar {
+ display: inline-block;
}
.oo-ui-toolbar-actions .oo-ui-popupWidget {
-webkit-touch-callout: default;
pointer-events: none;
}
.oo-ui-toolbar-bar {
- border-bottom: 1px solid #cccccc;
+ border-bottom: 1px solid #ccc;
background-color: #f8fbfd;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #f1f7fb));
- background-image: -webkit-linear-gradient(top, #ffffff 0, #f1f7fb 100%);
- background-image: -moz-linear-gradient(top, #ffffff 0, #f1f7fb 100%);
- background-image: linear-gradient(to bottom, #ffffff 0, #f1f7fb 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#fff1f7fb' )";
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #f1f7fb));
+ background-image: -webkit-linear-gradient(top, #fff 0, #f1f7fb 100%);
+ background-image: -moz-linear-gradient(top, #fff 0, #f1f7fb 100%);
+ background-image: linear-gradient(to bottom, #fff 0, #f1f7fb 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#fff1f7fb\' )';
}
.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
border: 0;
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
+.oo-ui-tool.oo-ui-widget-enabled {
+ -webkit-transition: background-color 100ms;
+ -moz-transition: background-color 100ms;
+ transition: background-color 100ms;
+}
+.oo-ui-tool.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
+ -webkit-transition: color 100ms;
+ -moz-transition: color 100ms;
+ transition: color 100ms;
+}
.oo-ui-popupTool .oo-ui-popupWidget-popup,
.oo-ui-popupTool .oo-ui-popupWidget-anchor {
z-index: 4;
/* @noflip */
margin-left: 1.25em;
}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup {
- border: 0;
- border-radius: 0;
- margin: 0;
-}
.oo-ui-toolGroupTool > .oo-ui-toolGroup {
border-right: 0;
}
.oo-ui-toolGroup {
display: inline-block;
vertical-align: middle;
- border-right: 1px solid #cccccc;
- border-radius: 0;
+ border-right: 1px solid #c8ccd1;
}
.oo-ui-toolGroup-empty {
display: none;
outline: 0;
cursor: default;
}
+.oo-ui-toolbar-actions .oo-ui-toolGroup {
+ border-right: 0;
+ border-left: 1px solid #9aa0a7;
+}
.oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
margin-left: 0;
}
line-height: 2.1;
padding: 0 0.4em;
}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
- color: #555555;
-}
.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
- background-color: #eeeeee;
+ background-color: #eaecf0;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled > .oo-ui-tool-link .oo-ui-tool-title {
+ color: #222;
+ -webkit-transition: color 100ms;
+ -moz-transition: color 100ms;
+ transition: color 100ms;
}
.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled.oo-ui-tool-active {
- background-color: #e5e5e5;
+ background-color: #eaf3ff;
box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
}
.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled.oo-ui-tool-active:hover {
- background-color: #eeeeee;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled.oo-ui-tool-active:active {
- background-color: #e5e5e5;
+ background-color: rgba(41, 98, 204, 0.1);
}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
- opacity: 0.7;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover > .oo-ui-tool-link .oo-ui-iconElement-icon {
- opacity: 0.9;
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled.oo-ui-tool-active > .oo-ui-tool-link .oo-ui-tool-title {
+ color: #36c;
}
.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title,
.oo-ui-barToolGroup.oo-ui-widget-disabled .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon,
.oo-ui-barToolGroup.oo-ui-widget-disabled .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
- opacity: 0.2;
+ opacity: 0.3;
}
.oo-ui-popupToolGroup {
position: relative;
.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
margin-right: 1.75em;
}
+.oo-ui-popupToolGroup-header {
+ line-height: 2.6;
+ margin: 0 0.6em;
+ font-weight: bold;
+}
.oo-ui-popupToolGroup-handle {
padding: 0.3125em;
height: 2.5em;
.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
left: 0;
}
-.oo-ui-popupToolGroup.oo-ui-widget-enabled .oo-ui-popupToolGroup-handle:hover {
- background-color: #eeeeee;
-}
-.oo-ui-popupToolGroup.oo-ui-widget-enabled .oo-ui-popupToolGroup-handle:active {
- background-color: #e5e5e5;
-}
-.oo-ui-popupToolGroup-header {
- line-height: 2.6;
- margin: 0 0.6em;
- font-weight: bold;
-}
-.oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
- box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
- background-color: #eeeeee;
-}
.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
top: 3.125em;
margin: 0 -1px;
- border: 1px solid #cccccc;
- background-color: #ffffff;
+ border: 1px solid #9aa0a7;
+ background-color: #fff;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
min-width: 16em;
}
width: 1.875em;
min-width: 1.875em;
}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
- padding-left: 0.5em;
- color: #555555;
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title,
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
+ line-height: 2;
}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
- line-height: 2;
+ padding-left: 0.5em;
+ color: #222;
}
.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
- color: #888888;
+ color: #888;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled {
+ -webkit-transition: background-color 100ms, box-shadow 100ms;
+ -moz-transition: background-color 100ms, box-shadow 100ms;
+ transition: background-color 100ms, box-shadow 100ms;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled.oo-ui-popupToolGroup-active {
+ box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+ background-color: #eaecf0;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled.oo-ui-popupToolGroup-active .oo-ui-tool-active.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
+ color: #36c;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled-handle:hover {
+ background-color: #eaecf0;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled-handle:active {
+ background-color: #eaf3ff;
}
.oo-ui-listToolGroup .oo-ui-tool {
display: block;
box-sizing: border-box;
}
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
- background-color: #eeeeee;
+ background-color: #eaecf0;
}
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
opacity: 0.9;
}
.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
+ background-color: #eaf3ff;
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:first-child {
box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
- background-color: #e5e5e5;
}
.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
- background-color: #eeeeee;
+ background-color: rgba(41, 98, 204, 0.1);
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
+ color: #36c;
}
.oo-ui-listToolGroup.oo-ui-widget-disabled,
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-title,
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-accel {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon,
.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-iconElement-icon {
- opacity: 0.2;
+ opacity: 0.3;
}
.oo-ui-menuToolGroup .oo-ui-tool {
display: block;
background-image: none;
}
.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
- background-image: url("themes/mediawiki/images/icons/check.png");
- background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check.svg");
- background-image: linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check.svg");
- background-image: -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check.png");
+ background-image: url('themes/mediawiki/images/icons/check-progressive.png');
+ background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-progressive.svg');
+ background-image: linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-progressive.svg');
+ background-image: -o-linear-gradient(transparent, transparent), url('themes/mediawiki/images/icons/check-progressive.png');
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
}
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
- background-color: #eeeeee;
+ background-color: rgba(41, 98, 204, 0.1);
+}
+.oo-ui-menuToolGroup .oo-ui-tool-name-menuTool.oo-ui-tool-active {
+ background-color: #eaf3ff;
}
.oo-ui-menuToolGroup.oo-ui-widget-disabled,
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-title {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon,
.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-iconElement-icon {
- opacity: 0.2;
+ opacity: 0.3;
}
.oo-ui-toolbar {
clear: both;
line-height: 1;
position: relative;
}
-.oo-ui-toolbar-actions {
- float: right;
-}
-.oo-ui-toolbar-actions .oo-ui-toolbar {
- display: inline-block;
+.oo-ui-toolbar-tools,
+.oo-ui-toolbar-actions,
+.oo-ui-toolbar-shadow {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
}
.oo-ui-toolbar-tools {
display: inline;
.oo-ui-toolbar-tools .oo-ui-tool {
white-space: normal;
}
-.oo-ui-toolbar-tools,
-.oo-ui-toolbar-actions,
-.oo-ui-toolbar-shadow {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
+.oo-ui-toolbar-actions {
+ float: right;
+}
+.oo-ui-toolbar-actions .oo-ui-toolbar {
+ display: inline-block;
}
.oo-ui-toolbar-actions .oo-ui-popupWidget {
-webkit-touch-callout: default;
pointer-events: none;
}
.oo-ui-toolbar-bar {
- border-bottom: 1px solid #cccccc;
- background-color: #ffffff;
+ border-bottom: 1px solid #c8ccd1;
+ background-color: #fff;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
font-weight: 500;
- color: #555555;
+ color: #222;
}
.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
- border: 0;
- background: none;
+ border-bottom: 0;
+ background-color: transparent;
box-shadow: none;
}
.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement {
.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
border: 0;
border-radius: 0;
- margin: 0;
padding: 0 0.3125em;
}
.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
margin: 0 1em;
line-height: 3.125em;
}
+.oo-ui-toolbar-actions > .oo-ui-toolbar:not( :last-child ) {
+ border-right: 1px solid #9aa0a7;
+}
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:48Z
+ * Date: 2016-09-13T18:30:02Z
*/
( function ( OO ) {
this.active = !!state;
if ( this.active ) {
this.$element.addClass( 'oo-ui-tool-active' );
+ this.setFlags( 'progressive' );
} else {
this.$element.removeClass( 'oo-ui-tool-active' );
+ this.clearFlags();
}
};
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
.oo-ui-draggableElement-handle,
.oo-ui-draggableElement-handle.oo-ui-widget {
padding: 1.5em;
}
.oo-ui-bookletLayout-outlinePanel {
- border-right: 1px solid #dddddd;
+ border-right: 1px solid #ddd;
}
.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
padding: 0;
background-color: transparent;
}
+.oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
+ cursor: default;
+}
.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
position: static;
background-color: transparent;
}
.oo-ui-toggleButtonWidget {
- display: inline-block;
- vertical-align: middle;
margin-right: 0.5em;
}
.oo-ui-toggleButtonWidget:last-child {
height: 2em;
width: 4em;
border-radius: 1em;
- box-shadow: 0 0 0 #ffffff, inset 0 0.1em 0.2em #dddddd;
- border: 1px solid #cccccc;
+ box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
+ border: 1px solid #ccc;
margin-right: 0.5em;
- background-color: #eeeeee;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #dddddd), color-stop(100%, #ffffff));
- background-image: -webkit-linear-gradient(top, #dddddd 0, #ffffff 100%);
- background-image: -moz-linear-gradient(top, #dddddd 0, #ffffff 100%);
- background-image: linear-gradient(to bottom, #dddddd 0, #ffffff 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
+ background-color: #eee;
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
+ background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
+ background-image: -moz-linear-gradient(top, #ddd 0, #fff 100%);
+ background-image: linear-gradient(to bottom, #ddd 0, #fff 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffdddddd\', endColorstr=\'#ffffffff\' )';
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
cursor: pointer;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover,
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
- border-color: #aaaaaa;
+ border-color: #aaa;
}
.oo-ui-toggleSwitchWidget-grip {
top: 0.25em;
-webkit-transition: left 250ms ease, margin-left 250ms ease;
-moz-transition: left 250ms ease, margin-left 250ms ease;
transition: left 250ms ease, margin-left 250ms ease;
- background-color: #eeeeee;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #dddddd));
- background-image: -webkit-linear-gradient(top, #ffffff 0, #dddddd 100%);
- background-image: -moz-linear-gradient(top, #ffffff 0, #dddddd 100%);
- background-image: linear-gradient(to bottom, #ffffff 0, #dddddd 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+ background-color: #eee;
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
+ background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
+ background-image: -moz-linear-gradient(top, #fff 0, #ddd 100%);
+ background-image: linear-gradient(to bottom, #fff 0, #ddd 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#ffdddddd\' )';
}
.oo-ui-toggleSwitchWidget-glow {
position: absolute;
background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
background-image: -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
background-image: linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffb0d9ee\', endColorstr=\'#ffeaf4fa\' )';
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
}
.oo-ui-selectFileWidget-selectButton {
display: table-cell;
- vertical-align: middle;
}
.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
position: relative;
overflow: hidden;
}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type="file"] {
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
position: absolute;
top: 0;
bottom: 0;
cursor: pointer;
padding-top: 100px;
}
-.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type="file"] {
+.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
display: none;
}
.oo-ui-selectFileWidget-info {
right: 0;
text-overflow: ellipsis;
}
-.oo-ui-selectFileWidget-fileType {
- display: none;
-}
.oo-ui-selectFileWidget-clearButton {
position: absolute;
z-index: 2;
}
.oo-ui-selectFileWidget-info {
height: 2.4em;
- background-color: #ffffff;
+ background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 0.25em 0 0 0.25em;
border-width: 1px 0 1px 1px;
white-space: nowrap;
text-overflow: ellipsis;
}
-.oo-ui-selectFileWidget-fileType {
- color: #888888;
- display: block;
- margin-top: 0.25em;
-}
.oo-ui-selectFileWidget-clearButton {
top: 0;
right: 0;
height: 2.3em;
}
.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
- color: #cccccc;
+ color: #ccc;
}
.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-label {
left: 2.475em;
background-color: #e1f3ff;
}
.oo-ui-selectFileWidget-dropTarget {
- background-color: #ffffff;
- border: 1px solid #aaaaaa;
+ background-color: #fff;
+ border: 1px solid #aaa;
vertical-align: middle;
border-radius: 0.25em;
}
.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
background-color: #f3f3f3;
- color: #cccccc;
- border-color: #dddddd;
- text-shadow: 0 1px 1px #ffffff;
+ color: #ccc;
+ border-color: #ddd;
+ text-shadow: 0 1px 1px #fff;
}
.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info {
background-color: #f3f3f3;
- color: #cccccc;
- border-color: #dddddd;
- text-shadow: 0 1px 1px #ffffff;
+ color: #ccc;
+ border-color: #ddd;
+ text-shadow: 0 1px 1px #fff;
}
.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
opacity: 0.2;
}
.oo-ui-outlineOptionWidget {
- position: relative;
- cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
opacity: 0.5;
}
.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
- color: #777777;
+ color: #777;
}
.oo-ui-outlineControlsWidget {
height: 3em;
- background-color: #ffffff;
+ background-color: #fff;
}
.oo-ui-outlineControlsWidget-items,
.oo-ui-outlineControlsWidget-movers {
text-align: left;
white-space: nowrap;
overflow: hidden;
- background-color: #eeeeee;
+ background-color: #eee;
box-shadow: inset 0 -0.015em 0.1em rgba(0, 0, 0, 0.1);
}
.oo-ui-tabOptionWidget {
}
.oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
background-color: rgba(255, 255, 255, 0.2);
- border-color: #dddddd;
+ border-color: #ddd;
}
.oo-ui-tabOptionWidget.oo-ui-widget-enabled:active {
- background-color: #ffffff;
- border-color: #dddddd;
+ background-color: #fff;
+ border-color: #ddd;
}
.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
.oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
- background-color: #ffffff;
- border-color: #dddddd;
+ background-color: #fff;
+ border-color: #ddd;
}
.oo-ui-capsuleMultiselectWidget {
display: inline-block;
display: inline;
}
.oo-ui-capsuleMultiselectWidget-handle {
- background-color: #ffffff;
+ background-color: #fff;
cursor: text;
min-height: 2.4em;
margin-right: 0.5em;
font-size: inherit;
font-family: inherit;
background-color: transparent;
- color: #000000;
+ color: #000;
vertical-align: middle;
}
.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
border-color: rgba(0, 0, 0, 0.2);
}
.oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle {
- color: #cccccc;
- text-shadow: 0 1px 1px #ffffff;
- border-color: #dddddd;
+ color: #ccc;
+ text-shadow: 0 1px 1px #fff;
+ border-color: #ddd;
background-color: #f3f3f3;
cursor: default;
}
margin: 0.1em;
height: 1.7em;
line-height: 1.7em;
- background-color: #eeeeee;
- background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #dddddd));
- background-image: -webkit-linear-gradient(top, #ffffff 0, #dddddd 100%);
- background-image: -moz-linear-gradient(top, #ffffff 0, #dddddd 100%);
- background-image: linear-gradient(to bottom, #ffffff 0, #dddddd 100%);
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
- border: 1px solid #cccccc;
- color: #555555;
+ background-color: #eee;
+ background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
+ background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
+ background-image: -moz-linear-gradient(top, #fff 0, #ddd 100%);
+ background-image: linear-gradient(to bottom, #fff 0, #ddd 100%);
+ -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#ffdddddd\' )';
+ border: 1px solid #ccc;
+ color: #555;
border-radius: 0.25em;
}
.oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
opacity: 0.5;
-webkit-transform: translate3d(0, 0, 0);
box-shadow: none;
- color: #333333;
- background: #eeeeee;
- border-color: #cccccc;
+ color: #333;
+ background: #eee;
+ border-color: #ccc;
}
.oo-ui-capsuleItemWidget > .oo-ui-buttonElement {
margin-top: -1.25em;
position: relative;
max-width: 50em;
}
-.oo-ui-numberInputWidget-field {
- display: table;
- table-layout: fixed;
- width: 100%;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget,
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
+.oo-ui-numberInputWidget-buttoned .oo-ui-buttonWidget,
+.oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget {
display: table-cell;
- vertical-align: middle;
}
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
- width: 100%;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
- white-space: nowrap;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget > .oo-ui-buttonElement-button {
+.oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
+.oo-ui-numberInputWidget-field {
+ display: table;
+ table-layout: fixed;
+ width: 100%;
+}
.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
width: 2.25em;
}
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
.oo-ui-draggableElement-handle,
.oo-ui-draggableElement-handle.oo-ui-widget {
padding: 1.5em;
}
.oo-ui-bookletLayout-outlinePanel {
- border-right: 1px solid #dddddd;
+ border-right: 1px solid #ddd;
}
.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
border-top-right-radius: 2px;
}
.oo-ui-buttonSelectWidget.oo-ui-widget-enabled:focus .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected .oo-ui-buttonElement-button {
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
}
.oo-ui-buttonOptionWidget {
display: inline-block;
padding: 0;
}
+.oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
+ cursor: default;
+}
.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
position: static;
background-color: transparent;
}
.oo-ui-toggleButtonWidget {
- display: inline-block;
- vertical-align: middle;
margin-right: 0.5em;
}
.oo-ui-toggleButtonWidget:last-child {
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
+ background-color: #f8f9fa;
width: 3.5em;
min-height: 26px;
height: 2em;
- border: 1px solid #767676;
+ border: 1px solid #72777d;
border-radius: 1em;
- background-color: #ffffff;
margin-right: 0.5em;
- -webkit-transition: background-color 100ms, border-color 100ms;
- -moz-transition: background-color 100ms, border-color 100ms;
- transition: background-color 100ms, border-color 100ms;
+ -webkit-transition: background-color 250ms, border-color 250ms;
+ -moz-transition: background-color 250ms, border-color 250ms;
+ transition: background-color 250ms, border-color 250ms;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
cursor: pointer;
margin-right: 0;
}
.oo-ui-toggleSwitchWidget:before {
- content: "";
+ content: '';
display: block;
position: absolute;
top: 1px;
border: 1px solid transparent;
border-radius: 1em;
z-index: 1;
- -webkit-transition: border-color 100ms;
- -moz-transition: border-color 100ms;
- transition: border-color 100ms;
+ -webkit-transition: border-color 250ms;
+ -moz-transition: border-color 250ms;
+ transition: border-color 250ms;
}
.oo-ui-toggleSwitchWidget-grip {
top: 0.3125em;
min-height: 16px;
height: 1.25em;
border-radius: 1.25em;
- -webkit-transition: left 100ms, margin-left 100ms;
- -moz-transition: left 100ms, margin-left 100ms;
- transition: left 100ms, margin-left 100ms;
+ -webkit-transition: background-color 250ms, left 100ms, margin-left 100ms;
+ -moz-transition: background-color 250ms, left 100ms, margin-left 100ms;
+ transition: background-color 250ms, left 100ms, margin-left 100ms;
}
.oo-ui-toggleSwitchWidget-glow {
display: none;
margin-left: -2px;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled .oo-ui-toggleSwitchWidget-grip {
- border: 1px solid #767676;
+ background-color: #f8f9fa;
+ border: 1px solid #72777d;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover {
- border-color: #2962cc;
+ background-color: #fff;
+ border-color: #447ff5;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
- border-color: #2962cc;
+ background-color: #fff;
+ border-color: #447ff5;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active,
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover {
- background-color: #767676;
- border-color: #347bff;
+ background-color: #36c;
+ border-color: #2a4b8d;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active .oo-ui-toggleSwitchWidget-grip,
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover .oo-ui-toggleSwitchWidget-grip {
- background-color: #ffffff;
- border-color: #ffffff;
+ background-color: #fff;
+ border-color: #fff;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus {
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
outline: 0;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus .oo-ui-toggleSwitchWidget-grip {
- border-color: #347bff;
+ border-color: #36c;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on {
- background-color: #347bff;
- border-color: #347bff;
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
- background-color: #ffffff;
- border-color: #ffffff;
+ background-color: #fff;
+ border-color: #fff;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:hover {
- background-color: #2962cc;
- border-color: #2962cc;
+ background-color: #36c;
+ border-color: #36c;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:active,
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:active:hover {
- background-color: #1f4999;
- border-color: #1f4999;
+ background-color: #2a4b8d;
+ border-color: #2a4b8d;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:focus {
- border-color: #347bff;
+ border-color: #36c;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:focus:before {
- border-color: #ffffff;
+ border-color: #fff;
}
.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
- background-color: #dddddd;
- border-color: #dddddd;
+ background-color: #c8ccd1;
+ border-color: #c8ccd1;
outline: 0;
}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled .oo-ui-toggleSwitchWidget-grip {
- background-color: #ffffff;
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
+ border: 1px solid #fff;
+ box-shadow: inset 0 0 0 1px #fff;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
+ background-color: #fff;
}
.oo-ui-selectFileWidget {
display: inline-block;
}
.oo-ui-selectFileWidget-selectButton {
display: table-cell;
- vertical-align: middle;
}
.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
position: relative;
overflow: hidden;
}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type="file"] {
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
position: absolute;
top: 0;
bottom: 0;
cursor: pointer;
padding-top: 100px;
}
-.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type="file"] {
+.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
display: none;
}
.oo-ui-selectFileWidget-info {
right: 0;
text-overflow: ellipsis;
}
-.oo-ui-selectFileWidget-fileType {
- display: none;
-}
.oo-ui-selectFileWidget-clearButton {
position: absolute;
z-index: 2;
}
.oo-ui-selectFileWidget-info {
height: 2.4em;
- background-color: #ffffff;
- border: 1px solid #cccccc;
+ background-color: #fff;
+ border: 1px solid #9aa0a7;
border-radius: 2px 0 0 2px;
border-width: 1px 0 1px 1px;
}
text-overflow: ellipsis;
padding-left: 0.5em;
}
-.oo-ui-selectFileWidget-fileType {
- color: #888888;
- display: block;
- margin-top: 0.25em;
-}
.oo-ui-selectFileWidget-clearButton {
top: 0;
right: 0;
height: 2.3em;
}
.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
- color: #cccccc;
+ color: #72777d;
}
.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-label {
left: 2.875em;
right: 2em;
}
.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget {
- background-color: #ebf2ff;
+ background-color: #eaf3ff;
}
.oo-ui-selectFileWidget-dropTarget {
- background-color: #ffffff;
- border: 1px solid #cccccc;
+ background-color: #fff;
+ border: 1px solid #9aa0a7;
vertical-align: middle;
overflow: hidden;
border-radius: 2px;
overflow: inherit;
white-space: normal;
}
-.oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget {
- background-color: #eeeeee;
+.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget {
+ background-color: #eee;
border-style: dashed;
}
.oo-ui-selectFileWidget.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
.oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
- background-color: #f3f3f3;
- border-color: #dddddd;
+ background-color: #eaecf0;
+ border-color: #c8ccd1;
}
.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info {
- background-color: #f3f3f3;
- color: #cccccc;
- border-color: #dddddd;
- text-shadow: 0 1px 1px #ffffff;
+ background-color: #eaecf0;
+ color: #72777d;
+ border-color: #c8ccd1;
+ text-shadow: 0 1px 1px #fff;
}
.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
.oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
- opacity: 0.2;
+ opacity: 0.51;
}
.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropLabel {
display: none;
}
.oo-ui-outlineOptionWidget {
- position: relative;
- cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
font-size: 1.1em;
padding: 0.75em;
+ -webkit-transition: background-color 100ms, color 100ms;
+ -moz-transition: background-color 100ms, color 100ms;
+ transition: background-color 100ms, color 100ms;
+}
+.oo-ui-outlineOptionWidget.oo-ui-optionWidget-highlighted {
+ background-color: #eaecf0;
+ color: #000;
+}
+.oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
+ background-color: #eaf3ff;
+ color: #36c;
+}
+.oo-ui-outlineOptionWidget.oo-ui-optionWidget-pressed {
+ background-color: rgba(41, 98, 204, 0.1);
+ color: #36c;
}
.oo-ui-outlineOptionWidget .oo-ui-iconElement-icon {
font-size: 90.90909%;
.oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
left: 4em;
}
-.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
- background-color: #d0d0d0;
- text-shadow: 0 1px 1px #ffffff;
-}
.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
font-weight: bold;
}
opacity: 0.5;
}
.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
- color: #777777;
+ color: #777;
}
.oo-ui-outlineControlsWidget {
height: 3em;
- background-color: #ffffff;
+ background-color: #fff;
}
.oo-ui-outlineControlsWidget-items,
.oo-ui-outlineControlsWidget-movers {
text-align: left;
white-space: nowrap;
overflow: hidden;
- background-color: #dddddd;
+ background-color: #ddd;
}
.oo-ui-tabOptionWidget {
display: inline-block;
border-bottom: 0;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
- color: #555555;
+ color: #222;
font-weight: bold;
}
.oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
.oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
- background-color: #ffffff;
- color: #333333;
+ background-color: #fff;
+ color: #333;
}
.oo-ui-capsuleMultiselectWidget {
display: inline-block;
min-height: 2.4em;
margin-right: 0.5em;
padding: 0.15em 0.25em;
- border: 1px solid #cccccc;
+ border: 1px solid #9aa0a7;
border-radius: 2px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
.oo-ui-capsuleMultiselectWidget-handle:last-child {
margin-right: 0;
}
+.oo-ui-capsuleMultiselectWidget-handle:hover {
+ border-color: #72777d;
+}
.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator,
.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
position: absolute;
font-size: inherit;
font-family: inherit;
background-color: transparent;
- color: #000000;
+ color: #000;
vertical-align: middle;
}
.oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
top: 0;
margin: 0.3em;
}
+.oo-ui-capsuleMultiselectWidget .oo-ui-popupWidget {
+ width: 100%;
+ margin-top: -1px;
+}
+.oo-ui-capsuleMultiselectWidget .oo-ui-popupWidget-popup {
+ min-width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ border-width: 0 1px;
+ border-radius: 0 0 2px 2px;
+}
.oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled .oo-ui-capsuleMultiselectWidget-handle {
- background-color: #ffffff;
+ background-color: #fff;
cursor: text;
- -webkit-transition: border-color 100ms;
- -moz-transition: border-color 100ms;
- transition: border-color 100ms;
+ -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+ -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+ transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
}
.oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled:hover .oo-ui-capsuleMultiselectWidget-handle {
- border-color: #aaaaaa;
+ border-color: #a2a9b1;
+}
+.oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled.oo-ui-capsuleMultiselectWidget-open .oo-ui-capsuleMultiselectWidget-handle {
+ border-color: #36c;
+ outline: 0;
+ box-shadow: inset 0 0 0 1px #36c;
}
.oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle {
- color: #cccccc;
- text-shadow: 0 1px 1px #ffffff;
- border-color: #dddddd;
- background-color: #f3f3f3;
+ color: #72777d;
+ text-shadow: 0 1px 1px #fff;
+ border-color: #c8ccd1;
+ background-color: #eaecf0;
+}
+.oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
+ opacity: 0.51;
}
-.oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon,
.oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
- opacity: 0.2;
+ opacity: 0.15;
}
.oo-ui-capsuleItemWidget {
position: relative;
vertical-align: middle;
height: 1.7em;
line-height: 1.7;
- background-color: #eeeeee;
- color: #555555;
+ background-color: #eee;
+ color: #222;
margin: 0.1em;
- border: 1px solid #cccccc;
+ border: 1px solid #9aa0a7;
border-radius: 2px;
padding: 0 0.4em;
}
}
.oo-ui-capsuleItemWidget:focus {
outline: 0;
- border-color: #347bff;
- box-shadow: inset 0 0 0 1px #347bff;
+ border-color: #36c;
+ box-shadow: inset 0 0 0 1px #36c;
}
.oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
- background-color: #f3f3f3;
- color: #cccccc;
- border-color: #dddddd;
- text-shadow: 0 1px 1px #ffffff;
+ background-color: #eaecf0;
+ color: #72777d;
+ border-color: #c8ccd1;
+ text-shadow: 0 1px 1px #fff;
}
.oo-ui-capsuleItemWidget > .oo-ui-buttonElement {
display: none;
.oo-ui-searchWidget-query {
height: 4em;
padding: 0 1em;
- border-bottom: 1px solid #cccccc;
+ border-bottom: 1px solid #9aa0a7;
}
.oo-ui-searchWidget-query .oo-ui-textInputWidget {
margin: 0.75em 0;
position: relative;
max-width: 50em;
}
-.oo-ui-numberInputWidget-field {
- display: table;
- table-layout: fixed;
- width: 100%;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget,
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
+.oo-ui-numberInputWidget-buttoned .oo-ui-buttonWidget,
+.oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget {
display: table-cell;
- vertical-align: middle;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
- width: 100%;
}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
- white-space: nowrap;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget > .oo-ui-buttonElement-button {
+.oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
+.oo-ui-numberInputWidget-field {
+ display: table;
+ table-layout: fixed;
+ width: 100%;
+}
+.oo-ui-numberInputWidget-buttoned .oo-ui-buttonWidget {
width: 2.5em;
}
+.oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button {
+ display: block;
+ padding-left: 0;
+ padding-right: 0;
+}
+.oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget input {
+ border-radius: 0;
+}
.oo-ui-numberInputWidget-minusButton.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
border-left-width: 0;
}
-.oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget input {
- border-radius: 0;
-}
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:48Z
+ * Date: 2016-09-13T18:30:02Z
*/
( function ( OO ) {
* };
*
* var card1 = new CardOneLayout( 'one' ),
- * card2 = new CardLayout( 'two', { label: 'Card two' } );
+ * card2 = new OO.ui.CardLayout( 'two', { label: 'Card two' } );
*
* card2.$element.append( '<p>Second card</p>' );
*
OO.ui.ToggleButtonWidget.parent.call( this, config );
// Mixin constructors
- OO.ui.mixin.ButtonElement.call( this, config );
+ OO.ui.mixin.ButtonElement.call( this, $.extend( {}, config, { active: this.active } ) );
OO.ui.mixin.IconElement.call( this, config );
OO.ui.mixin.IndicatorElement.call( this, config );
OO.ui.mixin.LabelElement.call( this, config );
/* Static Properties */
-OO.ui.OutlineOptionWidget.static.highlightable = false;
+OO.ui.OutlineOptionWidget.static.highlightable = true;
OO.ui.OutlineOptionWidget.static.scrollIntoViewOnSelect = true;
return this.level;
};
+/**
+ * @inheritdoc
+ */
+OO.ui.OutlineOptionWidget.prototype.setPressed = function ( state ) {
+ OO.ui.OutlineOptionWidget.parent.prototype.setPressed.call( this, state );
+ if ( this.constructor.static.pressable ) {
+ this.pressed = !!state;
+ if ( this.pressed ) {
+ this.setFlags( 'progressive' );
+ } else if ( !this.selected ) {
+ this.clearFlags();
+ }
+ }
+ return this;
+};
+
/**
* Set movability.
*
return this;
};
+/**
+ * @inheritdoc
+ */
+OO.ui.OutlineOptionWidget.prototype.setSelected = function ( state ) {
+ OO.ui.OutlineOptionWidget.parent.prototype.setSelected.call( this, state );
+ if ( this.constructor.static.selectable ) {
+ this.selected = !!state;
+ if ( this.selected ) {
+ this.setFlags( 'progressive' );
+ } else {
+ this.clearFlags();
+ }
+ }
+ return this;
+};
+
/**
* Set indentation level.
*
}
this.menu.connect( this, {
choose: 'onMenuChoose',
+ toggle: 'onMenuToggle',
add: 'onMenuItemsChange',
remove: 'onMenuItemsChange'
} );
}
};
+/**
+ * Handle menu toggle events.
+ *
+ * @private
+ * @param {boolean} isVisible Menu toggle event
+ */
+OO.ui.CapsuleMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
+ this.$element.toggleClass( 'oo-ui-capsuleMultiselectWidget-open', isVisible );
+};
+
/**
* Handle menu item change events.
*
.addClass( 'oo-ui-selectFileWidget-fileName' )
.text( this.currentFile.name )
);
- if ( this.currentFile.type !== '' ) {
- $label = $label.add(
- $( '<span>' )
- .addClass( 'oo-ui-selectFileWidget-fileType' )
- .text( this.currentFile.type )
- );
- }
this.setLabel( $label );
if ( this.showDropTarget ) {
return false;
}
- /*jshint bitwise: false */
+ /* eslint-disable no-bitwise */
if ( this.isInteger && ( n | 0 ) !== n ) {
return false;
}
- /*jshint bitwise: true */
+ /* eslint-enable no-bitwise */
if ( n < this.min || n > this.max ) {
return false;
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
.oo-ui-actionWidget.oo-ui-pendingElement-pending {
background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
.oo-ui-messageDialog-title {
font-size: 1.5em;
line-height: 1em;
- color: #000000;
+ color: #000;
}
.oo-ui-messageDialog-message {
font-size: 0.9em;
line-height: 1.25em;
- color: #666666;
+ color: #666;
}
.oo-ui-messageDialog-message-verbose {
font-size: 1.1em;
}
.oo-ui-processDialog-errors-title {
font-size: 1.5em;
- color: #000000;
+ color: #000;
margin-bottom: 2em;
}
.oo-ui-processDialog-error {
transition: opacity 250ms ease;
}
.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
- background-color: #ffffff;
+ background-color: #fff;
opacity: 0;
-webkit-transform: scale(0.5);
-moz-transform: scale(0.5);
bottom: 1em;
max-height: 100%;
max-height: calc(100% - 2em);
- border: 1px solid #cccccc;
+ border: 1px solid #ccc;
border-radius: 0.5em;
box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
}
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:53Z
+ * Date: 2016-09-13T18:30:06Z
*/
.oo-ui-window {
background: transparent;
white-space: nowrap;
}
.oo-ui-messageDialog-content > .oo-ui-window-foot {
- outline: 1px solid #aaaaaa;
+ outline: 1px solid #aaa;
}
.oo-ui-messageDialog-title,
.oo-ui-messageDialog-message {
.oo-ui-messageDialog-title {
font-size: 1.5em;
line-height: 1;
- color: #000000;
+ color: #000;
}
.oo-ui-messageDialog-message {
font-size: 0.9em;
line-height: 1.25;
- color: #555555;
+ color: #222;
}
.oo-ui-messageDialog-message-verbose {
font-size: 1.1em;
text-align: left;
}
.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
- border-right: 1px solid #cccccc;
+ border-right: 1px solid #9aa0a7;
margin: 0;
}
.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
border-right-width: 0;
}
.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
- border-bottom: 1px solid #cccccc;
+ border-bottom: 1px solid #9aa0a7;
margin: 0;
}
.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
}
.oo-ui-processDialog-errors-title {
font-size: 1.5em;
- color: #000000;
+ color: #000;
margin-bottom: 2em;
}
.oo-ui-processDialog-error {
transition: opacity 250ms;
}
.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
- background-color: #ffffff;
+ background-color: #fff;
opacity: 0;
-webkit-transform: scale(0.5);
-moz-transform: scale(0.5);
bottom: 1em;
max-height: 100%;
max-height: calc(100% - 2em);
- border: 1px solid #aaaaaa;
+ border: 1px solid #a2a9b1;
border-radius: 2px;
box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
}
/*!
- * OOjs UI v0.17.8
+ * OOjs UI v0.17.9
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2016 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2016-08-16T21:13:48Z
+ * Date: 2016-09-13T18:30:02Z
*/
( function ( OO ) {
return this;
};
+/* eslint-disable no-unused-vars */
/**
* ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that comprise them.
* Actions can be made available for specific contexts (modes) and circumstances
this.changing = false;
this.changed = false;
};
+/* eslint-enable no-unused-vars */
/* Setup */
$body = $( this.getElementDocument().body ),
// We could have multiple window managers open so only modify
// the body css at the bottom of the stack
- stackDepth = $body.data( 'windowManagerGlobalEvents' ) || 0 ;
+ stackDepth = $body.data( 'windowManagerGlobalEvents' ) || 0;
on = on === undefined ? !!this.globalEvents : !!on;
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
},
"progressive": {
- "color": "#347bff"
+ "color": "#36c",
+ "global": true
},
"constructive": {
- "color": "#347bff"
+ "color": "#36c"
},
"destructive": {
- "color": "#d11d13"
+ "color": "#c33"
},
"warning": {
"color": "#ff5d00"
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
},
"progressive": {
- "color": "#347bff"
+ "color": "#36c",
+ "global": true
},
"constructive": {
- "color": "#347bff"
+ "color": "#36c"
},
"destructive": {
- "color": "#d11d13"
+ "color": "#c33"
},
"warning": {
"color": "#ff5d00"
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
},
"progressive": {
- "color": "#347bff"
+ "color": "#36c",
+ "global": true
},
"constructive": {
- "color": "#347bff"
+ "color": "#36c"
},
"destructive": {
- "color": "#d11d13"
+ "color": "#c33"
},
"warning": {
"color": "#ff5d00"
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#FFFFFF",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
},
"progressive": {
- "color": "#347bff"
+ "color": "#36c",
+ "global": true
},
"constructive": {
- "color": "#347bff"
- },
- "constructive-deprecated": {
- "color": "#00af89"
+ "color": "#36c"
},
"destructive": {
- "color": "#d11d13"
+ "color": "#c33"
},
"warning": {
"color": "#ff5d00"
"advanced": { "file": "images/icons/advanced.svg" },
"alert": { "file": "images/icons/alert.svg", "variants": [ "warning" ] },
"cancel": { "file": "images/icons/cancel.svg", "variants": [ "destructive" ] },
- "check": { "file": "images/icons/check.svg", "variants": [ "constructive-deprecated", "constructive", "progressive", "destructive" ] },
- "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive-deprecated", "constructive", "progressive" ] },
+ "check": { "file": "images/icons/check.svg", "variants": [ "constructive", "progressive", "destructive" ] },
+ "circle": { "file": "images/icons/circle.svg", "variants": [ "constructive", "progressive" ] },
"close": { "file": {
"ltr": "images/icons/close-ltr.svg",
"rtl": "images/icons/close-rtl.svg"
"rtl": "images/icons/search-rtl.svg"
} },
"settings": { "file": "images/icons/settings.svg" },
- "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive", "progressive" ] },
+ "tag": { "file": "images/icons/tag.svg", "variants": [ "destructive", "warning", "constructive" ] },
"undo": { "file": {
"ltr": "images/icons/arched-arrow-rtl.svg",
"rtl": "images/icons/arched-arrow-ltr.svg"
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<g id="add">
<path id="plus" d="M13 6h-2v5H6v2h5v5h2v-5h5v-2h-5z"/>
</g>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="add">
<path id="plus" d="M13 6h-2v5H6v2h5v5h2v-5h5v-2h-5z"/>
</g>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<g id="add">
<path id="plus" d="M13 6h-2v5H6v2h5v5h2v-5h5v-2h-5z"/>
</g>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20 13.44v-2.88l-1.8-.3c-.1-.397-.3-.794-.6-1.39l1.1-1.49-2.1-2.088-1.5 1.093c-.5-.298-1-.497-1.4-.596L13.5 4h-2.9l-.3 1.79c-.5.098-.9.297-1.4.595L7.4 5.292 5.3 7.38l1 1.49c-.3.496-.4.894-.6 1.39l-1.7.2v2.882l1.8.298c.1.497.3.894.6 1.39l-1 1.492 2.1 2.087 1.5-1c.4.2.9.395 1.4.594l.3 1.79h3l.3-1.79c.5-.1.9-.298 1.4-.596l1.5 1.092 2.1-2.08-1.1-1.49c.3-.496.5-.993.6-1.39l1.5-.3zm-8 1.492c-1.7 0-3-1.292-3-2.982 0-1.69 1.3-2.98 3-2.98s3 1.29 3 2.98-1.3 2.982-3 2.982z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20 13.44v-2.88l-1.8-.3c-.1-.397-.3-.794-.6-1.39l1.1-1.49-2.1-2.088-1.5 1.093c-.5-.298-1-.497-1.4-.596L13.5 4h-2.9l-.3 1.79c-.5.098-.9.297-1.4.595L7.4 5.292 5.3 7.38l1 1.49c-.3.496-.4.894-.6 1.39l-1.7.2v2.882l1.8.298c.1.497.3.894.6 1.39l-1 1.492 2.1 2.087 1.5-1c.4.2.9.395 1.4.594l.3 1.79h3l.3-1.79c.5-.1.9-.298 1.4-.596l1.5 1.092 2.1-2.08-1.1-1.49c.3-.496.5-.993.6-1.39l1.5-.3zm-8 1.492c-1.7 0-3-1.292-3-2.982 0-1.69 1.3-2.98 3-2.98s3 1.29 3 2.98-1.3 2.982-3 2.982z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="alert">
<path id="point" d="M11 16h2v2h-2z"/>
<path id="stroke" d="M13.516 10h-3L11 15h2z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="alert">
+ <path id="point" d="M11 16h2v2h-2z"/>
+ <path id="stroke" d="M13.516 10h-3L11 15h2z"/>
+ <path id="triangle" d="M12.017 5.974L19.537 19H4.497l7.52-13.026m0-2.474c-.545 0-1.09.357-1.5 1.07L2.53 18.403C1.705 19.833 2.38 21 4.03 21H20c1.65 0 2.325-1.17 1.5-2.6L13.517 4.575c-.413-.715-.956-1.072-1.5-1.072z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9 9h6c.554 0 1 .446 1 1v5c0 .554-.446 1-1 1H9c-.554 0-1-.446-1-1v-5c0-.554.446-1 1-1zm-5.5 9h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1zm0-12h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1z" id="align-center"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9 9h6c.554 0 1 .446 1 1v5c0 .554-.446 1-1 1H9c-.554 0-1-.446-1-1v-5c0-.554.446-1 1-1zm-5.5 9h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1zm0-12h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1z" id="align-center"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M4 9h6c.554 0 1 .446 1 1v5c0 .554-.446 1-1 1H4c-.554 0-1-.446-1-1v-5c0-.554.446-1 1-1zm9.5 0h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm0 3h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm0 3h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm-10-9h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1zm0 12h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1z" id="align-float-left"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M4 9h6c.554 0 1 .446 1 1v5c0 .554-.446 1-1 1H4c-.554 0-1-.446-1-1v-5c0-.554.446-1 1-1zm9.5 0h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm0 3h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm0 3h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm-10-9h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1zm0 12h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1z" id="align-float-left"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20 9h-6c-.554 0-1 .446-1 1v5c0 .554.446 1 1 1h6c.554 0 1-.446 1-1v-5c0-.554-.446-1-1-1zm-9.5 0h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm0 3h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm0 3h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm10-9h-17a.5.5 0 0 0 0 1h17a.5.5 0 0 0 0-1zm0 12h-17a.5.5 0 0 0 0 1h17a.5.5 0 0 0 0-1z" id="align-float-right"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20 9h-6c-.554 0-1 .446-1 1v5c0 .554.446 1 1 1h6c.554 0 1-.446 1-1v-5c0-.554-.446-1-1-1zm-9.5 0h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm0 3h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm0 3h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm10-9h-17a.5.5 0 0 0 0 1h17a.5.5 0 0 0 0-1zm0 12h-17a.5.5 0 0 0 0 1h17a.5.5 0 0 0 0-1z" id="align-float-right"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M13.3 6.3l6.3 5.7-6.3 5.7v-3.8H12c-3.2 0-6.3 1.3-7.6 3.8 0-4.7 2.8-7.6 7.9-7.6h.9V6.3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M13.3 6.3l6.3 5.7-6.3 5.7v-3.8H12c-3.2 0-6.3 1.3-7.6 3.8 0-4.7 2.8-7.6 7.9-7.6h.9V6.3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M10.7 6.3L4.4 12l6.3 5.7v-3.8H12c3.2 0 6.3 1.3 7.6 3.8 0-4.7-2.8-7.6-7.9-7.6h-.9V6.3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M10.7 6.3L4.4 12l6.3 5.7v-3.8H12c3.2 0 6.3 1.3 7.6 3.8 0-4.7-2.8-7.6-7.9-7.6h-.9V6.3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 12H6c-1.7 0-3 1.3-3 3h13v3l5-4.5L16 9v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 12H6c-1.7 0-3 1.3-3 3h13v3l5-4.5L16 9v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M8 12h10c1.7 0 3 1.3 3 3H8v3l-5-4.5L8 9v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M8 12h10c1.7 0 3 1.3 3 3H8v3l-5-4.5L8 9v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 10h4V5h-4v5zm-5 2h9v-1H7v1zm0 2h9v-1H7v1zm0 2h9v-1H7v1zm4-9H7v1h4V7zm0 2H7v1h4V9zm0-4H7v1h4V5zM5 3h13v16H8c-1.7 0-3-1.3-3-3V3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 10h4V5h-4v5zm-5 2h9v-1H7v1zm0 2h9v-1H7v1zm0 2h9v-1H7v1zm4-9H7v1h4V7zm0 2H7v1h4V9zm0-4H7v1h4V5zM5 3h13v16H8c-1.7 0-3-1.3-3-3V3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M11 10H7V5h4v5zm5 2H7v-1h9v1zm0 2H7v-1h9v1zm0 2H7v-1h9v1zm-4-9h4v1h-4V7zm0 2h4v1h-4V9zm0-4h4v1h-4V5zm6-2H5v16h10c1.7 0 3-1.3 3-3V3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M11 10H7V5h4v5zm5 2H7v-1h9v1zm0 2H7v-1h9v1zm0 2H7v-1h9v1zm-4-9h4v1h-4V7zm0 2h4v1h-4V9zm0-4h4v1h-4V5zm6-2H5v16h10c1.7 0 3-1.3 3-3V3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 11l-6 7-4-4-1 1 5 5 7-8z"/>
<path d="M17 14V3H4v13c0 1.7 1.3 3 3 3h5l-3-3H6v-1h2.6l1-1H6v-1h9v1h-2l1 1h2l1-1zM6 5h4v1H6V5zm0 2h4v1H6V7zm0 2h4v1H6V9zm9 3H6v-1h9v1zm-4-2V5h4v5h-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 11l-6 7-4-4-1 1 5 5 7-8z"/>
+ <path d="M17 14V3H4v13c0 1.7 1.3 3 3 3h5l-3-3H6v-1h2.6l1-1H6v-1h9v1h-2l1 1h2l1-1zM6 5h4v1H6V5zm0 2h4v1H6V7zm0 2h4v1H6V9zm9 3H6v-1h9v1zm-4-2V5h4v5h-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M5 11l6 7 4-4 1 1-5 5-7-8z"/>
<path d="M9 14V3h13v13c0 1.7-1.3 3-3 3h-5l3-3h3v-1h-2.6l-1-1H20v-1h-9v1h2l-1 1h-2l-1-1zm11-9h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm-9 3h9v-1h-9v1zm4-2V5h-4v5h4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M5 11l6 7 4-4 1 1-5 5-7-8z"/>
+ <path d="M9 14V3h13v13c0 1.7-1.3 3-3 3h-5l3-3h3v-1h-2.6l-1-1H20v-1h-9v1h2l-1 1h-2l-1-1zm11-9h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm-9 3h9v-1h-9v1zm4-2V5h-4v5h4z"/>
+</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="article-redirect">
<path id="arrow" d="M18.1 14.2L23 18l-4.9 4.8v-2.2c-1.7 0-2.9-.2-4.3-1.2-1.2-.8-2.5-2.6-2.3-4.1 1.4 1 2.9 1.5 4.4 1.5.7 0 1.4-.1 2.1-.3l.1-2.3"/>
<path id="page" d="M5 3v13c0 1.7 1.3 3 3 3h3.375c-.157-.205-.3-.43-.438-.656-.42-.688-.77-1.483-.843-2.344H7v-1h3.125l.125-1H7v-1h3.375l.03-.188.283.188H16v1h-3.906l.22.156c.523.375 1.065.64 1.592.844H16v.406c.208-.013.418-.07.625-.094.068-1.294.125-3.874.125-3.874l1.25.968V3H5zm2 2h4v1H7V5zm5 0h4v5h-4V5zM7 7h4v1H7V7zm0 2h4v1H7V9zm0 2h9v1H7v-1z"/>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="article-redirect">
+ <path id="arrow" d="M18.1 14.2L23 18l-4.9 4.8v-2.2c-1.7 0-2.9-.2-4.3-1.2-1.2-.8-2.5-2.6-2.3-4.1 1.4 1 2.9 1.5 4.4 1.5.7 0 1.4-.1 2.1-.3l.1-2.3"/>
+ <path id="page" d="M5 3v13c0 1.7 1.3 3 3 3h3.375c-.157-.205-.3-.43-.438-.656-.42-.688-.77-1.483-.843-2.344H7v-1h3.125l.125-1H7v-1h3.375l.03-.188.283.188H16v1h-3.906l.22.156c.523.375 1.065.64 1.592.844H16v.406c.208-.013.418-.07.625-.094.068-1.294.125-3.874.125-3.874l1.25.968V3H5zm2 2h4v1H7V5zm5 0h4v5h-4V5zM7 7h4v1H7V7zm0 2h4v1H7V9zm0 2h9v1H7v-1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="article-redirect">
<path id="arrow" d="M5.9 14.2L1 18l4.9 4.8v-2.2c1.7 0 2.9-.2 4.3-1.2 1.2-.8 2.5-2.6 2.3-4.1-1.4 1-2.9 1.5-4.4 1.5-.7 0-1.4-.1-2.1-.3l-.1-2.3"/>
<path id="page" d="M19 3v13c0 1.7-1.3 3-3 3h-3.375c.157-.205.3-.43.438-.656.42-.688.77-1.483.843-2.344H17v-1h-3.125l-.125-1H17v-1h-3.375l-.03-.188-.283.188H8v1h3.906l-.22.156a7.097 7.097 0 0 1-1.592.844H8v.406c-.208-.013-.418-.07-.625-.094a178.903 178.903 0 0 1-.125-3.874L6 12.405V3zm-2 2h-4v1h4zm-5 0H8v5h4zm5 2h-4v1h4zm0 2h-4v1h4zm0 2H8v1h9z"/>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="article-redirect">
+ <path id="arrow" d="M5.9 14.2L1 18l4.9 4.8v-2.2c1.7 0 2.9-.2 4.3-1.2 1.2-.8 2.5-2.6 2.3-4.1-1.4 1-2.9 1.5-4.4 1.5-.7 0-1.4-.1-2.1-.3l-.1-2.3"/>
+ <path id="page" d="M19 3v13c0 1.7-1.3 3-3 3h-3.375c.157-.205.3-.43.438-.656.42-.688.77-1.483.843-2.344H17v-1h-3.125l-.125-1H17v-1h-3.375l-.03-.188-.283.188H8v1h3.906l-.22.156a7.097 7.097 0 0 1-1.592.844H8v.406c-.208-.013-.418-.07-.625-.094a178.903 178.903 0 0 1-.125-3.874L6 12.405V3zm-2 2h-4v1h4zm-5 0H8v5h4zm5 2h-4v1h4zm0 2h-4v1h4zm0 2H8v1h9z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M19.1 18.5c.6-.7.9-1.5.9-2.5 0-2.2-1.8-4-4-4s-4 1.8-4 4 1.8 4 4 4c.7 0 1.3-.1 1.8-.4l2.7 2.7 1.1-1.1-2.5-2.7zm-3.1-.3c-1.2 0-2.2-1-2.2-2.3 0-1.2 1-2.2 2.2-2.2 1.2 0 2.3 1 2.3 2.2-.1 1.3-1.1 2.3-2.3 2.3zM11.8 13c.3-.4.6-.7 1-1H7v-1h9s1.2 0 2 .6V3H5v13c0 1.7 1.3 3 3 3h3.8c-.6-.8-1-1.9-1-3H7v-1h3.9l.3-1H7v-1h4.8zm.2-8h4v5h-4V5zM7 5h4v1H7V5zm0 2h4v1H7V7zm0 2h4v1H7V9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M19.1 18.5c.6-.7.9-1.5.9-2.5 0-2.2-1.8-4-4-4s-4 1.8-4 4 1.8 4 4 4c.7 0 1.3-.1 1.8-.4l2.7 2.7 1.1-1.1-2.5-2.7zm-3.1-.3c-1.2 0-2.2-1-2.2-2.3 0-1.2 1-2.2 2.2-2.2 1.2 0 2.3 1 2.3 2.2-.1 1.3-1.1 2.3-2.3 2.3zM11.8 13c.3-.4.6-.7 1-1H7v-1h9s1.2 0 2 .6V3H5v13c0 1.7 1.3 3 3 3h3.8c-.6-.8-1-1.9-1-3H7v-1h3.9l.3-1H7v-1h4.8zm.2-8h4v5h-4V5zM7 5h4v1H7V5zm0 2h4v1H7V7zm0 2h4v1H7V9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7.5 18.5c-.6-.7-.9-1.5-.9-2.5 0-2.2 1.8-4 4-4s4 1.8 4 4-1.8 4-4 4c-.7 0-1.3-.1-1.8-.4l-2.7 2.7L5 21.2l2.5-2.7zm3.1-.3c1.2 0 2.2-1 2.2-2.3 0-1.2-1-2.2-2.2-2.2-1.2 0-2.3 1-2.3 2.2.1 1.3 1.1 2.3 2.3 2.3zm4.2-5.2c-.3-.4-.6-.7-1-1h5.8v-1h-9s-1.2 0-2 .6V3h13v13c0 1.7-1.3 3-3 3h-3.8c.6-.8 1-1.9 1-3h3.8v-1h-3.9l-.3-1h4.2v-1h-4.8zm-.2-8h-4v5h4V5zm5 0h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7.5 18.5c-.6-.7-.9-1.5-.9-2.5 0-2.2 1.8-4 4-4s4 1.8 4 4-1.8 4-4 4c-.7 0-1.3-.1-1.8-.4l-2.7 2.7L5 21.2l2.5-2.7zm3.1-.3c1.2 0 2.2-1 2.2-2.3 0-1.2-1-2.2-2.2-2.2-1.2 0-2.3 1-2.3 2.2.1 1.3 1.1 2.3 2.3 2.3zm4.2-5.2c-.3-.4-.6-.7-1-1h5.8v-1h-9s-1.2 0-2 .6V3h13v13c0 1.7-1.3 3-3 3h-3.8c.6-.8 1-1.9 1-3h3.8v-1h-3.9l-.3-1h4.2v-1h-4.8zm-.2-8h-4v5h4V5zm5 0h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9z"/>
+</svg>
<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M11 12h4V7h-4v5zm-5 2h9v-1H6v1zm0 2h9v-1H6v1zm0 2h9v-1H6v1zm4-9H6v1h4V9zm0 2H6v1h4v-1zm0-4H6v1h4V7zM4 5h13v16H7c-1.7 0-3-1.3-3-3V5z"/>
<path d="M18 4v14h2V2H7v2" fill-rule="evenodd"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M11 12h4V7h-4v5zm-5 2h9v-1H6v1zm0 2h9v-1H6v1zm0 2h9v-1H6v1zm4-9H6v1h4V9zm0 2H6v1h4v-1zm0-4H6v1h4V7zM4 5h13v16H7c-1.7 0-3-1.3-3-3V5z"/>
+ <path d="M18 4v14h2V2H7v2" fill-rule="evenodd"/>
+</svg>
<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M13 12H9V7h4v5zm5 2H9v-1h9v1zm0 2H9v-1h9v1zm0 2H9v-1h9v1zm-4-9h4v1h-4V9zm0 2h4v1h-4v-1zm0-4h4v1h-4V7zm6-2H7v16h10c1.7 0 3-1.3 3-3V5z"/>
<path d="M6 4v14H4V2h13v2" fill-rule="evenodd"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M13 12H9V7h4v5zm5 2H9v-1h9v1zm0 2H9v-1h9v1zm0 2H9v-1h9v1zm-4-9h4v1h-4V9zm0 2h4v1h-4v-1zm0-4h4v1h-4V7zm6-2H7v16h10c1.7 0 3-1.3 3-3V5z"/>
+ <path d="M6 4v14H4V2h13v2" fill-rule="evenodd"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="-293 385 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="-293 385 24 24"><style>* { fill: #fff }</style>
<path d="M-274.3 390.9c-1.6-1.6-4.3-1.5-5.8.1l.2.2c.5.5 1.3.7 2.1.4.8-.3 1.7-.1 2.4.6 1 .9.9 2.4 0 3.4l-7.1 7.1c-.9 1-2.4.9-3.4 0s-.9-2.4 0-3.4l4.4-4.4c.3-.3.9-.5 1.3-.1s.2 1-.1 1.3l-3.4 3.4c-.6.6-.6 1.7.1 2.3l4.3-4.3c.8-.8 1.1-1.8.9-2.7-.2-.9-.9-1.6-1.7-1.9-.9-.2-1.9 0-2.6.7l-4.4 4.4c-1.6 1.6-1.6 4.3.1 5.8 1.5 1.6 4.3 1.5 5.8-.1l7-7c.8-.8 1.2-1.9 1.2-3s-.5-2.1-1.3-2.8c-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-1.5-1.6.8.7 0 0z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="-293 385 24 24"><style>* { fill: #36c }</style>
+ <path d="M-274.3 390.9c-1.6-1.6-4.3-1.5-5.8.1l.2.2c.5.5 1.3.7 2.1.4.8-.3 1.7-.1 2.4.6 1 .9.9 2.4 0 3.4l-7.1 7.1c-.9 1-2.4.9-3.4 0s-.9-2.4 0-3.4l4.4-4.4c.3-.3.9-.5 1.3-.1s.2 1-.1 1.3l-3.4 3.4c-.6.6-.6 1.7.1 2.3l4.3-4.3c.8-.8 1.1-1.8.9-2.7-.2-.9-.9-1.6-1.7-1.9-.9-.2-1.9 0-2.6.7l-4.4 4.4c-1.6 1.6-1.6 4.3.1 5.8 1.5 1.6 4.3 1.5 5.8-.1l7-7c.8-.8 1.2-1.9 1.2-3s-.5-2.1-1.3-2.8c-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-.7-.7.8.7 0 0-1.5-1.6.8.7 0 0z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="-119 70 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="-119 70 24 24"><style>* { fill: #fff }</style>
<path d="M-113.3 75.6c-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7-1.3 1.7-1.3 2.8 0 1.1.4 2.2 1.2 3l7 7c1.5 1.6 4.3 1.7 5.8.1 1.7-1.5 1.7-4.2.1-5.8l-4.4-4.4c-.7-.7-1.7-.9-2.6-.7-.8.3-1.5 1-1.7 1.9-.2.9.1 1.9.9 2.7l4.3 4.3c.7-.6.7-1.7.1-2.3l-3.4-3.4c-.3-.3-.5-.9-.1-1.3s1-.2 1.3.1l4.4 4.4c.9 1 1 2.5 0 3.4s-2.5 1-3.4 0l-7.1-7.1c-.9-1-1-2.5 0-3.4.7-.7 1.6-.9 2.4-.6.8.3 1.6.1 2.1-.4l.2-.2c-1.5-1.6-4.2-1.8-5.8-.1-.8.7 1.5-1.7 0 0z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="-119 70 24 24"><style>* { fill: #36c }</style>
+ <path d="M-113.3 75.6c-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7.7-.7 0 0-.8.7-1.3 1.7-1.3 2.8 0 1.1.4 2.2 1.2 3l7 7c1.5 1.6 4.3 1.7 5.8.1 1.7-1.5 1.7-4.2.1-5.8l-4.4-4.4c-.7-.7-1.7-.9-2.6-.7-.8.3-1.5 1-1.7 1.9-.2.9.1 1.9.9 2.7l4.3 4.3c.7-.6.7-1.7.1-2.3l-3.4-3.4c-.3-.3-.5-.9-.1-1.3s1-.2 1.3.1l4.4 4.4c.9 1 1 2.5 0 3.4s-2.5 1-3.4 0l-7.1-7.1c-.9-1-1-2.5 0-3.4.7-.7 1.6-.9 2.4-.6.8.3 1.6.1 2.1-.4l.2-.2c-1.5-1.6-4.2-1.8-5.8-.1-.8.7 1.5-1.7 0 0z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17.5 13V8c0-3-2.3-5-5.5-5S6.5 5 6.5 8v5c0 2 0 3-2 3v1h15v-1c-2 0-2-1-2-3zM12 19H9c0 1 1.6 2 3 2s3-1 3-2h-3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M17.5 13V8c0-3-2.3-5-5.5-5S6.5 5 6.5 8v5c0 2 0 3-2 3v1h15v-1c-2 0-2-1-2-3zM12 19H9c0 1 1.6 2 3 2s3-1 3-2h-3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17.8 13.7L19.5 9c1-2.8-.5-5.5-3.5-6.6-3-1.1-5.9 0-6.9 2.8L7.4 9.9c-.7 1.9-1 2.8-2.9 2.1l-.3 1 14.1 5.1.3-.9c-1.9-.7-1.5-1.6-.8-3.5zM12 18.8l-2.8-1c-.3.9.8 2.4 2.1 2.9s3.2.1 3.5-.9l-2.8-1z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M17.8 13.7L19.5 9c1-2.8-.5-5.5-3.5-6.6-3-1.1-5.9 0-6.9 2.8L7.4 9.9c-.7 1.9-1 2.8-2.9 2.1l-.3 1 14.1 5.1.3-.9c-1.9-.7-1.5-1.6-.8-3.5zM12 18.8l-2.8-1c-.3.9.8 2.4 2.1 2.9s3.2.1 3.5-.9l-2.8-1z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M6.21 13.7L4.51 9c-1-2.8.5-5.5 3.5-6.6 3-1.1 5.9 0 6.9 2.8l1.7 4.7c.7 1.9 1 2.8 2.9 2.1l.3 1-14.1 5.1-.3-.9c1.9-.7 1.5-1.6.8-3.5zm5.8 5.1l2.8-1c.3.9-.8 2.4-2.1 2.9s-3.2.1-3.5-.9l2.8-1z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M6.21 13.7L4.51 9c-1-2.8.5-5.5 3.5-6.6 3-1.1 5.9 0 6.9 2.8l1.7 4.7c.7 1.9 1 2.8 2.9 2.1l.3 1-14.1 5.1-.3-.9c1.9-.7 1.5-1.6.8-3.5zm5.8 5.1l2.8-1c.3.9-.8 2.4-2.1 2.9s-3.2.1-3.5-.9l2.8-1z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 12l-3-2-1 4-1-4-3 2 2-3-4-1 4-1-2-3 3 2 1-4 1 4 3-2-2 3 4 1-4 1 2 3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 12l-3-2-1 4-1-4-3 2 2-3-4-1 4-1-2-3 3 2 1-4 1 4 3-2-2 3 4 1-4 1 2 3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
<g id="up">
<path id="arrow" d="M15.5 9h7L19 3z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
+ <g id="up">
+ <path id="arrow" d="M15.5 9h7L19 3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
<g id="up">
<path id="arrow" d="M1.5 9h7L5 3z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
+ <g id="up">
+ <path id="arrow" d="M1.5 9h7L5 3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm5 9H7v-2h10v2z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm5 9H7v-2h10v2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm5 9H7v-2h10v2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 18h3L14 6h-3L6 18h3l1.25-3h4.5L16 18zm-4.917-5L12.5 9.6l1.417 3.4h-2.834z" id="bold-a"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 18h3L14 6h-3L6 18h3l1.25-3h4.5L16 18zm-4.917-5L12.5 9.6l1.417 3.4h-2.834z" id="bold-a"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-arab-ain">
<path id="arab-ain" d="M9.337 13.616c0 1.35 1.386 2.1 4.16 2.258l2.186-.03.318.045c-.03.12-.25.34-.66.65l-.09.06c-1.233.93-2.42 1.394-3.56 1.394-1.14 0-2.043-.33-2.71-.99-.65-.66-.973-1.56-.973-2.7.006-1.353.567-2.572 1.685-3.657v-.044l-.606-.55a.952.952 0 0 1-.222-.63c0-.49.24-1.11.72-1.863.65-1.045 1.302-1.565 1.957-1.56.886.005 1.618.42 2.194 1.246.325.48-.03.55-1.064.22-.843-.33-1.528-.05-2.055.826l.016.074 1.125.866.05.005c1.405-.497 2.42-.74 3.044-.725-.06.116-.14.36-.244.732a27.75 27.75 0 0 1-.304.982l-.125.372-.386.05c-1.743.24-2.992.716-3.745 1.43-.465.463-.7.972-.704 1.524"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-arab-ain">
+ <path id="arab-ain" d="M9.337 13.616c0 1.35 1.386 2.1 4.16 2.258l2.186-.03.318.045c-.03.12-.25.34-.66.65l-.09.06c-1.233.93-2.42 1.394-3.56 1.394-1.14 0-2.043-.33-2.71-.99-.65-.66-.973-1.56-.973-2.7.006-1.353.567-2.572 1.685-3.657v-.044l-.606-.55a.952.952 0 0 1-.222-.63c0-.49.24-1.11.72-1.863.65-1.045 1.302-1.565 1.957-1.56.886.005 1.618.42 2.194 1.246.325.48-.03.55-1.064.22-.843-.33-1.528-.05-2.055.826l.016.074 1.125.866.05.005c1.405-.497 2.42-.74 3.044-.725-.06.116-.14.36-.244.732a27.75 27.75 0 0 1-.304.982l-.125.372-.386.05c-1.743.24-2.992.716-3.745 1.43-.465.463-.7.972-.704 1.524"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-arab-dad">
<path id="arab-dad" d="M16.41 8.232l-1.675-.665L15.43 6l1.687.64-.707 1.592m.775 3.078c-.51-.286-1-.427-1.476-.423-.478 0-.99.205-1.54.616l-.505.38.006.024c1.085.066 1.935.1 2.55.1h.315c.57-.022.994-.065 1.278-.132-.067-.17-.275-.36-.625-.566h-.006M10.38 14.6c-.016-.905-.33-1.87-.937-2.9l1.294-1.73.118.15c.267.337.504.925.713 1.767l.064.05c.496-.007.942-.17 1.338-.484v-.006l1.732-1.53c.68-.6 1.282-.9 1.807-.9.383.003.85.194 1.394.57.55.378.884.697 1 .96.063.15.094.385.094.71 0 .694-.11 1.227-.33 1.596-.193.31-.474.555-.845.734-.438.208-1.55.312-3.333.312-.8 0-1.794-.02-2.982-.064l-.142.43c-.254.67-.463 1.112-.625 1.323-.724.937-1.785 1.405-3.182 1.405-1.71-.006-2.56-.92-2.56-2.74.003-.94.278-1.814.824-2.618.15-.216.298-.367.444-.454.225-.133.288-.09.188.124-.396.862-.596 1.548-.6 2.058.008 1.177.752 1.768 2.232 1.772 1.038-.004 1.803-.182 2.295-.535"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-arab-dad">
+ <path id="arab-dad" d="M16.41 8.232l-1.675-.665L15.43 6l1.687.64-.707 1.592m.775 3.078c-.51-.286-1-.427-1.476-.423-.478 0-.99.205-1.54.616l-.505.38.006.024c1.085.066 1.935.1 2.55.1h.315c.57-.022.994-.065 1.278-.132-.067-.17-.275-.36-.625-.566h-.006M10.38 14.6c-.016-.905-.33-1.87-.937-2.9l1.294-1.73.118.15c.267.337.504.925.713 1.767l.064.05c.496-.007.942-.17 1.338-.484v-.006l1.732-1.53c.68-.6 1.282-.9 1.807-.9.383.003.85.194 1.394.57.55.378.884.697 1 .96.063.15.094.385.094.71 0 .694-.11 1.227-.33 1.596-.193.31-.474.555-.845.734-.438.208-1.55.312-3.333.312-.8 0-1.794-.02-2.982-.064l-.142.43c-.254.67-.463 1.112-.625 1.323-.724.937-1.785 1.405-3.182 1.405-1.71-.006-2.56-.92-2.56-2.74.003-.94.278-1.814.824-2.618.15-.216.298-.367.444-.454.225-.133.288-.09.188.124-.396.862-.596 1.548-.6 2.058.008 1.177.752 1.768 2.232 1.772 1.038-.004 1.803-.182 2.295-.535"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-armn-to">
<path id="armn-to" d="M13.86 16.257c.124 0 .254-.026.39-.078.135-.06.257-.15.367-.28a1.43 1.43 0 0 0 .273-.517c.073-.214.11-.48.11-.798V13h-1.14c-.14 0-.284.026-.43.078a.905.905 0 0 0-.383.258c-.11.125-.2.294-.274.508-.067.213-.1.487-.1.82 0 .34.035.47.108.695.08.21.18.39.29.53.12.13.25.23.39.29.14.05.276.07.406.07m-2.97-7.84a2.67 2.67 0 0 0-.975.45 2.1 2.1 0 0 0-.672.813c-.16.342-.242.78-.242 1.31V18H6v-7.188c0-.776.15-1.455.453-2.04a4.227 4.227 0 0 1 1.234-1.467c.52-.39 1.13-.685 1.83-.883a8.114 8.114 0 0 1 2.225-.297c.526 0 1.04.044 1.54.133.504.088.98.22 1.43.398.447.172.858.388 1.233.65.375.26.698.564.97.913.275.34.49.73.64 1.17.15.43.226 1.09.226 1.61h1.36v2.04h-1.36v1.6c0 .58-.102 1.09-.31 1.54-.21.44-.49.81-.844 1.11-.35.302-.834.53-1.297.687-.465.15-.954.226-1.47.226-.51 0-.997-.08-1.46-.235a3.46 3.46 0 0 1-1.22-.703 3.452 3.452 0 0 1-.836-1.174c-.203-.472-.304-1.027-.304-1.662s.1-1.18.32-1.64c.21-.46.49-.684.85-.976.35-.297.76-.513 1.22-.648.452-.14.93-.21 1.43-.21h1.13c-.01-.49-.04-1.044-.24-1.36a2.26 2.26 0 0 0-.77-.767 3.234 3.234 0 0 0-.986-.427c-.375-.09-.578-.094-1.1-.094-.52 0-.64.02-1.01.102z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-armn-to">
+ <path id="armn-to" d="M13.86 16.257c.124 0 .254-.026.39-.078.135-.06.257-.15.367-.28a1.43 1.43 0 0 0 .273-.517c.073-.214.11-.48.11-.798V13h-1.14c-.14 0-.284.026-.43.078a.905.905 0 0 0-.383.258c-.11.125-.2.294-.274.508-.067.213-.1.487-.1.82 0 .34.035.47.108.695.08.21.18.39.29.53.12.13.25.23.39.29.14.05.276.07.406.07m-2.97-7.84a2.67 2.67 0 0 0-.975.45 2.1 2.1 0 0 0-.672.813c-.16.342-.242.78-.242 1.31V18H6v-7.188c0-.776.15-1.455.453-2.04a4.227 4.227 0 0 1 1.234-1.467c.52-.39 1.13-.685 1.83-.883a8.114 8.114 0 0 1 2.225-.297c.526 0 1.04.044 1.54.133.504.088.98.22 1.43.398.447.172.858.388 1.233.65.375.26.698.564.97.913.275.34.49.73.64 1.17.15.43.226 1.09.226 1.61h1.36v2.04h-1.36v1.6c0 .58-.102 1.09-.31 1.54-.21.44-.49.81-.844 1.11-.35.302-.834.53-1.297.687-.465.15-.954.226-1.47.226-.51 0-.997-.08-1.46-.235a3.46 3.46 0 0 1-1.22-.703 3.452 3.452 0 0 1-.836-1.174c-.203-.472-.304-1.027-.304-1.662s.1-1.18.32-1.64c.21-.46.49-.684.85-.976.35-.297.76-.513 1.22-.648.452-.14.93-.21 1.43-.21h1.13c-.01-.49-.04-1.044-.24-1.36a2.26 2.26 0 0 0-.77-.767 3.234 3.234 0 0 0-.986-.427c-.375-.09-.578-.094-1.1-.094-.52 0-.64.02-1.01.102z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-b">
<path id="b" d="M7 18h6c2 0 4-1 4-3 0-1.064.01-1.975-1.99-3 2-.975 1.99-1.935 1.99-3 0-2-2-3-4-3H7v12zm7-8c0 1 0 1-2 1h-2V8h2c2 0 2 0 2 1v1zm-2 6h-2v-3h2c2 0 2 0 2 1v1s0 1-2 1z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-b">
+ <path id="b" d="M7 18h6c2 0 4-1 4-3 0-1.064.01-1.975-1.99-3 2-.975 1.99-1.935 1.99-3 0-2-2-3-4-3H7v12zm7-8c0 1 0 1-2 1h-2V8h2c2 0 2 0 2 1v1zm-2 6h-2v-3h2c2 0 2 0 2 1v1s0 1-2 1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-cyrl-be">
<path id="cyrl-be" d="M7 6h9v2h-6v3h2.65c.892 0 1.632.11 2.22.327.587.218 1.087.622 1.5 1.21.42.59.63 1.188.63 1.98 0 .812-.21 1.397-.63 1.976-.418.578-.897.974-1.436 1.187-.533.213-1.295.32-2.286.32h-5.65m4.768-2c.75 0 1.28-.05 1.584-.12.305-.077.57-.247.792-.51.23-.26.343-.472.343-.854 0-.557-.2-.868-.596-1.12-.4-.255-1.07-.397-2.02-.397H10v3"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-cyrl-be">
+ <path id="cyrl-be" d="M7 6h9v2h-6v3h2.65c.892 0 1.632.11 2.22.327.587.218 1.087.622 1.5 1.21.42.59.63 1.188.63 1.98 0 .812-.21 1.397-.63 1.976-.418.578-.897.974-1.436 1.187-.533.213-1.295.32-2.286.32h-5.65m4.768-2c.75 0 1.28-.05 1.584-.12.305-.077.57-.247.792-.51.23-.26.343-.472.343-.854 0-.557-.2-.868-.596-1.12-.4-.255-1.07-.397-2.02-.397H10v3"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-cyrl-te">
<path id="te" d="M11 18V8H7V6h11v2h-4v10"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-cyrl-te">
+ <path id="te" d="M11 18V8H7V6h11v2h-4v10"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-cyrl-zhe">
<path id="cyrl-zhe" d="M13 6v5.154c.328-.033.537-.18.705-.447.168-.266.4-.873.698-1.82.39-1.242.79-2.034 1.197-2.375.403-.336 1.075-.504 2.014-.504L18 6v1.78l-.386-.008c-.4 0-.69.062-.878.187-.186.112-.337.3-.452.55-.115.25-.286.76-.512 1.533-.12.41-.25.755-.392 1.032-.137.275-.383.536-.738.78.44.156.8.465 1.084.926.288.455.603 1.103.944 1.943L18 18h-2.314l-1.17-3.08-.113-.253-.24-.56c-.247-.57-.45-.933-.61-1.09A.726.726 0 0 0 13 12.78V18h-2v-5.22c-.226 0-.382.077-.546.23-.164.15-.368.517-.612 1.097l-.246.56-.113.253L8.313 18H6l1.33-3.267c.327-.808.635-1.447.923-1.92.293-.476.663-.793 1.11-.95-.355-.244-.603-.5-.745-.772a6.357 6.357 0 0 1-.392-1.04c-.222-.76-.39-1.26-.505-1.52-.11-.25-.26-.44-.45-.57-.18-.12-.49-.18-.912-.18H6V6l.386.008c.953 0 1.63.17 2.034.512.4.347.79 1.136 1.177 2.366.3.954.534 1.564.698 1.83.168.26.377.405.705.438V6.002"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-cyrl-zhe">
+ <path id="cyrl-zhe" d="M13 6v5.154c.328-.033.537-.18.705-.447.168-.266.4-.873.698-1.82.39-1.242.79-2.034 1.197-2.375.403-.336 1.075-.504 2.014-.504L18 6v1.78l-.386-.008c-.4 0-.69.062-.878.187-.186.112-.337.3-.452.55-.115.25-.286.76-.512 1.533-.12.41-.25.755-.392 1.032-.137.275-.383.536-.738.78.44.156.8.465 1.084.926.288.455.603 1.103.944 1.943L18 18h-2.314l-1.17-3.08-.113-.253-.24-.56c-.247-.57-.45-.933-.61-1.09A.726.726 0 0 0 13 12.78V18h-2v-5.22c-.226 0-.382.077-.546.23-.164.15-.368.517-.612 1.097l-.246.56-.113.253L8.313 18H6l1.33-3.267c.327-.808.635-1.447.923-1.92.293-.476.663-.793 1.11-.95-.355-.244-.603-.5-.745-.772a6.357 6.357 0 0 1-.392-1.04c-.222-.76-.39-1.26-.505-1.52-.11-.25-.26-.44-.45-.57-.18-.12-.49-.18-.912-.18H6V6l.386.008c.953 0 1.63.17 2.034.512.4.347.79 1.136 1.177 2.366.3.954.534 1.564.698 1.83.168.26.377.405.705.438V6.002"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-f">
<path id="f" d="M16 8V6H8v12h3v-5h4v-2h-4V8z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-f">
+ <path id="f" d="M16 8V6H8v12h3v-5h4v-2h-4V8z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-g">
<path id="g" d="M12 14v-2h5v4.203c-.497.475-1.22.894-2.166 1.26A7.994 7.994 0 0 1 11.97 18c-1.23 0-2.303-.253-3.217-.76a4.908 4.908 0 0 1-2.062-2.185A7.008 7.008 0 0 1 6 11.96c0-1.208.26-2.282.77-3.222.518-.94 1.27-1.66 2.26-2.16.754-.386 1.693-.58 2.816-.58 1.46 0 2.6.304 3.418.91.825.603 1.354 1.436 1.59 2.502l-2.36.435a2.433 2.433 0 0 0-.94-1.346c-.454-.34-1.022-.5-1.707-.5-1.038 0-1.864.32-2.48.97-.61.65-.914 1.61-.914 2.89 0 1.375.31 2.41.93 3.1.62.687 1.434 1.03 2.44 1.03.497 0 .995-.095 1.49-.285.505-.196 1.334-.57 1.69-.846v-.868"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-g">
+ <path id="g" d="M12 14v-2h5v4.203c-.497.475-1.22.894-2.166 1.26A7.994 7.994 0 0 1 11.97 18c-1.23 0-2.303-.253-3.217-.76a4.908 4.908 0 0 1-2.062-2.185A7.008 7.008 0 0 1 6 11.96c0-1.208.26-2.282.77-3.222.518-.94 1.27-1.66 2.26-2.16.754-.386 1.693-.58 2.816-.58 1.46 0 2.6.304 3.418.91.825.603 1.354 1.436 1.59 2.502l-2.36.435a2.433 2.433 0 0 0-.94-1.346c-.454-.34-1.022-.5-1.707-.5-1.038 0-1.864.32-2.48.97-.61.65-.914 1.61-.914 2.89 0 1.375.31 2.41.93 3.1.62.687 1.434 1.03 2.44 1.03.497 0 .995-.095 1.49-.285.505-.196 1.334-.57 1.69-.846v-.868"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-geor-man">
<path id="geor-man" d="M13.832 14.06c0-1.714-.394-2.572-1.182-2.572-.868 0-1.302.78-1.302 2.338-.01 1.624.42 2.436 1.295 2.436.793 0 1.19-.734 1.19-2.2m2.167 0C16 16.686 14.884 18 12.65 18 10.218 18 9 16.614 9 13.84c0-2.737 1.217-4.105 3.65-4.105.842 0 1.183.63 1.183.63v-1.58c0-.788-.45-1.183-1.347-1.183-.572 0-.858.374-.858 1.123h-2.34C9.29 6.908 10.35 6 12.462 6 14.83 6 16.01 6.946 16 8.84"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-geor-man">
+ <path id="geor-man" d="M13.832 14.06c0-1.714-.394-2.572-1.182-2.572-.868 0-1.302.78-1.302 2.338-.01 1.624.42 2.436 1.295 2.436.793 0 1.19-.734 1.19-2.2m2.167 0C16 16.686 14.884 18 12.65 18 10.218 18 9 16.614 9 13.84c0-2.737 1.217-4.105 3.65-4.105.842 0 1.183.63 1.183.63v-1.58c0-.788-.45-1.183-1.347-1.183-.572 0-.858.374-.858 1.123h-2.34C9.29 6.908 10.35 6 12.462 6 14.83 6 16.01 6.946 16 8.84"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-l">
<path id="l" d="M8 18V6h3v10h5v2"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-l">
+ <path id="l" d="M8 18V6h3v10h5v2"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-n">
<path id="n" d="M7 18V6h3l4 8V6h3v12h-3l-4-8v8H7"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-n">
+ <path id="n" d="M7 18V6h3l4 8V6h3v12h-3l-4-8v8H7"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="bold-v">
<path id="v" d="M10.5 18L6 6h3l3 8 3-8h3l-4.5 12"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="bold-v">
+ <path id="v" d="M10.5 18L6 6h3l3 8 3-8h3l-4.5 12"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 7c-1.7 0-3 1.3-3 3 0-1.7-1.3-3-3-3H3v13h6c1.7 0 3 1 3 2 0-1 1.3-2 3-2h6V7h-6zm5 12h-5c-1.7 0-2 .4-2 .4v-8.9C13 9.1 14.1 8 15.5 8H20v11z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 7c-1.7 0-3 1.3-3 3 0-1.7-1.3-3-3-3H3v13h6c1.7 0 3 1 3 2 0-1 1.3-2 3-2h6V7h-6zm5 12h-5c-1.7 0-2 .4-2 .4v-8.9C13 9.1 14.1 8 15.5 8H20v11z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9 7c1.7 0 3 1.3 3 3 0-1.7 1.3-3 3-3h6v13h-6c-1.7 0-3 1-3 2 0-1-1.3-2-3-2H3V7h6zM4 19h5c1.7 0 2 .4 2 .4v-8.9C11 9.1 9.9 8 8.5 8H4v11z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9 7c1.7 0 3 1.3 3 3 0-1.7 1.3-3 3-3h6v13h-6c-1.7 0-3 1-3 2 0-1-1.3-2-3-2H3V7h6zM4 19h5c1.7 0 2 .4 2 .4v-8.9C11 9.1 9.9 8 8.5 8H4v11z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 5H8c-1.1 0-2 .9-2 2v3h3v11l4-3 4 3V7c0-1.1-.9-2-2-2zM9 9H7V7c0-.6.4-1 1-1h1v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 5H8c-1.1 0-2 .9-2 2v3h3v11l4-3 4 3V7c0-1.1-.9-2-2-2zM9 9H7V7c0-.6.4-1 1-1h1v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M8 5h7c1.1 0 2 .9 2 2v3h-3v11l-4-3-4 3V7c0-1.1.9-2 2-2zm6 4h2V7c0-.6-.4-1-1-1h-1v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M8 5h7c1.1 0 2 .9 2 2v3h-3v11l-4-3-4 3V7c0-1.1.9-2 2-2zm6 4h2V7c0-.6-.4-1-1-1h-1v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3 6v11c0 1.7 1.3 3 3 3h15V6H3zm2.5 1C6.3 7 7 7.7 7 8.5S6.3 10 5.5 10 4 9.3 4 8.5 4.7 7 5.5 7zM20 19H6c-1.1 0-2-.9-2-2v-6h16v8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3 6v11c0 1.7 1.3 3 3 3h15V6H3zm2.5 1C6.3 7 7 7.7 7 8.5S6.3 10 5.5 10 4 9.3 4 8.5 4.7 7 5.5 7zM20 19H6c-1.1 0-2-.9-2-2v-6h16v8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 6v11c0 1.7-1.3 3-3 3H3V6h18zm-2.5 1c-.8 0-1.5.7-1.5 1.5s.7 1.5 1.5 1.5S20 9.3 20 8.5 19.3 7 18.5 7zM4 19h14c1.1 0 2-.9 2-2v-6H4v8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 6v11c0 1.7-1.3 3-3 3H3V6h18zm-2.5 1c-.8 0-1.5.7-1.5 1.5s.7 1.5 1.5 1.5S20 9.3 20 8.5 19.3 7 18.5 7zM4 19h14c1.1 0 2-.9 2-2v-6H4v8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M4 5v10c0 1.7 1.3 3 3 3h14V8c0-1.7-1.3-3-3-3H4zm2 1a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zM5 9h3v2H5V9zm4 0h3v2H9V9zm4 0h3v2h-3V9zm4 0h3v2h-3V9zM5 12h3v2H5v-2zm4 0h3v2H9v-2zm4 0h3v2h-3v-2zm4 0h3v2h-3v-2zM5 15h3v2H7c-1.195 0-2-.805-2-2zm4 0h3v2H9v-2zm4 0h3v2h-3v-2zm4 0h3v2h-3v-2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M4 5v10c0 1.7 1.3 3 3 3h14V8c0-1.7-1.3-3-3-3H4zm2 1a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zM5 9h3v2H5V9zm4 0h3v2H9V9zm4 0h3v2h-3V9zm4 0h3v2h-3V9zM5 12h3v2H5v-2zm4 0h3v2H9v-2zm4 0h3v2h-3v-2zm4 0h3v2h-3v-2zM5 15h3v2H7c-1.195 0-2-.805-2-2zm4 0h3v2H9v-2zm4 0h3v2h-3v-2zm4 0h3v2h-3v-2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 5v10c0 1.7-1.3 3-3 3H4V8c0-1.7 1.3-3 3-3h14zm-2 1a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-4 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-4 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2zM7 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm13 3h-3v2h3V9zm-4 0h-3v2h3V9zm-4 0H9v2h3V9zM8 9H5v2h3V9zm12 3h-3v2h3v-2zm-4 0h-3v2h3v-2zm-4 0H9v2h3v-2zm-4 0H5v2h3v-2zm12 3h-3v2h1c1.195 0 2-.805 2-2zm-4 0h-3v2h3v-2zm-4 0H9v2h3v-2zm-4 0H5v2h3v-2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 5v10c0 1.7-1.3 3-3 3H4V8c0-1.7 1.3-3 3-3h14zm-2 1a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-4 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-4 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2zM7 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm13 3h-3v2h3V9zm-4 0h-3v2h3V9zm-4 0H9v2h3V9zM8 9H5v2h3V9zm12 3h-3v2h3v-2zm-4 0h-3v2h3v-2zm-4 0H9v2h3v-2zm-4 0H5v2h3v-2zm12 3h-3v2h1c1.195 0 2-.805 2-2zm-4 0h-3v2h3v-2zm-4 0H9v2h3v-2zm-4 0H5v2h3v-2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<g id="cancel">
<path id="circle-with-strike" d="M12 5.022a6.98 6.98 0 0 0-.003 13.956 6.98 6.98 0 0 0-.002-13.956zM6.885 12c0-1.092.572-3.25.93-2.93l7.113 7.114c.487.525-1.838.93-2.93.93A5.113 5.113 0 0 1 6.884 12zm9.298 2.93L9.07 7.815c-.445-.483 1.837-.93 2.93-.93a5.112 5.112 0 0 1 5.114 5.113c0 1.092-.364 3.542-.93 2.93z"/>
</g>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="cancel">
<path id="circle-with-strike" d="M12 5.022a6.98 6.98 0 0 0-.003 13.956 6.98 6.98 0 0 0-.002-13.956zM6.885 12c0-1.092.572-3.25.93-2.93l7.113 7.114c.487.525-1.838.93-2.93.93A5.113 5.113 0 0 1 6.884 12zm9.298 2.93L9.07 7.815c-.445-.483 1.837-.93 2.93-.93a5.112 5.112 0 0 1 5.114 5.113c0 1.092-.364 3.542-.93 2.93z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="cancel">
+ <path id="circle-with-strike" d="M12 5.022a6.98 6.98 0 0 0-.003 13.956 6.98 6.98 0 0 0-.002-13.956zM6.885 12c0-1.092.572-3.25.93-2.93l7.113 7.114c.487.525-1.838.93-2.93.93A5.113 5.113 0 0 1 6.884 12zm9.298 2.93L9.07 7.815c-.445-.483 1.837-.93 2.93-.93a5.112 5.112 0 0 1 5.114 5.113c0 1.092-.364 3.542-.93 2.93z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 13.1l8.9 8.9c.8-.8.8-2 0-2.8l-6.1-6.1 6-6.1c.8-.8.8-2 0-2.8L7 13.1z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 13.1l8.9 8.9c.8-.8.8-2 0-2.8l-6.1-6.1 6-6.1c.8-.8.8-2 0-2.8L7 13.1z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16.5 13.1L7.6 22c-.8-.8-.8-2 0-2.8l6.1-6.1-6-6.1c-.8-.8-.8-2 0-2.8l8.8 8.9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16.5 13.1L7.6 22c-.8-.8-.8-2 0-2.8l6.1-6.1-6-6.1c-.8-.8-.8-2 0-2.8l8.8 8.9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 16l8.9-8.9c-.8-.8-2-.8-2.8 0L12 13.2l-6.1-6c-.8-.8-2-.8-2.8 0L12 16z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 16l8.9-8.9c-.8-.8-2-.8-2.8 0L12 13.2l-6.1-6c-.8-.8-2-.8-2.8 0L12 16z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 6.5l8.9 8.9c-.8.8-2 .8-2.8 0L12 9.3l-6.1 6c-.8.8-2 .8-2.8 0L12 6.5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 6.5l8.9 8.9c-.8.8-2 .8-2.8 0L12 9.3l-6.1 6c-.8.8-2 .8-2.8 0L12 6.5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="regular-expression">
<path id="upper-case" d="M7.53 7L4 17h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 7h-2.12zm1.064 1.53L9.938 13H7.25l1.344-4.47z"/>
<path id="lower-case" d="M18.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.564 0-.955-.208-1.377-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.322-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.688-1.4c.877-.46 1.85-.69 2.916-.69 1.024 0 1.59.22 2.134.662.545.445.818 1.12.818 2.03V17h-1.45m-.394-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.336.87 1.008.87.48 0 .865-.137 1.152-.414.29-.277.436-.645.436-1.103v-.627"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="regular-expression">
+ <path id="upper-case" d="M7.53 7L4 17h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 7h-2.12zm1.064 1.53L9.938 13H7.25l1.344-4.47z"/>
+ <path id="lower-case" d="M18.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.564 0-.955-.208-1.377-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.322-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.688-1.4c.877-.46 1.85-.69 2.916-.69 1.024 0 1.59.22 2.134.662.545.445.818 1.12.818 2.03V17h-1.45m-.394-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.336.87 1.008.87.48 0 .865-.137 1.152-.414.29-.277.436-.645.436-1.103v-.627"/>
+ </g>
+</svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
- <path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
-</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
</svg>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
- <circle cx="12" cy="12" r="6"/>
-</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<circle cx="12" cy="12" r="6"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<circle cx="12" cy="12" r="6"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<circle cx="12" cy="12" r="6"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 12h9v-1H7v1zm0 2h9v-1H7v1zm0 2h9v-1H7v1zm4-9H7v1h4V7zm0 2H7v1h4V9zm0-4H7v1h4V5zm5-2h2v16H8c-1.7 0-3-1.3-3-3V3h8v7l1.5-2 1.5 2V3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 12h9v-1H7v1zm0 2h9v-1H7v1zm0 2h9v-1H7v1zm4-9H7v1h4V7zm0 2H7v1h4V9zm0-4H7v1h4V5zm5-2h2v16H8c-1.7 0-3-1.3-3-3V3h8v7l1.5-2 1.5 2V3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 12H7v-1h9v1zm0 2H7v-1h9v1zm0 2H7v-1h9v1zm-4-9h4v1h-4V7zm0 2h4v1h-4V9zm0-4h4v1h-4V5zM7 3H5v16h10c1.7 0 3-1.3 3-3V3h-8v7L8.5 8 7 10V3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 12H7v-1h9v1zm0 2H7v-1h9v1zm0 2H7v-1h9v1zm-4-9h4v1h-4V7zm0 2h4v1h-4V9zm0-4h4v1h-4V5zM7 3H5v16h10c1.7 0 3-1.3 3-3V3h-8v7L8.5 8 7 10V3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="clear">
<path id="circle-with-cross" d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 11l-1 1-3-3-3 3-1-1 3-3-3-3 1-1 3 3 3-3 1 1-3 3 3 3z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="clear">
+ <path id="circle-with-cross" d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 11l-1 1-3-3-3 3-1-1 3-3-3-3 1-1 3 3 3-3 1 1-3 3 3 3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3 12l-4-3V8h2v5l1.7 1.2c1.3.9 1 1.9.3 2.8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3 12l-4-3V8h2v5l1.7 1.2c1.3.9 1 1.9.3 2.8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="close">
<path id="cross" d="M17.4 8.1c.8-.8.8-2 0-2.8L12 10.8 7.4 6.2 6 7.6l4.6 4.6-4 4c-.8.8-.8 2 0 2.8l5.4-5.4 4.6 4.6 1.4-1.4-4.6-4.6z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="close">
+ <path id="cross" d="M17.4 8.1c.8-.8.8-2 0-2.8L12 10.8 7.4 6.2 6 7.6l4.6 4.6-4 4c-.8.8-.8 2 0 2.8l5.4-5.4 4.6 4.6 1.4-1.4-4.6-4.6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="close">
<path id="cross" d="M6.6 8.1c-.8-.8-.8-2 0-2.8l5.4 5.5 4.6-4.6L18 7.6l-4.6 4.6 4 4c.8.8.8 2 0 2.8L12 13.6l-4.6 4.6L6 16.8l4.6-4.6z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="close">
+ <path id="cross" d="M6.6 8.1c-.8-.8-.8-2 0-2.8l5.4 5.5 4.6-4.6L18 7.6l-4.6 4.6 4 4c.8.8.8 2 0 2.8L12 13.6l-4.6 4.6L6 16.8l4.6-4.6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="code">
<path id="left-bracket" d="M4 12v-1h1c1 0 1 0 1-1V7.614c0-.514.024-.896.073-1.142.054-.252.14-.463.257-.633.204-.28.473-.48.808-.59.335-.11.872-.25 1.835-.25H10v1h-.752c-.457 0-.77.19-.936.406-.167.216-.312.446-.312 1.07v1.856c0 .73-.04 1.18-.244 1.493-.2.307-.562.53-1.09.667.535.155.9.385 1.096.688.2.31.238.76.238 1.49v1.86c0 .62.145.85.312 1.06.166.22.48.41.936.41H10v1H8.973c-.963 0-1.5-.133-1.835-.248a1.578 1.578 0 0 1-.808-.59 1.68 1.68 0 0 1-.257-.626C6.023 16.283 6 15.9 6 15.386V13c0-1 0-1-1-1H4z"/>
<use transform="matrix(-1 0 0 1 24 0)" id="right-bracket" width="24" height="24" xlink:href="#left-bracket"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="code">
+ <path id="left-bracket" d="M4 12v-1h1c1 0 1 0 1-1V7.614c0-.514.024-.896.073-1.142.054-.252.14-.463.257-.633.204-.28.473-.48.808-.59.335-.11.872-.25 1.835-.25H10v1h-.752c-.457 0-.77.19-.936.406-.167.216-.312.446-.312 1.07v1.856c0 .73-.04 1.18-.244 1.493-.2.307-.562.53-1.09.667.535.155.9.385 1.096.688.2.31.238.76.238 1.49v1.86c0 .62.145.85.312 1.06.166.22.48.41.936.41H10v1H8.973c-.963 0-1.5-.133-1.835-.248a1.578 1.578 0 0 1-.808-.59 1.68 1.68 0 0 1-.257-.626C6.023 16.283 6 15.9 6 15.386V13c0-1 0-1-1-1H4z"/>
+ <use transform="matrix(-1 0 0 1 24 0)" id="right-bracket" width="24" height="24" xlink:href="#left-bracket"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="collapse">
<path id="arrow" d="M6.697 15.714L12 10.412l5.303 5.302 1.414-1.414L12 7.583 5.283 14.3z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="collapse">
+ <path id="arrow" d="M6.697 15.714L12 10.412l5.303 5.302 1.414-1.414L12 7.583 5.283 14.3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="comment">
<path id="speech-bubble" d="M15 6H9a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3v3l3-3h3a3 3 0 0 0 3-3V9a3 3 0 0 0-3-3z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="comment">
+ <path id="speech-bubble" d="M15 6H9a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3v3l3-3h3a3 3 0 0 0 3-3V9a3 3 0 0 0-3-3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 5H4v12c0 1.6 1.3 3 3 3h12V8c0-1.7-1.4-3-3-3zM7.5 17c-.8 0-1.5-.7-1.5-1.5S6.7 14 7.5 14s1.5.7 1.5 1.5S8.3 17 7.5 17zm0-6C6.7 11 6 10.3 6 9.5S6.7 8 7.5 8 9 8.7 9 9.5 8.3 11 7.5 11zm4 3c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm4 3c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm0-6c-.8 0-1.5-.7-1.5-1.5S14.7 8 15.5 8s1.5.7 1.5 1.5-.7 1.5-1.5 1.5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 5H4v12c0 1.6 1.3 3 3 3h12V8c0-1.7-1.4-3-3-3zM7.5 17c-.8 0-1.5-.7-1.5-1.5S6.7 14 7.5 14s1.5.7 1.5 1.5S8.3 17 7.5 17zm0-6C6.7 11 6 10.3 6 9.5S6.7 8 7.5 8 9 8.7 9 9.5 8.3 11 7.5 11zm4 3c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm4 3c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm0-6c-.8 0-1.5-.7-1.5-1.5S14.7 8 15.5 8s1.5.7 1.5 1.5-.7 1.5-1.5 1.5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 5h12v12c0 1.6-1.3 3-3 3H4V8c0-1.7 1.4-3 3-3zm8.5 12c.8 0 1.5-.7 1.5-1.5s-.7-1.5-1.5-1.5-1.5.7-1.5 1.5.7 1.5 1.5 1.5zm0-6c.8 0 1.5-.7 1.5-1.5S16.3 8 15.5 8 14 8.7 14 9.5s.7 1.5 1.5 1.5zm-4 3c.8 0 1.5-.7 1.5-1.5s-.7-1.5-1.5-1.5-1.5.7-1.5 1.5.7 1.5 1.5 1.5zm-4 3c.8 0 1.5-.7 1.5-1.5S8.3 14 7.5 14 6 14.7 6 15.5 6.7 17 7.5 17zm0-6c.8 0 1.5-.7 1.5-1.5S8.3 8 7.5 8 6 8.7 6 9.5 6.7 11 7.5 11z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 5h12v12c0 1.6-1.3 3-3 3H4V8c0-1.7 1.4-3 3-3zm8.5 12c.8 0 1.5-.7 1.5-1.5s-.7-1.5-1.5-1.5-1.5.7-1.5 1.5.7 1.5 1.5 1.5zm0-6c.8 0 1.5-.7 1.5-1.5S16.3 8 15.5 8 14 8.7 14 9.5s.7 1.5 1.5 1.5zm-4 3c.8 0 1.5-.7 1.5-1.5s-.7-1.5-1.5-1.5-1.5.7-1.5 1.5.7 1.5 1.5 1.5zm-4 3c.8 0 1.5-.7 1.5-1.5S8.3 14 7.5 14 6 14.7 6 15.5 6.7 17 7.5 17zm0-6c.8 0 1.5-.7 1.5-1.5S8.3 8 7.5 8 6 8.7 6 9.5 6.7 11 7.5 11z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 18l8-10H4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 18l8-10H4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 11h-3V4c-1.7 0-3 1.3-3 3v4H7l4.5 5 4.5-5zm1 2v5H7c-.6 0-1-.4-1-1v-4H4v4c0 1.9 1.3 3 3 3h12v-7h-2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 11h-3V4c-1.7 0-3 1.3-3 3v4H7l4.5 5 4.5-5zm1 2v5H7c-.6 0-1-.4-1-1v-4H4v4c0 1.9 1.3 3 3 3h12v-7h-2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 11h3V4c1.7 0 3 1.3 3 3v4h3l-4.5 5L7 11zm-1 2v5h10c.6 0 1-.4 1-1v-4h2v4c0 1.9-1.3 3-3 3H4v-7h2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 11h3V4c1.7 0 3 1.3 3 3v4h3l-4.5 5L7 11zm-1 2v5h10c.6 0 1-.4 1-1v-4h2v4c0 1.9-1.3 3-3 3H4v-7h2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17 2L5 14l-1 5 5-1L21 6c0-2-2-4-4-4zM7.2 15.5c-.3-.3-.7-.6-1-.8C8.5 12.4 17.5 3.3 17.5 3.3c.4.1.7.3 1 .7L7.2 15.5z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M17 2L5 14l-1 5 5-1L21 6c0-2-2-4-4-4zM7.2 15.5c-.3-.3-.7-.6-1-.8C8.5 12.4 17.5 3.3 17.5 3.3c.4.1.7.3 1 .7L7.2 15.5z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M8 2l12 12 1 5-5-1L4 6c0-2 2-4 4-4zm9.8 13.5c.3-.3.7-.6 1-.8C16.5 12.4 7.5 3.3 7.5 3.3c-.4.1-.7.3-1 .7l11.3 11.5z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M8 2l12 12 1 5-5-1L4 6c0-2 2-4 4-4zm9.8 13.5c.3-.3.7-.6 1-.8C16.5 12.4 7.5 3.3 7.5 3.3c-.4.1-.7.3-1 .7l11.3 11.5z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 4V3s0-3-3-3-3 3-3 3v1h-1v6h8V4zm-1.5 0h-3V3s0-1.5 1.5-1.5c1.48.06 1.5 1.5 1.5 1.5zM13 9.6l-6.8 6.9c-.3-.3-.7-.6-1-.8 1.4-1.4 5-5 7.8-7.9V6l-9 9-1 5 5-1 8-8h-3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 4V3s0-3-3-3-3 3-3 3v1h-1v6h8V4zm-1.5 0h-3V3s0-1.5 1.5-1.5c1.48.06 1.5 1.5 1.5 1.5zM13 9.6l-6.8 6.9c-.3-.3-.7-.6-1-.8 1.4-1.4 5-5 7.8-7.9V6l-9 9-1 5 5-1 8-8h-3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M4 4V3s0-3 3-3 3 3 3 3v1h1v6H3V4zm1.5 0h3V3s0-1.5-1.5-1.5C5.52 1.56 5.5 3 5.5 3zM12 9.6l6.8 6.9c.3-.3.7-.6 1-.8-1.4-1.4-5-5-7.8-7.9V6l9 9 1 5-5-1-8-8h3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M4 4V3s0-3 3-3 3 3 3 3v1h1v6H3V4zm1.5 0h3V3s0-1.5-1.5-1.5C5.52 1.56 5.5 3 5.5 3zM12 9.6l6.8 6.9c.3-.3.7-.6 1-.8-1.4-1.4-5-5-7.8-7.9V6l9 9 1 5-5-1-8-8h3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M14.9 2.8c.9 0 1.8.2 2.7.6.9.4 1.6.9 1.9 1.6-2.8.1-5 1.1-6.6 3.1l1.3 2-6.7-.3L8 3l1.7 2c1.8-1.5 3.5-2.2 5.2-2.2z"/>
<path d="M15.2 11.1l-2.6-.1-5.4 5.5c-.3-.3-.7-.6-1-.8.9-.9 2.8-2.8 4.7-4.8H9.1L5 15l-1 5 5-1 7.8-7.8-1.6-.1zM20.6 6c-1.7 0-3.2.5-4.4 1.4l-.9.9.8 1.3.9 1.4 4-4c0-.3-.1-.7-.2-1h-.2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M14.9 2.8c.9 0 1.8.2 2.7.6.9.4 1.6.9 1.9 1.6-2.8.1-5 1.1-6.6 3.1l1.3 2-6.7-.3L8 3l1.7 2c1.8-1.5 3.5-2.2 5.2-2.2z"/>
+ <path d="M15.2 11.1l-2.6-.1-5.4 5.5c-.3-.3-.7-.6-1-.8.9-.9 2.8-2.8 4.7-4.8H9.1L5 15l-1 5 5-1 7.8-7.8-1.6-.1zM20.6 6c-1.7 0-3.2.5-4.4 1.4l-.9.9.8 1.3.9 1.4 4-4c0-.3-.1-.7-.2-1h-.2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M10.1 2.8c-.9 0-1.8.2-2.7.6-.9.4-1.6.9-1.9 1.6 2.8.1 5 1.1 6.6 3.1l-1.3 2 6.7-.3L17 3l-1.7 2c-1.8-1.5-3.5-2.2-5.2-2.2z"/>
<path d="M9.8 11.1l2.6-.1 5.4 5.5c.3-.3.7-.6 1-.8-.9-.9-2.8-2.8-4.7-4.8h1.8L20 15l1 5-5-1-7.8-7.8 1.6-.1zM4.4 6c1.7 0 3.2.5 4.4 1.4l.9.9-.8 1.3L8 11 4 7c0-.3.1-.7.2-1h.2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M10.1 2.8c-.9 0-1.8.2-2.7.6-.9.4-1.6.9-1.9 1.6 2.8.1 5 1.1 6.6 3.1l-1.3 2 6.7-.3L17 3l-1.7 2c-1.8-1.5-3.5-2.2-5.2-2.2z"/>
+ <path d="M9.8 11.1l2.6-.1 5.4 5.5c.3-.3.7-.6 1-.8-.9-.9-2.8-2.8-4.7-4.8h1.8L20 15l1 5-5-1-7.8-7.8 1.6-.1zM4.4 6c1.7 0 3.2.5 4.4 1.4l.9.9-.8 1.3L8 11 4 7c0-.3.1-.7.2-1h.2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M8 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4zM14 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4zM20 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M8 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4zM14 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4zM20 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="expand">
<path id="arrow" d="M17.303 8.283L12 13.586 6.697 8.283 5.283 9.697 12 16.414l6.717-6.717z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="expand">
+ <path id="arrow" d="M17.303 8.283L12 13.586 6.697 8.283 5.283 9.697 12 16.414l6.717-6.717z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="external">
<path id="box" d="M4 4h6v2H6v12h12v-4h2v6H4z"/>
<path id="arrow" d="M12.42 4H20v7.58l-2.84-2.846L12.892 13 11 11.106l4.264-4.266z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="external">
+ <path id="box" d="M4 4h6v2H6v12h12v-4h2v6H4z"/>
+ <path id="arrow" d="M12.42 4H20v7.58l-2.84-2.846L12.892 13 11 11.106l4.264-4.266z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="external">
<path id="box" d="M20 4h-6v2h4v12H6v-4H4v6h16z"/>
<path id="arrow" d="M11.58 4H4v7.58l2.84-2.846L11.108 13 13 11.106 8.736 6.84z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="external">
+ <path id="box" d="M20 4h-6v2h4v12H6v-4H4v6h16z"/>
+ <path id="arrow" d="M11.58 4H4v7.58l2.84-2.846L11.108 13 13 11.106 8.736 6.84z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 8c-5 0-11 6-11 6s6 6 11 6 11-6 11-6-6-6-11-6zm0 10c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
<circle cx="12" cy="14" r="2"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 8c-5 0-11 6-11 6s6 6 11 6 11-6 11-6-6-6-11-6zm0 10c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
+ <circle cx="12" cy="14" r="2"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M19.4 12.7c.7-.8 1.2-1.7 1.4-2.7h-1.6c-.9 2.5-3.9 4.4-7.7 4.6h-.1c-3.7-.2-6.8-2.1-7.7-4.6H2.2c.2 1 .8 1.9 1.4 2.7l-2 2 .7.7 2-2c.8.6 1.7 1.2 2.7 1.7l-1 2.8.9.3 1-2.8c1 .3 2 .6 3.1.6v3h1v-3c1.1-.1 2.2-.3 3.1-.6l1 2.8.9-.3-1-2.8c1-.4 1.9-1 2.6-1.7l2 2 .7-.7-1.9-2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M19.4 12.7c.7-.8 1.2-1.7 1.4-2.7h-1.6c-.9 2.5-3.9 4.4-7.7 4.6h-.1c-3.7-.2-6.8-2.1-7.7-4.6H2.2c.2 1 .8 1.9 1.4 2.7l-2 2 .7.7 2-2c.8.6 1.7 1.2 2.7 1.7l-1 2.8.9.3 1-2.8c1 .3 2 .6 3.1.6v3h1v-3c1.1-.1 2.2-.3 3.1-.6l1 2.8.9-.3-1-2.8c1-.4 1.9-1 2.6-1.7l2 2 .7-.7-1.9-2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="find">
<path id="magnifying-glass" d="M13.656 11c-1.92 0-3.5 1.548-3.5 3.47 0 1.92 1.58 3.5 3.5 3.5.75 0 1.432-.253 2-.657l.094.156 2.375 2.37c.19.19.534.15.78-.096s.315-.59.126-.78l-2.37-2.377-.185-.094a3.545 3.545 0 0 0 .655-2.03c0-1.92-1.55-3.47-3.47-3.47zm0 1.656a1.8 1.8 0 0 1 1.813 1.813 1.83 1.83 0 0 1-1.82 1.84c-1.01 0-1.844-.83-1.844-1.847s.832-1.814 1.844-1.814z"/>
<path id="text" d="M6 5v2h10V5H6zm0 3v2h11V8H6zm0 3v2h3.53a4.443 4.443 0 0 1 1.44-2H6zm0 3v2h3.53c-.177-.48-.28-.99-.28-1.53 0-.16.046-.315.063-.47H6z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="find">
+ <path id="magnifying-glass" d="M13.656 11c-1.92 0-3.5 1.548-3.5 3.47 0 1.92 1.58 3.5 3.5 3.5.75 0 1.432-.253 2-.657l.094.156 2.375 2.37c.19.19.534.15.78-.096s.315-.59.126-.78l-2.37-2.377-.185-.094a3.545 3.545 0 0 0 .655-2.03c0-1.92-1.55-3.47-3.47-3.47zm0 1.656a1.8 1.8 0 0 1 1.813 1.813 1.83 1.83 0 0 1-1.82 1.84c-1.01 0-1.844-.83-1.844-1.847s.832-1.814 1.844-1.814z"/>
+ <path id="text" d="M6 5v2h10V5H6zm0 3v2h11V8H6zm0 3v2h3.53a4.443 4.443 0 0 1 1.44-2H6zm0 3v2h3.53c-.177-.48-.28-.99-.28-1.53 0-.16.046-.315.063-.47H6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="find">
<path id="magnifying-glass" d="M11.344 11c1.92 0 3.5 1.548 3.5 3.47 0 1.92-1.58 3.5-3.5 3.5-.75 0-1.432-.253-2-.657l-.094.156-2.375 2.37c-.19.19-.534.15-.78-.096s-.315-.59-.126-.78l2.37-2.377.185-.094a3.545 3.545 0 0 1-.655-2.03c0-1.92 1.55-3.47 3.47-3.47zm0 1.656A1.8 1.8 0 0 0 9.53 14.47c0 1.01.806 1.84 1.818 1.84 1.01 0 1.844-.83 1.844-1.845s-.832-1.814-1.844-1.814z"/>
<path id="text" d="M19 5v2H9V5zm0 3v2H8V8zm0 3v2h-3.53a4.443 4.443 0 0 0-1.44-2zm0 3v2h-3.53c.177-.48.28-.99.28-1.53 0-.16-.046-.315-.063-.47z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="find">
+ <path id="magnifying-glass" d="M11.344 11c1.92 0 3.5 1.548 3.5 3.47 0 1.92-1.58 3.5-3.5 3.5-.75 0-1.432-.253-2-.657l-.094.156-2.375 2.37c-.19.19-.534.15-.78-.096s-.315-.59-.126-.78l2.37-2.377.185-.094a3.545 3.545 0 0 1-.655-2.03c0-1.92 1.55-3.47 3.47-3.47zm0 1.656A1.8 1.8 0 0 0 9.53 14.47c0 1.01.806 1.84 1.818 1.84 1.01 0 1.844-.83 1.844-1.845s-.832-1.814-1.844-1.814z"/>
+ <path id="text" d="M19 5v2H9V5zm0 3v2H8V8zm0 3v2h-3.53a4.443 4.443 0 0 0-1.44-2zm0 3v2h-3.53c.177-.48.28-.99.28-1.53 0-.16-.046-.315-.063-.47z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M14 6.5V5c-1.4-1.5-5.2-1.2-6 0V4H7v15h1v-7c.8-.8 3.4-.9 5-.5V13c1.2 1.5 4.3 1.2 5 0V6c-.7.7-2.7.9-4 .5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M14 6.5V5c-1.4-1.5-5.2-1.2-6 0V4H7v15h1v-7c.8-.8 3.4-.9 5-.5V13c1.2 1.5 4.3 1.2 5 0V6c-.7.7-2.7.9-4 .5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M10.3 7.5V6c1.4-1.5 5.2-1.2 6 0V5h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V14c-1.2 1.5-4.3 1.2-5 0V7c.7.7 2.7.9 4 .5z"/>
</svg>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M10.3 7.5V6c1.4-1.5 5.2-1.2 6 0V5h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V14c-1.2 1.5-4.3 1.2-5 0V7c.7.7 2.7.9 4 .5z"/>
+</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
</svg>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
</svg>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M2 5v15h20V5H2zm15 11H8c-.6 0-1-.4-1-1V9h3l2 1h5v6z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M2 5v15h20V5H2zm15 11H8c-.6 0-1-.4-1-1V9h3l2 1h5v6z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M22 5v15H2V5h20zM7 16h9c.6 0 1-.4 1-1V9h-3l-2 1H7v6z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M22 5v15H2V5h20zM7 16h9c.6 0 1-.4 1-1V9h-3l-2 1H7v6z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path id="arrow" d="M6 6v4l1.28-1.28 2 2 1.423-1.44-2-2L10 6z"/>
<use transform="rotate(90 12 12)" xlink:href="#arrow"/>
<use transform="rotate(180 12 12)" xlink:href="#arrow"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path id="arrow" d="M6 6v4l1.28-1.28 2 2 1.423-1.44-2-2L10 6z"/>
+ <use transform="rotate(90 12 12)" xlink:href="#arrow"/>
+ <use transform="rotate(180 12 12)" xlink:href="#arrow"/>
+ <use transform="rotate(-90 12 12)" xlink:href="#arrow"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M11 13L5 6h15l-6 7v7c-1.7 0-3-1.3-3-3v-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M11 13L5 6h15l-6 7v7c-1.7 0-3-1.3-3-3v-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M14 13l6-7H5l6 7v7c1.7 0 3-1.3 3-3v-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M14 13l6-7H5l6 7v7c1.7 0 3-1.3 3-3v-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 7c-2 0-3 2-3 2s-1-2-3-2c-2.5 0-4 2-4 4 0 4 5 5 7 8 2-3 7-4 7-8 0-2-1.5-4-4-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 7c-2 0-3 2-3 2s-1-2-3-2c-2.5 0-4 2-4 4 0 4 5 5 7 8 2-3 7-4 7-8 0-2-1.5-4-4-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="help">
<path id="circle" d="M12 2.085c-5.477 0-9.915 4.438-9.915 9.916 0 5.48 4.438 9.92 9.916 9.92 5.48 0 9.92-4.44 9.92-9.913 0-5.477-4.44-9.915-9.913-9.915zm.002 18a8.084 8.084 0 1 1 0-16.168 8.084 8.084 0 0 1 0 16.168z"/>
<g id="question-mark">
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="help">
+ <path id="circle" d="M12 2.085c-5.477 0-9.915 4.438-9.915 9.916 0 5.48 4.438 9.92 9.916 9.92 5.48 0 9.92-4.44 9.92-9.913 0-5.477-4.44-9.915-9.913-9.915zm.002 18a8.084 8.084 0 1 1 0-16.168 8.084 8.084 0 0 1 0 16.168z"/>
+ <g id="question-mark">
+ <path id="top" d="M11.766 6.688c-2.5 0-3.22 2.188-3.22 2.188l1.412.854s.298-.79.9-1.23c.517-.374 1.626-.624 2.22.126.7.885-.17 1.587-1.078 2.72C11.047 12.53 11 15 11 15h1.97s.134-2.318 1.04-3.38c.603-.708 1.443-1.34 1.443-2.495s-1.187-2.437-3.687-2.437z"/>
+ <path id="bottom" d="M11 16h2v2h-2z"/>
+ </g>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="help">
<path id="circle" d="M12 2.085c5.477 0 9.915 4.438 9.915 9.916 0 5.48-4.438 9.92-9.916 9.92-5.48 0-9.92-4.44-9.92-9.913 0-5.477 4.44-9.915 9.913-9.915zm-.002 18a8.084 8.084 0 1 0 0-16.168 8.084 8.084 0 0 0 0 16.168z"/>
<g id="question-mark">
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="help">
+ <path id="circle" d="M12 2.085c5.477 0 9.915 4.438 9.915 9.916 0 5.48-4.438 9.92-9.916 9.92-5.48 0-9.92-4.44-9.92-9.913 0-5.477 4.44-9.915 9.913-9.915zm-.002 18a8.084 8.084 0 1 0 0-16.168 8.084 8.084 0 0 0 0 16.168z"/>
+ <g id="question-mark">
+ <path id="top" d="M12.234 6.688c2.5 0 3.22 2.188 3.22 2.188l-1.412.854s-.298-.79-.9-1.23c-.517-.374-1.626-.624-2.22.126-.7.885.17 1.587 1.078 2.72C12.953 12.53 13 15 13 15h-1.97s-.134-2.318-1.04-3.38c-.603-.708-1.443-1.34-1.443-2.495 0-1.156 1.187-2.437 3.687-2.437z"/>
+ <path id="bottom" d="M13 16h-2v2h2z"/>
+ </g>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="history">
<path id="clock-hands" d="M17.26 15.076s-2.385-1.935-4.005-3.062c.72-2.397 1.702-6.56 1.702-6.56s-4.35 5.364-4.877 6.7c-.463 1.168 1.46 2.21 2.346 1.678 1.9.55 4.834 1.244 4.834 1.244z"/>
<path id="arrow" d="M12.086 2.085C6.608 2.085 2.17 6.523 2.17 12a9.86 9.86 0 0 0 1.3 4.9l-2.22 2.04h5.688v-5.22L4.87 15.616A7.982 7.982 0 0 1 4.004 12a8.084 8.084 0 0 1 16.167.004 8.08 8.08 0 0 1-8.08 8.085 7.975 7.975 0 0 1-3.21-.68L8.05 21.04a9.81 9.81 0 0 0 4.045.874C17.563 21.914 22 17.476 22 12c0-5.477-4.438-9.915-9.914-9.915z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="history">
+ <path id="clock-hands" d="M17.26 15.076s-2.385-1.935-4.005-3.062c.72-2.397 1.702-6.56 1.702-6.56s-4.35 5.364-4.877 6.7c-.463 1.168 1.46 2.21 2.346 1.678 1.9.55 4.834 1.244 4.834 1.244z"/>
+ <path id="arrow" d="M12.086 2.085C6.608 2.085 2.17 6.523 2.17 12a9.86 9.86 0 0 0 1.3 4.9l-2.22 2.04h5.688v-5.22L4.87 15.616A7.982 7.982 0 0 1 4.004 12a8.084 8.084 0 0 1 16.167.004 8.08 8.08 0 0 1-8.08 8.085 7.975 7.975 0 0 1-3.21-.68L8.05 21.04a9.81 9.81 0 0 0 4.045.874C17.563 21.914 22 17.476 22 12c0-5.477-4.438-9.915-9.914-9.915z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="image">
<path id="mountains" d="M18 17l-3-3-2 1-3-3-4 5zm2-11v13H4V6z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="image">
+ <path id="mountains" d="M18 17l-3-3-2 1-3-3-4 5zm2-11v13H4V6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="image">
<path id="mountains" d="M6 17l3-3 2 1 3-3 4 5zM4 6v13h16V6z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="image">
+ <path id="mountains" d="M6 17l3-3 2 1 3-3 4 5zM4 6v13h16V6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="imageAdd">
<path id="mountains" d="M16 17l-3-3-2 1-3-3-4 5zm-1-8v4h3v6H2V6h9v3z"/>
<path id="add" d="M22 6h-4V2h-2v4h-4v2h4v4h2V8h4z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="imageAdd">
+ <path id="mountains" d="M16 17l-3-3-2 1-3-3-4 5zm-1-8v4h3v6H2V6h9v3z"/>
+ <path id="add" d="M22 6h-4V2h-2v4h-4v2h4v4h2V8h4z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="imageAdd">
<path id="mountains" d="M8 17l3-3 2 1 3-3 4 5zm1-8v4H6v6h16V6h-9v3z"/>
<path id="add" d="M2 6h4V2h2v4h4v2H8v4H6V8H2z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="imageAdd">
+ <path id="mountains" d="M8 17l3-3 2 1 3-3 4 5zm1-8v4H6v6h16V6h-9v3z"/>
+ <path id="add" d="M2 6h4V2h2v4h4v2H8v4H6V8H2z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M2 4v14h2V6h15V4H2zm3 3v13h16V7H5zm6 6l3 3 2-1 3 3H7l4-5z" id="imageGallery"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M2 4v14h2V6h15V4H2zm3 3v13h16V7H5zm6 6l3 3 2-1 3 3H7l4-5z" id="imageGallery"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 4v14h-2V6H4V4h17zm-3 3v13H2V7h16zm-6 6l-3 3-2-1-3 3h12l-4-5z" id="imageGallery"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 4v14h-2V6H4V4h17zm-3 3v13H2V7h16zm-6 6l-3 3-2-1-3 3h12l-4-5z" id="imageGallery"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="imageAdd">
<path id="mountains" d="M18 17l-3-3-2 1-3-3-4 5zm2-5v7H4V6h8v6z"/>
<path id="lock" d="M18.5 5h-3V4s0-1.5 1.5-1.5c1.5.06 1.5 1.5 1.5 1.5zM20 5V4s0-3-3-3-3 3-3 3v1h-1v6h8V5z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="imageAdd">
+ <path id="mountains" d="M18 17l-3-3-2 1-3-3-4 5zm2-5v7H4V6h8v6z"/>
+ <path id="lock" d="M18.5 5h-3V4s0-1.5 1.5-1.5c1.5.06 1.5 1.5 1.5 1.5zM20 5V4s0-3-3-3-3 3-3 3v1h-1v6h8V5z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="imageAdd">
<path id="mountains" d="M7 17l3-3 2 1 3-3 4 5zm-2-5v7h16V6h-8v6z"/>
<path id="lock" d="M6.5 5h3V4s0-1.5-1.5-1.5C6.5 2.56 6.5 4 6.5 4zM5 5V4s0-3 3-3 3 3 3 3v1h1v6H4V5z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="imageAdd">
+ <path id="mountains" d="M7 17l3-3 2 1 3-3 4 5zm-2-5v7h16V6h-8v6z"/>
+ <path id="lock" d="M6.5 5h3V4s0-1.5-1.5-1.5C6.5 2.56 6.5 4 6.5 4zM5 5V4s0-3 3-3 3 3 3 3v1h1v6H4V5z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M10 8h9v2h-9V8zm0 3h9v2h-9v-2zm0 3h6v2h-6v-2zm11-8H3V4h18v2zm0 14H3v-2h18v2zM3 8v8l5-4-5-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M10 8h9v2h-9V8zm0 3h9v2h-9v-2zm0 3h6v2h-6v-2zm11-8H3V4h18v2zm0 14H3v-2h18v2zM3 8v8l5-4-5-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M14 8H5v2h9V8zm0 3H5v2h9v-2zm0 3H8v2h6v-2zM3 6h18V4H3v2zm0 14h18v-2H3v2zM21 8v8l-5-4 5-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M14 8H5v2h9V8zm0 3H5v2h9v-2zm0 3H8v2h6v-2zM3 6h18V4H3v2zm0 14h18v-2H3v2zM21 8v8l-5-4 5-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="info">
<path id="circled-i" d="M11.5 17a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11zm0-12a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13zm.5 5v4h1v1h-3v-1h1v-3h-1v-1zm-1-2h1v1h-1z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="info">
+ <path id="circled-i" d="M11.5 17a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11zm0-12a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13zm.5 5v4h1v1h-3v-1h1v-3h-1v-1zm-1-2h1v1h-1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-a">
<path id="a" d="M14.667 6h-1.372l-7 12H8l2.333-4h4L15 18h1.667l-2-12zm-3.75 7l2.527-4.333.723 4.333h-3.25z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-a">
+ <path id="a" d="M14.667 6h-1.372l-7 12H8l2.333-4h4L15 18h1.667l-2-12zm-3.75 7l2.527-4.333.723 4.333h-3.25z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-arab-keheh-jeem">
<path id="arab-keheh-jeem" d="M18.125 5.844c-1.695.555-3.297 1.162-4.594 1.938-.49.3-.77.712-.87 1.125a1.26 1.26 0 0 0 .065.78c.19.406.54.575.844.814l.093-.12.53.627c.14.165.345.514.47.94.138.462.08.724 0 1.124h-3.44c-.34 0-.592.007-.766-.02-.34-.053-.256-.21-.234-.34.33-.127.56-.173.934-.14.29-.495.593-.886.906-1.314-.98.037-1.877.015-2.687-.094-.346-.046-.698-.185-1.094-.155-.36.026-.77.24-1.03.72-.25.447-.436.838-.66 1.28l.75-.47c.23-.14.486-.226.72-.218.158.004.276.053.407.093-.234.204-.51.4-.72.56-.3.26-.704.69-.908 1-.403.617-.694 1.086-.875 1.78-.18.69.003 1.34.468 1.75.426.38.846.52 1.28.566.65.064 1.206.092 2-.19.658-.23 1.022-.552 1.5-.97-.882.11-1.816.09-2.53.033-.87-.07-1.268-.386-1.47-.596-.27-.283-.306-.64-.155-1.22a1.44 1.44 0 0 1 .25-.53c.17-.228.363-.435.593-.656.45-.436 1.01-.737 1.46-.94-.042.207-.104.444-.052.69.05.23.25.38.44.47.26.12.506.152.69.153 1.42.01 2.86 0 4.28 0 .246 0 .45-.163.593-.375.14-.21.25-.48.343-.845.13-.5.094-1.062-.094-1.625a4.812 4.812 0 0 0-.72-1.406c-.336-.444-.675-.83-1-1.22 1.256-.815 2.715-1.24 3.97-1.688.12-.452.222-.926.31-1.313zm-9.47 8.438c-.26.394-.583.69-.874 1 .38.286.75.556 1.1.813.336-.303.627-.674.876-.97-.39-.267-.77-.587-1.093-.843z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-arab-keheh-jeem">
+ <path id="arab-keheh-jeem" d="M18.125 5.844c-1.695.555-3.297 1.162-4.594 1.938-.49.3-.77.712-.87 1.125a1.26 1.26 0 0 0 .065.78c.19.406.54.575.844.814l.093-.12.53.627c.14.165.345.514.47.94.138.462.08.724 0 1.124h-3.44c-.34 0-.592.007-.766-.02-.34-.053-.256-.21-.234-.34.33-.127.56-.173.934-.14.29-.495.593-.886.906-1.314-.98.037-1.877.015-2.687-.094-.346-.046-.698-.185-1.094-.155-.36.026-.77.24-1.03.72-.25.447-.436.838-.66 1.28l.75-.47c.23-.14.486-.226.72-.218.158.004.276.053.407.093-.234.204-.51.4-.72.56-.3.26-.704.69-.908 1-.403.617-.694 1.086-.875 1.78-.18.69.003 1.34.468 1.75.426.38.846.52 1.28.566.65.064 1.206.092 2-.19.658-.23 1.022-.552 1.5-.97-.882.11-1.816.09-2.53.033-.87-.07-1.268-.386-1.47-.596-.27-.283-.306-.64-.155-1.22a1.44 1.44 0 0 1 .25-.53c.17-.228.363-.435.593-.656.45-.436 1.01-.737 1.46-.94-.042.207-.104.444-.052.69.05.23.25.38.44.47.26.12.506.152.69.153 1.42.01 2.86 0 4.28 0 .246 0 .45-.163.593-.375.14-.21.25-.48.343-.845.13-.5.094-1.062-.094-1.625a4.812 4.812 0 0 0-.72-1.406c-.336-.444-.675-.83-1-1.22 1.256-.815 2.715-1.24 3.97-1.688.12-.452.222-.926.31-1.313zm-9.47 8.438c-.26.394-.583.69-.874 1 .38.286.75.556 1.1.813.336-.303.627-.674.876-.97-.39-.267-.77-.587-1.093-.843z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-arab-meem">
<path id="arab-meem" d="M16 9.73l-.93 2.19h-4.663c-.48 0-.857.12-1.135.366l-.06.11c-.185 2.016-.503 3.558-.956 4.627a8.31 8.31 0 0 1-1.082 1.833c-.177.226-.22.186-.126-.12l.142-.503.17-.67.234-.87.002-.008.202-1.045.258-1.41.353-1.907c.19-.312.42-.638.692-.98a24.1 24.1 0 0 1 .94-1.09c.13-.092.697-.18 1.705-.266 1.05-.086 1.64-.183 1.765-.293l.065-.128c.01-.11-.01-.24-.052-.394a2.403 2.403 0 0 0-.232-.522c-.22-.428-.438-.64-.654-.64-.294 0-.915.268-1.864.805-.36.208-.378.125-.05-.247 1.555-1.71 2.705-2.566 3.45-2.566.38 0 .67.13.86.394.134.195.25.6.343 1.21l.202 1.2c.105.586.24.895.408.925"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-arab-meem">
+ <path id="arab-meem" d="M16 9.73l-.93 2.19h-4.663c-.48 0-.857.12-1.135.366l-.06.11c-.185 2.016-.503 3.558-.956 4.627a8.31 8.31 0 0 1-1.082 1.833c-.177.226-.22.186-.126-.12l.142-.503.17-.67.234-.87.002-.008.202-1.045.258-1.41.353-1.907c.19-.312.42-.638.692-.98a24.1 24.1 0 0 1 .94-1.09c.13-.092.697-.18 1.705-.266 1.05-.086 1.64-.183 1.765-.293l.065-.128c.01-.11-.01-.24-.052-.394a2.403 2.403 0 0 0-.232-.522c-.22-.428-.438-.64-.654-.64-.294 0-.915.268-1.864.805-.36.208-.378.125-.05-.247 1.555-1.71 2.705-2.566 3.45-2.566.38 0 .67.13.86.394.134.195.25.6.343 1.21l.202 1.2c.105.586.24.895.408.925"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-armn-sha">
<path id="armn-sha" d="M11.564 7.678a3.073 3.073 0 0 0-.93-.268c-.35-.047-.75-.07-1.197-.07h-1.11L8.587 6h1.723c.558 0 1.042.032 1.45.095.416.063.794.173 1.136.33l4.483 2.033-.33 1.67-2.625-1.165a1.867 1.867 0 0 0-.433-.134 2.45 2.45 0 0 0-.576-.06 4.88 4.88 0 0 0-1.663.28c-.526.19-1 .46-1.427.812-.42.35-.776.78-1.07 1.283a5.48 5.48 0 0 0-.63 1.71c-.24 1.255-.15 2.21.27 2.87.424.65 1.19.976 2.292.976.55 0 1.044-.08 1.48-.236a3.488 3.488 0 0 0 1.135-.66c.325-.29.59-.634.795-1.034.21-.4.363-.84.458-1.322l.11-.56h1.6l-.12.59a5.925 5.925 0 0 1-.676 1.844 5.19 5.19 0 0 1-1.214 1.423c-.488.395-1.053.7-1.694.923a6.573 6.573 0 0 1-2.106.324c-.767 0-1.434-.114-2-.34-.568-.226-1.025-.554-1.372-.985-.347-.437-.573-.97-.678-1.608-.105-.64-.078-1.366.08-2.186.125-.66.346-1.274.66-1.836A6.332 6.332 0 0 1 8.792 9.54a5.955 5.955 0 0 1 1.496-1.072 5.87 5.87 0 0 1 1.732-.57l-.465-.23"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-armn-sha">
+ <path id="armn-sha" d="M11.564 7.678a3.073 3.073 0 0 0-.93-.268c-.35-.047-.75-.07-1.197-.07h-1.11L8.587 6h1.723c.558 0 1.042.032 1.45.095.416.063.794.173 1.136.33l4.483 2.033-.33 1.67-2.625-1.165a1.867 1.867 0 0 0-.433-.134 2.45 2.45 0 0 0-.576-.06 4.88 4.88 0 0 0-1.663.28c-.526.19-1 .46-1.427.812-.42.35-.776.78-1.07 1.283a5.48 5.48 0 0 0-.63 1.71c-.24 1.255-.15 2.21.27 2.87.424.65 1.19.976 2.292.976.55 0 1.044-.08 1.48-.236a3.488 3.488 0 0 0 1.135-.66c.325-.29.59-.634.795-1.034.21-.4.363-.84.458-1.322l.11-.56h1.6l-.12.59a5.925 5.925 0 0 1-.676 1.844 5.19 5.19 0 0 1-1.214 1.423c-.488.395-1.053.7-1.694.923a6.573 6.573 0 0 1-2.106.324c-.767 0-1.434-.114-2-.34-.568-.226-1.025-.554-1.372-.985-.347-.437-.573-.97-.678-1.608-.105-.64-.078-1.366.08-2.186.125-.66.346-1.274.66-1.836A6.332 6.332 0 0 1 8.792 9.54a5.955 5.955 0 0 1 1.496-1.072 5.87 5.87 0 0 1 1.732-.57l-.465-.23"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-c">
<path id="c" d="M15.008 13.718l1.48.214c-.467 1.34-1.15 2.354-2.045 3.04a4.835 4.835 0 0 1-3.015 1.03c-1.36 0-2.438-.43-3.237-1.29C7.4 15.85 7 14.618 7 13.012c0-2.09.606-3.817 1.817-5.184C9.897 6.61 11.237 6 12.84 6c1.186 0 2.145.33 2.878.99.738.66 1.165 1.546 1.282 2.66l-1.397.135c-.148-.84-.453-1.464-.916-1.876-.458-.42-1.05-.63-1.78-.63-1.368 0-2.475.63-3.32 1.89-.733 1.087-1.1 2.377-1.1 3.87 0 1.194.283 2.104.848 2.732.565.628 1.3.942 2.206.942.78 0 1.48-.26 2.1-.785.63-.52 1.08-1.26 1.37-2.216"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-c">
+ <path id="c" d="M15.008 13.718l1.48.214c-.467 1.34-1.15 2.354-2.045 3.04a4.835 4.835 0 0 1-3.015 1.03c-1.36 0-2.438-.43-3.237-1.29C7.4 15.85 7 14.618 7 13.012c0-2.09.606-3.817 1.817-5.184C9.897 6.61 11.237 6 12.84 6c1.186 0 2.145.33 2.878.99.738.66 1.165 1.546 1.282 2.66l-1.397.135c-.148-.84-.453-1.464-.916-1.876-.458-.42-1.05-.63-1.78-.63-1.368 0-2.475.63-3.32 1.89-.733 1.087-1.1 2.377-1.1 3.87 0 1.194.283 2.104.848 2.732.565.628 1.3.942 2.206.942.78 0 1.48-.26 2.1-.785.63-.52 1.08-1.26 1.37-2.216"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-d">
<path id="d" d="M7 18L9.462 6h3.557c.85 0 1.5.063 1.95.188.642.17 1.192.472 1.65.91.454.43.8.97 1.03 1.62.23.65.344 1.378.344 2.186 0 .966-.146 1.847-.436 2.644-.284.79-.66 1.49-1.127 2.095-.46.6-.946 1.072-1.455 1.416-.504.33-1.1.582-1.794.75-.525.122-1.17.19-1.94.19H7m1.86-1.36h1.866c.842 0 1.59-.08 2.245-.24a3.26 3.26 0 0 0 1.05-.436 4.19 4.19 0 0 0 1.04-.975 6.652 6.652 0 0 0 .975-1.825c.247-.687.37-1.467.37-2.34 0-.97-.166-1.716-.5-2.235-.332-.522-.755-.87-1.27-1.04-.38-.124-.974-.186-1.78-.186H11L9.095 16.64"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-d">
+ <path id="d" d="M7 18L9.462 6h3.557c.85 0 1.5.063 1.95.188.642.17 1.192.472 1.65.91.454.43.8.97 1.03 1.62.23.65.344 1.378.344 2.186 0 .966-.146 1.847-.436 2.644-.284.79-.66 1.49-1.127 2.095-.46.6-.946 1.072-1.455 1.416-.504.33-1.1.582-1.794.75-.525.122-1.17.19-1.94.19H7m1.86-1.36h1.866c.842 0 1.59-.08 2.245-.24a3.26 3.26 0 0 0 1.05-.436 4.19 4.19 0 0 0 1.04-.975 6.652 6.652 0 0 0 .975-1.825c.247-.687.37-1.467.37-2.34 0-.97-.166-1.716-.5-2.235-.332-.522-.755-.87-1.27-1.04-.38-.124-.974-.186-1.78-.186H11L9.095 16.64"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-e">
<path id="e" d="M7 18L9.474 6H18l-.282 1.367H10.77L10.02 11h6.09l-.28 1.367H9.74l-.88 4.273h7.44L16.018 18H7"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-e">
+ <path id="e" d="M7 18L9.474 6H18l-.282 1.367H10.77L10.02 11h6.09l-.28 1.367H9.74l-.88 4.273h7.44L16.018 18H7"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-geor-kan">
<path id="geor-kan" d="M15.057 14.663C14.617 16.888 13.223 18 10.88 18 8.96 18 8 17.213 8 15.64c0-.298.036-.624.108-.977.083-.43.245-.836.488-1.217l1.24.605-.206.62c-.055.26-.083.497-.083.71 0 .97.52 1.46 1.564 1.46 1.31 0 2.108-.724 2.39-2.17l.058-.33a3.17 3.17 0 0 0 .066-.615c0-.927-.546-1.39-1.64-1.39H10.87l.247-1.26h1.118c1.203-.004 1.91-.55 2.12-1.64.04-.18.057-.355.057-.52 0-1.144-.9-1.715-2.696-1.715L11.94 6C14.646 6 16 6.877 16 8.627c0 .248-.027.516-.082.803-.204 1.092-1.05 1.824-2.54 2.194l-.033.166c1.23.2 1.845.823 1.845 1.872 0 .21-.025.433-.074.67l-.058.332"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-geor-kan">
+ <path id="geor-kan" d="M15.057 14.663C14.617 16.888 13.223 18 10.88 18 8.96 18 8 17.213 8 15.64c0-.298.036-.624.108-.977.083-.43.245-.836.488-1.217l1.24.605-.206.62c-.055.26-.083.497-.083.71 0 .97.52 1.46 1.564 1.46 1.31 0 2.108-.724 2.39-2.17l.058-.33a3.17 3.17 0 0 0 .066-.615c0-.927-.546-1.39-1.64-1.39H10.87l.247-1.26h1.118c1.203-.004 1.91-.55 2.12-1.64.04-.18.057-.355.057-.52 0-1.144-.9-1.715-2.696-1.715L11.94 6C14.646 6 16 6.877 16 8.627c0 .248-.027.516-.082.803-.204 1.092-1.05 1.824-2.54 2.194l-.033.166c1.23.2 1.845.823 1.845 1.872 0 .21-.025.433-.074.67l-.058.332"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-i">
<path id="i" d="M12.5 18l.25-.995h-1.5l2.508-10.037h1.5L15.5 6h-5l-.242.968h1.5l-2.51 10.037h-1.5L7.5 18z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-i">
+ <path id="i" d="M12.5 18l.25-.995h-1.5l2.508-10.037h1.5L15.5 6h-5l-.242.968h1.5l-2.51 10.037h-1.5L7.5 18z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-k">
<path id="k" d="M12.018 10.652L17 6h-2l-5.31 5.234L11 6H9.5l-3 12H8l1.173-4.693 1.54-1.438C11 16 14 18 14 18h2s-4-2-3.982-7.348z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-k">
+ <path id="k" d="M12.018 10.652L17 6h-2l-5.31 5.234L11 6H9.5l-3 12H8l1.173-4.693 1.54-1.438C11 16 14 18 14 18h2s-4-2-3.982-7.348z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="italic-s">
<path id="s" d="M16.474 6.59l-.302 1.525a7.36 7.36 0 0 0-1.557-.628 5.432 5.432 0 0 0-1.487-.217c-.935 0-1.68.204-2.23.612-.554.408-.83.95-.83 1.627 0 .37.1.65.302.86.207.19.733.4 1.58.63l.937.23c1.06.274 1.795.622 2.208 1.046.413.42.62 1.007.62 1.766 0 1.167-.46 2.117-1.38 2.85-.913.734-2.12 1.1-3.617 1.1-.615 0-1.232-.06-1.852-.185-.62-.12-1.242-.3-1.867-.55l.31-1.61a7.613 7.613 0 0 0 1.72.805c.58.18 1.155.27 1.73.27.976 0 1.76-.216 2.347-.65.59-.434.883-1 .883-1.697 0-.465-.12-.816-.354-1.054-.233-.242-.737-.46-1.512-.657l-.937-.24c-1.07-.28-1.8-.6-2.19-.964-.39-.368-.584-.88-.584-1.535 0-1.152.442-2.094 1.325-2.828.89-.74 2.043-1.108 3.463-1.108.555 0 1.1.05 1.644.146.542.1 1.085.245 1.627.442"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="italic-s">
+ <path id="s" d="M16.474 6.59l-.302 1.525a7.36 7.36 0 0 0-1.557-.628 5.432 5.432 0 0 0-1.487-.217c-.935 0-1.68.204-2.23.612-.554.408-.83.95-.83 1.627 0 .37.1.65.302.86.207.19.733.4 1.58.63l.937.23c1.06.274 1.795.622 2.208 1.046.413.42.62 1.007.62 1.766 0 1.167-.46 2.117-1.38 2.85-.913.734-2.12 1.1-3.617 1.1-.615 0-1.232-.06-1.852-.185-.62-.12-1.242-.3-1.867-.55l.31-1.61a7.613 7.613 0 0 0 1.72.805c.58.18 1.155.27 1.73.27.976 0 1.76-.216 2.347-.65.59-.434.883-1 .883-1.697 0-.465-.12-.816-.354-1.054-.233-.242-.737-.46-1.512-.657l-.937-.24c-1.07-.28-1.8-.6-2.19-.964-.39-.368-.584-.88-.584-1.535 0-1.152.442-2.094 1.325-2.828.89-.74 2.043-1.108 3.463-1.108.555 0 1.1.05 1.644.146.542.1 1.085.245 1.627.442"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 9V8h-6v1h6zm-2 2v-1h-4v1h4zM6 5h1v16H6V5zm2 0h10v13c0 1.7-1.3 3-3 3H8V5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 9V8h-6v1h6zm-2 2v-1h-4v1h4zM6 5h1v16H6V5zm2 0h10v13c0 1.7-1.3 3-3 3H8V5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M8 9V8h6v1H8zm2 2v-1h4v1h-4zm8-6h-1v16h1V5zm-2 0H6v13c0 1.7 1.3 3 3 3h7V5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M8 9V8h6v1H8zm2 2v-1h4v1h-4zm8-6h-1v16h1V5zm-2 0H6v13c0 1.7 1.3 3 3 3h7V5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M14.5 4C11.5 4 9 6.5 9 9.5c0 1 .3 1.9.7 2.8L4 18v2h4v-2h2v-2h2l1.2-1.2c.4.1.9.2 1.3.2 3 0 5.5-2.5 5.5-5.5S17.5 4 14.5 4zM16 9c-.8 0-1.5-.7-1.5-1.5S15.2 6 16 6s1.5.7 1.5 1.5S16.8 9 16 9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M14.5 4C11.5 4 9 6.5 9 9.5c0 1 .3 1.9.7 2.8L4 18v2h4v-2h2v-2h2l1.2-1.2c.4.1.9.2 1.3.2 3 0 5.5-2.5 5.5-5.5S17.5 4 14.5 4zM16 9c-.8 0-1.5-.7-1.5-1.5S15.2 6 16 6s1.5.7 1.5 1.5S16.8 9 16 9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9.5 4c3 0 5.5 2.5 5.5 5.5 0 1-.3 1.9-.7 2.8L20 18v2h-4v-2h-2v-2h-2l-1.2-1.2c-.4.1-.9.2-1.3.2-3 0-5.5-2.5-5.5-5.5S6.5 4 9.5 4zM8 9c.8 0 1.5-.7 1.5-1.5S8.8 6 8 6s-1.5.7-1.5 1.5S7.2 9 8 9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9.5 4c3 0 5.5 2.5 5.5 5.5 0 1-.3 1.9-.7 2.8L20 18v2h-4v-2h-2v-2h-2l-1.2-1.2c-.4.1-.9.2-1.3.2-3 0-5.5-2.5-5.5-5.5S6.5 4 9.5 4zM8 9c.8 0 1.5-.7 1.5-1.5S8.8 6 8 6s-1.5.7-1.5 1.5S7.2 9 8 9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3 7v9c0 1.7 1.3 3 3 3h15V7H3zm8 2h2v2h-2V9zm0 3h2v2h-2v-2zM8 9h2v2H8V9zm0 3h2v2H8v-2zm-1 5H6c-.6 0-1-.4-1-1v-1h2v2zm0-3H5v-2h2v2zm0-3H5V9h2v2zm9 6H8v-2h8v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2zm3 6h-2v-2h2v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3 7v9c0 1.7 1.3 3 3 3h15V7H3zm8 2h2v2h-2V9zm0 3h2v2h-2v-2zM8 9h2v2H8V9zm0 3h2v2H8v-2zm-1 5H6c-.6 0-1-.4-1-1v-1h2v2zm0-3H5v-2h2v2zm0-3H5V9h2v2zm9 6H8v-2h8v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2zm3 6h-2v-2h2v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 7v9c0 1.7-1.3 3-3 3H3V7h18zm-8 2h-2v2h2V9zm0 3h-2v2h2v-2zm3-3h-2v2h2V9zm0 3h-2v2h2v-2zm1 5h1c.6 0 1-.4 1-1v-1h-2v2zm0-3h2v-2h-2v2zm0-3h2V9h-2v2zm-9 6h8v-2H8v2zm0-3h2v-2H8v2zm0-3h2V9H8v2zm-3 6h2v-2H5v2zm0-3h2v-2H5v2zm0-3h2V9H5v2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 7v9c0 1.7-1.3 3-3 3H3V7h18zm-8 2h-2v2h2V9zm0 3h-2v2h2v-2zm3-3h-2v2h2V9zm0 3h-2v2h2v-2zm1 5h1c.6 0 1-.4 1-1v-1h-2v2zm0-3h2v-2h-2v2zm0-3h2V9h-2v2zm-9 6h8v-2H8v2zm0-3h2v-2H8v2zm0-3h2V9H8v2zm-3 6h2v-2H5v2zm0-3h2v-2H5v2zm0-3h2V9H5v2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="A">
<path d="M18.738 15.673l1.137 3.15h1.575L17.775 7.448h-2.188l-3.85 11.375h1.575l1.05-3.15h4.375zM16.55 8.76l1.837 5.427h-3.675l1.838-5.425z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="A">
+ <path d="M18.738 15.673l1.137 3.15h1.575L17.775 7.448h-2.188l-3.85 11.375h1.575l1.05-3.15h4.375zM16.55 8.76l1.837 5.427h-3.675l1.838-5.425z"/>
+ </g>
+ <g id="文">
+ <path d="M8.325 6.573h.787l-.875-1.75h-1.75l.438.875a1.56 1.56 0 0 0 1.4.875z"/>
+ <path d="m 9.202,12.874 c 0.7,0.525 1.486,0.963 2.45,1.225 l -0.438,1.31 A 9.17,9.17 0 0 1 8.151,13.835 c -1.49,1.137 -3.063,1.837 -4.813,2.363 L 2.9,14.885 C 4.386,14.36 5.874,13.835 7.1,12.872 5.962,11.648 5.174,10.335 4.65,8.758 l -1.663,0 0,-1.31 10.85,0 -0.438,1.312 -1.75,0 c -0.308,1.33 -1.255,2.957 -2.45,4.114 z m 1.05,-4.114 -4.114,0 c 0.35,1.226 1.138,2.363 2.013,3.238 0.926,-1 1.617,-1.957 2.1,-3.237 z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="A">
<path d="M5.612 15.673l-1.137 3.15H2.9L6.575 7.448h2.188l3.85 11.375h-1.575l-1.05-3.15H5.613zM7.8 8.76l-1.837 5.427h3.675L7.8 8.762z" id="path5"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="A">
+ <path d="M5.612 15.673l-1.137 3.15H2.9L6.575 7.448h2.188l3.85 11.375h-1.575l-1.05-3.15H5.613zM7.8 8.76l-1.837 5.427h3.675L7.8 8.762z" id="path5"/>
+ </g>
+ <g id="文">
+ <path d="M16.384 6.573h.787l-.873-1.75h-1.75l.438.875c.26.535.805.874 1.4.875z" id="path7"/>
+ <path d="M15.15 12.874c-.7.525-1.486.963-2.45 1.225l.438 1.31a9.17 9.17 0 0 0 3.063-1.575c1.49 1.137 3.064 1.837 4.814 2.363l.438-1.313c-1.486-.525-2.974-1.05-4.2-2.013 1.138-1.224 1.926-2.537 2.45-4.114h1.663v-1.31h-10.85l.438 1.312h1.75c.308 1.33 1.255 2.957 2.45 4.114zM14.1 8.76h4.114c-.35 1.226-1.138 2.363-2.013 3.238-.925-1-1.616-1.957-2.1-3.237z" id="path11-7"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="layout-ltr">
<path id="text" d="M5 19V5h6v8h8v6H5z"/>
<path id="float" d="M13 5v6h6V5h-6zm5 5h-4V6h4v4z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="layout-ltr">
+ <path id="text" d="M5 19V5h6v8h8v6H5z"/>
+ <path id="float" d="M13 5v6h6V5h-6zm5 5h-4V6h4v4z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="layout-rtl">
<path id="text" d="M5 19v-6h8V5h6v14H5z"/>
<path id="float" d="M5 5v6h6V5H5zm1 1h4v4H6V6z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="layout-rtl">
+ <path id="text" d="M5 19v-6h8V5h6v14H5z"/>
+ <path id="float" d="M5 5v6h6V5H5zm1 1h4v4H6V6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15.387 4.33c-2.1 0-3.6 1.9-5.1 3.3.2 0 .5-.1.8-.1.5 0 1 .1 1.5.3.8-.8 1.6-1.7 2.8-1.7.6 0 1.3.3 1.8.7 1 1 1 2.6 0 3.6l-2.6 2.6c-.4.4-1.2.7-1.8.7-1.4 0-2.1-.9-2.6-2l-1.3 1.3c.8 1.5 2 2.6 3.8 2.6 1.2 0 2.3-.5 3-1.3l2.6-2.6c.9-.9 1.5-2 1.5-3.3-.2-2.2-2.2-4.1-4.4-4.1zm-4.3 12.1l-.9.9c-.4.4-1.2.7-1.8.7-.6 0-1.3-.3-1.8-.7-1-1-1-2.7 0-3.6l2.6-2.6c.4-.4 1.2-.7 1.8-.7 1.4 0 2.1 1 2.6 2l1.3-1.3c-.8-1.5-2-2.6-3.8-2.6-1.2 0-2.3.5-3 1.3l-2.6 2.6c-1.7 1.7-1.7 4.4 0 6 1.6 1.6 4.4 1.7 5.9 0l1.9-1.9c-.3.1-.6.1-.9.1-.5 0-.9 0-1.3-.2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15.387 4.33c-2.1 0-3.6 1.9-5.1 3.3.2 0 .5-.1.8-.1.5 0 1 .1 1.5.3.8-.8 1.6-1.7 2.8-1.7.6 0 1.3.3 1.8.7 1 1 1 2.6 0 3.6l-2.6 2.6c-.4.4-1.2.7-1.8.7-1.4 0-2.1-.9-2.6-2l-1.3 1.3c.8 1.5 2 2.6 3.8 2.6 1.2 0 2.3-.5 3-1.3l2.6-2.6c.9-.9 1.5-2 1.5-3.3-.2-2.2-2.2-4.1-4.4-4.1zm-4.3 12.1l-.9.9c-.4.4-1.2.7-1.8.7-.6 0-1.3-.3-1.8-.7-1-1-1-2.7 0-3.6l2.6-2.6c.4-.4 1.2-.7 1.8-.7 1.4 0 2.1 1 2.6 2l1.3-1.3c-.8-1.5-2-2.6-3.8-2.6-1.2 0-2.3.5-3 1.3l-2.6 2.6c-1.7 1.7-1.7 4.4 0 6 1.6 1.6 4.4 1.7 5.9 0l1.9-1.9c-.3.1-.6.1-.9.1-.5 0-.9 0-1.3-.2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9.025 3.6c2.1 0 3.6 1.9 5.1 3.3-.2 0-.5-.1-.8-.1-.5 0-1 .1-1.5.3-.8-.8-1.6-1.7-2.8-1.7-.6 0-1.3.3-1.8.7-1 1-1 2.6 0 3.6l2.6 2.6c.4.4 1.2.7 1.8.7 1.4 0 2.1-.9 2.6-2l1.3 1.3c-.8 1.5-2 2.6-3.8 2.6-1.2 0-2.3-.5-3-1.3l-2.6-2.6c-.9-.9-1.5-2-1.5-3.3.2-2.2 2.2-4.1 4.4-4.1zm4.3 12.1l.9.9c.4.4 1.2.7 1.8.7.6 0 1.3-.3 1.8-.7 1-1 1-2.7 0-3.6l-2.6-2.6c-.4-.4-1.2-.7-1.8-.7-1.4 0-2.1 1-2.6 2l-1.3-1.3c.8-1.5 2-2.6 3.8-2.6 1.2 0 2.3.5 3 1.3l2.6 2.6c1.7 1.7 1.7 4.4 0 6-1.6 1.6-4.4 1.7-5.9 0l-1.9-1.9c.3.1.6.1.9.1.5 0 .9 0 1.3-.2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9.025 3.6c2.1 0 3.6 1.9 5.1 3.3-.2 0-.5-.1-.8-.1-.5 0-1 .1-1.5.3-.8-.8-1.6-1.7-2.8-1.7-.6 0-1.3.3-1.8.7-1 1-1 2.6 0 3.6l2.6 2.6c.4.4 1.2.7 1.8.7 1.4 0 2.1-.9 2.6-2l1.3 1.3c-.8 1.5-2 2.6-3.8 2.6-1.2 0-2.3-.5-3-1.3l-2.6-2.6c-.9-.9-1.5-2-1.5-3.3.2-2.2 2.2-4.1 4.4-4.1zm4.3 12.1l.9.9c.4.4 1.2.7 1.8.7.6 0 1.3-.3 1.8-.7 1-1 1-2.7 0-3.6l-2.6-2.6c-.4-.4-1.2-.7-1.8-.7-1.4 0-2.1 1-2.6 2l-1.3-1.3c.8-1.5 2-2.6 3.8-2.6 1.2 0 2.3.5 3 1.3l2.6 2.6c1.7 1.7 1.7 4.4 0 6-1.6 1.6-4.4 1.7-5.9 0l-1.9-1.9c.3.1.6.1.9.1.5 0 .9 0 1.3-.2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 7H9V5h12v2zM7 6c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm14 7H9v-2h12v2zM7 12c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm14 7H9v-2h12v2zM7 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 7H9V5h12v2zM7 6c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm14 7H9v-2h12v2zM7 12c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm14 7H9v-2h12v2zM7 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3 7h12V5H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zM3 13h12v-2H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zM3 19h12v-2H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3 7h12V5H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zM3 13h12v-2H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zM3 19h12v-2H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 7H8V5h13v2zm0 6H8v-2h13v2zm0 6H8v-2h13v2zM4 4h2v4H5V5H4zm-1 6V9h3v3H4v1h2v1H3v-3h2v-1zm3 10H3v-1h2v-1H4v-1h1v-1H3v-1h3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 7H8V5h13v2zm0 6H8v-2h13v2zm0 6H8v-2h13v2zM4 4h2v4H5V5H4zm-1 6V9h3v3H4v1h2v1H3v-3h2v-1zm3 10H3v-1h2v-1H4v-1h1v-1H3v-1h3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3 7h13V5H3zm0 6h13v-2H3zm0 6h13v-2H3zM18 4h2v4h-1V5h-1zm0 6V9h3v3h-2v1h2v1h-3v-3h2v-1zm3 10h-3v-1h2v-1h-1v-1h1v-1h-2v-1h3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3 7h13V5H3zm0 6h13v-2H3zm0 6h13v-2H3zM18 4h2v4h-1V5h-1zm0 6V9h3v3h-2v1h2v1h-3v-3h2v-1zm3 10h-3v-1h2v-1h-1v-1h1v-1h-2v-1h3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M15 8s0-3-2.5-3S10 8 10 8v1h5zm2 0v1h2v10H9c-1.7 0-3-1.3-3-3V9h2V8s0-5 4.5-5S17 8 17 8z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 8s0-3-2.5-3S10 8 10 8v1h5zm2 0v1h2v10H9c-1.7 0-3-1.3-3-3V9h2V8s0-5 4.5-5S17 8 17 8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 8s0-3-2.5-3S10 8 10 8v1h5zm2 0v1h2v10H9c-1.7 0-3-1.3-3-3V9h2V8s0-5 4.5-5S17 8 17 8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M10 8s0-3 2.5-3S15 8 15 8v1h-5zM8 8v1H6v10h10c1.7 0 3-1.3 3-3V9h-2V8s0-5-4.5-5S8 8 8 8z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M10 8s0-3 2.5-3S15 8 15 8v1h-5zM8 8v1H6v10h10c1.7 0 3-1.3 3-3V9h-2V8s0-5-4.5-5S8 8 8 8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M10 8s0-3 2.5-3S15 8 15 8v1h-5zM8 8v1H6v10h10c1.7 0 3-1.3 3-3V9h-2V8s0-5-4.5-5S8 8 8 8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 14v3l5-4.5L15 8v3H8c0 1.7 1.3 3 3 3h4zm-1-9H4v15h10v-2H6V7h8V5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 14v3l5-4.5L15 8v3H8c0 1.7 1.3 3 3 3h4zm-1-9H4v15h10v-2H6V7h8V5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9 14v3l-5-4.5L9 8v3h7c0 1.7-1.3 3-3 3H9zm1-9h10v15H10v-2h8V7h-8V5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9 14v3l-5-4.5L9 8v3h7c0 1.7-1.3 3-3 3H9zm1-9h10v15H10v-2h8V7h-8V5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 6c-3.9 0-7 3.1-7 7s3.1 7 7 7 7-3.1 7-7-3.1-7-7-7zm0 13c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6zm-1.7-4.6c-.7 0-1-.4-1-1.2s.3-1.2 1-1.2c.4 0 .6.2.8.6l.9-.5c-.4-.7-1-1-1.9-1-.6 0-1.1.2-1.5.6s-.6.8-.6 1.5.2 1.2.6 1.6c.4.4.9.6 1.5.6.8 0 1.4-.4 1.9-1.1l-.9-.4c-.2.3-.5.5-.8.5zm4 0c-.7 0-1-.4-1-1.2s.3-1.2 1-1.2c.4 0 .6.2.8.6l.9-.5c-.4-.7-1-1-1.9-1-.6 0-1.1.2-1.5.6s-.6.8-.6 1.5.2 1.2.6 1.6c.4.4.9.6 1.5.6.8 0 1.4-.4 1.9-1.1l-.9-.4c-.2.3-.5.5-.8.5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 6c-3.9 0-7 3.1-7 7s3.1 7 7 7 7-3.1 7-7-3.1-7-7-7zm0 13c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6zm-1.7-4.6c-.7 0-1-.4-1-1.2s.3-1.2 1-1.2c.4 0 .6.2.8.6l.9-.5c-.4-.7-1-1-1.9-1-.6 0-1.1.2-1.5.6s-.6.8-.6 1.5.2 1.2.6 1.6c.4.4.9.6 1.5.6.8 0 1.4-.4 1.9-1.1l-.9-.4c-.2.3-.5.5-.8.5zm4 0c-.7 0-1-.4-1-1.2s.3-1.2 1-1.2c.4 0 .6.2.8.6l.9-.5c-.4-.7-1-1-1.9-1-.6 0-1.1.2-1.5.6s-.6.8-.6 1.5.2 1.2.6 1.6c.4.4.9.6 1.5.6.8 0 1.4-.4 1.9-1.1l-.9-.4c-.2.3-.5.5-.8.5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15.4 7.8c-2-.9-2.3-2.5-2.4-2.8.1.1 2 1 2 1l-3-5-3 5 2-1s0 .8.6 2.1c.8 1.5 2.2 2.2 2.2 2.2s1.6.7 2.2 1.3l-.7.7-.5-.5-.4 1.8 1.8-.4-.5-.5.7-.7c.9 1 1.5 2.3 1.6 3.8h-1V14l-1.5 1 1.5 1v-.8h1c-.1 1.5-.6 2.8-1.6 3.8l-.7-.7.5-.5-1.8-.4.4 1.8.5-.5.7.7c-1 .9-2.3 1.5-3.8 1.6v-1h.8l-1-1.5-1 1.5h.8v1c-1.5-.1-2.8-.6-3.8-1.6l.7-.7.5.5.4-1.8-1.8.4.5.5-.7.7c-.9-1-1.5-2.3-1.6-3.8h1v.8l1.5-1L7 14v.8H6c.1-1.5.6-2.8 1.6-3.8l.7.7-.5.5 1.8.4-.4-1.8-.5.5-.7-.7-1.5-1.4A7.99 7.99 0 0 0 4 15c0 4.4 3.6 8 8 8s8-3.6 8-8c0-3.2-1.9-5.9-4.6-7.2z"/>
<circle cx="12" cy="15" r="3"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15.4 7.8c-2-.9-2.3-2.5-2.4-2.8.1.1 2 1 2 1l-3-5-3 5 2-1s0 .8.6 2.1c.8 1.5 2.2 2.2 2.2 2.2s1.6.7 2.2 1.3l-.7.7-.5-.5-.4 1.8 1.8-.4-.5-.5.7-.7c.9 1 1.5 2.3 1.6 3.8h-1V14l-1.5 1 1.5 1v-.8h1c-.1 1.5-.6 2.8-1.6 3.8l-.7-.7.5-.5-1.8-.4.4 1.8.5-.5.7.7c-1 .9-2.3 1.5-3.8 1.6v-1h.8l-1-1.5-1 1.5h.8v1c-1.5-.1-2.8-.6-3.8-1.6l.7-.7.5.5.4-1.8-1.8.4.5.5-.7.7c-.9-1-1.5-2.3-1.6-3.8h1v.8l1.5-1L7 14v.8H6c.1-1.5.6-2.8 1.6-3.8l.7.7-.5.5 1.8.4-.4-1.8-.5.5-.7-.7-1.5-1.4A7.99 7.99 0 0 0 4 15c0 4.4 3.6 8 8 8s8-3.6 8-8c0-3.2-1.9-5.9-4.6-7.2z"/>
+ <circle cx="12" cy="15" r="3"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M22.3 6.3c0 .2 0 .3-.1.3-.7.1-1.2.5-1.6 1.1-.1.2-.2.4-.3.7l-4.6 10.1c-.1.2-.2.3-.2.3s-.1.1-.2.1c-.2 0-.4-.1-.5-.4L12.2 13l-2.8 5.5c-.1.3-.3.4-.5.4s-.4-.1-.5-.4L4.1 8.4c-.3-.8-.6-1.2-.8-1.4-.2-.2-.5-.3-1-.4-.1-.1-.1-.2-.1-.3 0-.2 0-.3.1-.3h4.3c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.6.1-1 .2-1.1.4-.1.2 0 .6.3 1.2l3.6 8.2h.1l2.2-4.4L10 8.4c-.3-.7-.6-1.2-.8-1.4s-.5-.3-.9-.4c-.1-.1-.1-.2-.1-.3 0-.2 0-.3.1-.3h3.6c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.4.1-.6.2-.6.4s.1.6.4 1.2l1 1.9 1-1.9c.3-.6.5-.9.5-1.1 0-.2 0-.3-.1-.4-.1-.1-.3-.1-.5-.1l-.1-.3c0-.2 0-.3.1-.3h3c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.5.1-.8.2-1.1.5-.3.3-.6.7-.8 1.3l-1.3 2.8 2.5 5.2h.1l3.7-8.1c.3-.5.3-.9.2-1.2-.1-.3-.5-.4-1.1-.5-.1-.1-.1-.2-.1-.3s0-.3.1-.3h3.7c-.2.1-.2.2-.2.3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M22.3 6.3c0 .2 0 .3-.1.3-.7.1-1.2.5-1.6 1.1-.1.2-.2.4-.3.7l-4.6 10.1c-.1.2-.2.3-.2.3s-.1.1-.2.1c-.2 0-.4-.1-.5-.4L12.2 13l-2.8 5.5c-.1.3-.3.4-.5.4s-.4-.1-.5-.4L4.1 8.4c-.3-.8-.6-1.2-.8-1.4-.2-.2-.5-.3-1-.4-.1-.1-.1-.2-.1-.3 0-.2 0-.3.1-.3h4.3c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.6.1-1 .2-1.1.4-.1.2 0 .6.3 1.2l3.6 8.2h.1l2.2-4.4L10 8.4c-.3-.7-.6-1.2-.8-1.4s-.5-.3-.9-.4c-.1-.1-.1-.2-.1-.3 0-.2 0-.3.1-.3h3.6c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.4.1-.6.2-.6.4s.1.6.4 1.2l1 1.9 1-1.9c.3-.6.5-.9.5-1.1 0-.2 0-.3-.1-.4-.1-.1-.3-.1-.5-.1l-.1-.3c0-.2 0-.3.1-.3h3c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.5.1-.8.2-1.1.5-.3.3-.6.7-.8 1.3l-1.3 2.8 2.5 5.2h.1l3.7-8.1c.3-.5.3-.9.2-1.2-.1-.3-.5-.4-1.1-.5-.1-.1-.1-.2-.1-.3s0-.3.1-.3h3.7c-.2.1-.2.2-.2.3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 6L9 4 3 6v15l6-2 6 2 6-2V4l-6 2zM8.7 18.1L4 19.6V6.7L9 5v12.9l-.3.2zm11.3.2L15 20V7.1l.3-.1L20 5.4v12.9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 6L9 4 3 6v15l6-2 6 2 6-2V4l-6 2zM8.7 18.1L4 19.6V6.7L9 5v12.9l-.3.2zm11.3.2L15 20V7.1l.3-.1L20 5.4v12.9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9 6l6-2 6 2v15l-6-2-6 2-6-2V4l6 2zm6.3 12.1l4.7 1.5V6.7L15 5v12.9l.3.2zM4 18.3L9 20V7.1L8.7 7 4 5.4v12.9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9 6l6-2 6 2v15l-6-2-6 2-6-2V4l6 2zm6.3 12.1l4.7 1.5V6.7L15 5v12.9l.3.2zM4 18.3L9 20V7.1L8.7 7 4 5.4v12.9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M19 12c0-3.9-3.1-7-7-7s-7 3.1-7 7c0 1.4.4 2.6 1.1 3.7L12 23l5.9-7.3c.7-1.1 1.1-2.3 1.1-3.7zm-7 4c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M19 12c0-3.9-3.1-7-7-7s-7 3.1-7 7c0 1.4.4 2.6 1.1 3.7L12 23l5.9-7.3c.7-1.1 1.1-2.3 1.1-3.7zm-7 4c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M24 4h-4V0h-2v4h-4v2h4v4h2V6h4z"/>
<path d="M18 11h-1V7.1l-.1-.1H13V5.1c-.3-.1-.7-.1-1-.1-3.9 0-7 3.1-7 7 0 1.4.4 2.6 1.1 3.7L12 23l5.9-7.3c.7-1.1 1.1-2.3 1.1-3.7 0-.3 0-.7-.1-1H18zm-6 5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M24 4h-4V0h-2v4h-4v2h4v4h2V6h4z"/>
+ <path d="M18 11h-1V7.1l-.1-.1H13V5.1c-.3-.1-.7-.1-1-.1-3.9 0-7 3.1-7 7 0 1.4.4 2.6 1.1 3.7L12 23l5.9-7.3c.7-1.1 1.1-2.3 1.1-3.7 0-.3 0-.7-.1-1H18zm-6 5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M0 4h4V0h2v4h4v2H6v4H4V6H0z"/>
<path d="M6 11h1V7.1l.1-.1H11V5.1c.3-.1.7-.1 1-.1 3.9 0 7 3.1 7 7 0 1.4-.4 2.6-1.1 3.7L12 23l-5.9-7.3C5.4 14.6 5 13.4 5 12c0-.3 0-.7.1-1H6zm6 5c2.2 0 4-1.8 4-4s-1.8-4-4-4-4 1.8-4 4 1.8 4 4 4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M0 4h4V0h2v4h4v2H6v4H4V6H0z"/>
+ <path d="M6 11h1V7.1l.1-.1H11V5.1c.3-.1.7-.1 1-.1 3.9 0 7 3.1 7 7 0 1.4-.4 2.6-1.1 3.7L12 23l-5.9-7.3C5.4 14.6 5 13.4 5 12c0-.3 0-.7.1-1H6zm6 5c2.2 0 4-1.8 4-4s-1.8-4-4-4-4 1.8-4 4 1.8 4 4 4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="markup">
<path id="left-bracket" d="M9.665 6.32l-4.259 4.274-1.406 1.406 1.406 1.406 4.259 4.274 1.406-1.438-4.259-4.243 4.259-4.243z"/>
<use transform="matrix(-1 0 0 1 24 0)" id="right-bracket" xlink:href="#left-bracket"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="markup">
+ <path id="left-bracket" d="M9.665 6.32l-4.259 4.274-1.406 1.406 1.406 1.406 4.259 4.274 1.406-1.438-4.259-4.243 4.259-4.243z"/>
+ <use transform="matrix(-1 0 0 1 24 0)" id="right-bracket" xlink:href="#left-bracket"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="menu">
<path id="lines" d="M6 15h12a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1zm-1-4v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1zm0-5v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="menu">
+ <path id="lines" d="M6 15h12a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1zm-1-4v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1zm0-5v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 9c0-1.7-1.3-3-3-3H3v3l9 4 9-4zM3 11v6c0 1.7 1.3 3 3 3h15v-9l-9 4-9-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M21 9c0-1.7-1.3-3-3-3H3v3l9 4 9-4zM3 11v6c0 1.7 1.3 3 3 3h15v-9l-9 4-9-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3 9c0-1.7 1.3-3 3-3h15v3l-9 4-9-4zm18 2v6c0 1.7-1.3 3-3 3H3v-9l9 4 9-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3 9c0-1.7 1.3-3 3-3h15v3l-9 4-9-4zm18 2v6c0 1.7-1.3 3-3 3H3v-9l9 4 9-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20 11l-4-3v2h-3V7h2l-3-4-3 4h2v3H8V8l-4 3 4 3v-2h3v3H9l3 4 3-4h-2v-3h3v2z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="move-ltr">
<path id="arrow" d="M8.935 7.18l5.302 5.303-5.302 5.303L10.35 19.2l6.715-6.717-6.716-6.716z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="move-ltr">
+ <path id="arrow" d="M8.935 7.18l5.302 5.303-5.302 5.303L10.35 19.2l6.715-6.717-6.716-6.716z"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20 11l-4-3v2h-3V7h2l-3-4-3 4h2v3H8V8l-4 3 4 3v-2h3v3H9l3 4 3-4h-2v-3h3v2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="move-rtl">
<path id="arrow" d="M15.065 17.786l-5.302-5.303 5.302-5.302-1.415-1.41-6.714 6.72 6.714 6.71z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="move-rtl">
+ <path id="arrow" d="M15.065 17.786l-5.302-5.303 5.302-5.302-1.415-1.41-6.714 6.72 6.714 6.71z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 5l2.5 2.5L11 11c-1.2 1.2-1.2 2.8 0 4l5.5-5.5L19 12V5h-7zm5 12H8c-.6 0-1-.4-1-1V7h3L8 5H5v11c0 1.7 1.3 3 3 3h11v-3l-2-2v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 5l2.5 2.5L11 11c-1.2 1.2-1.2 2.8 0 4l5.5-5.5L19 12V5h-7zm5 12H8c-.6 0-1-.4-1-1V7h3L8 5H5v11c0 1.7 1.3 3 3 3h11v-3l-2-2v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 5L9.5 7.5 13 11c1.2 1.2 1.2 2.8 0 4L7.5 9.5 5 12V5h7zM7 17h9c.6 0 1-.4 1-1V7h-3l2-2h3v11c0 1.7-1.3 3-3 3H5v-3l2-2v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 5L9.5 7.5 13 11c1.2 1.2 1.2 2.8 0 4L7.5 9.5 5 12V5h7zM7 17h9c.6 0 1-.4 1-1V7h-3l2-2h3v11c0 1.7-1.3 3-3 3H5v-3l2-2v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17.8 5.7c-.5 0-.9.2-1.2.5s-.5.7-.5 1.2v4.3H11v-4l-6 5.5 6 5.5v-4h8v-9h-1.2z" id="line_return"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M17.8 5.7c-.5 0-.9.2-1.2.5s-.5.7-.5 1.2v4.3H11v-4l-6 5.5 6 5.5v-4h8v-9h-1.2z" id="line_return"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M6.2 5.7c.5 0 .9.2 1.2.5.3.3.5.7.5 1.2v4.3H13v-4l6 5.5-6 5.5v-4H5v-9h1.2z" id="line_return"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M6.2 5.7c.5 0 .9.2 1.2.5.3.3.5.7.5 1.2v4.3H13v-4l6 5.5-6 5.5v-4H5v-9h1.2z" id="line_return"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M6 7v12c-.6 0-1-.4-1-1V9H4v9c0 1.1.9 2 2 2h15V7H6zm9 11H8v-1h7v1zm0-2H8v-1h7v1zm0-2H8v-1h7v1zm4 4h-3v-5h3v5zm0-7H8V9h11v2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M6 7v12c-.6 0-1-.4-1-1V9H4v9c0 1.1.9 2 2 2h15V7H6zm9 11H8v-1h7v1zm0-2H8v-1h7v1zm0-2H8v-1h7v1zm4 4h-3v-5h3v5zm0-7H8V9h11v2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M19 7v12c.6 0 1-.4 1-1V9h1v9c0 1.1-.9 2-2 2H4V7h15zm-9 11h7v-1h-7v1zm0-2h7v-1h-7v1zm0-2h7v-1h-7v1zm-4 4h3v-5H6v5zm0-7h11V9H6v2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M19 7v12c.6 0 1-.4 1-1V9h1v9c0 1.1-.9 2-2 2H4V7h15zm-9 11h7v-1h-7v1zm0-2h7v-1h-7v1zm0-2h7v-1h-7v1zm-4 4h3v-5H6v5zm0-7h11V9H6v2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 13l2 2V5h-3v2h1zM3 3L2 4l1 1v14h3v-2H5V7l2 2v10h3v-2H9v-6l6 6h-1v2h3l3 3 1-1-3-3zm7 4V5H7l2 2zm8-2v2h1v10l2 2V5z" id="noWikiText-rtl"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 13l2 2V5h-3v2h1zM3 3L2 4l1 1v14h3v-2H5V7l2 2v10h3v-2H9v-6l6 6h-1v2h3l3 3 1-1-3-3zm7 4V5H7l2 2zm8-2v2h1v10l2 2V5z" id="noWikiText-rtl"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9 13l-2 2V5h3v2H9zM21 3l1 1-1 1v14h-3v-2h1V7l-2 2v10h-3v-2h1v-6l-6 6h1v2H7l-3 3-1-1 3-3zm-7 4V5h3l-2 2zM6 5v2H5v10l-2 2V5z" id="noWikiText-rtl"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9 13l-2 2V5h3v2H9zM21 3l1 1-1 1v14h-3v-2h1V7l-2 2v10h-3v-2h1v-6l-6 6h1v2H7l-3 3-1-1 3-3zm-7 4V5h3l-2 2zM6 5v2H5v10l-2 2V5z" id="noWikiText-rtl"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="svg3116"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="svg3116"><style>* { fill: #fff }</style>
<path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm-1-5h2V8h-2zm0 3h2v-2h-2z" id="alert"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="svg3116"><style>* { fill: #36c }</style>
+ <path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm-1-5h2V8h-2zm0 3h2v-2h-2z" id="alert"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #ffffff }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #fff }</style>
<path d="M17.8 18.6H2.5l2.7-2.7V6h15.3v9.9c0 1.53-1.17 2.7-2.7 2.7zm-7.542-4.95c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #347bff }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #36c }</style>
<path d="M17.8 18.6H2.5l2.7-2.7V6h15.3v9.9c0 1.53-1.17 2.7-2.7 2.7zm-7.542-4.95c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #ffffff }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #fff }</style>
<path d="M5.2 18.6h15.3l-2.7-2.7V6H2.5v9.9c0 1.53 1.17 2.7 2.7 2.7zm7.542-4.95c0 .405.135.675.405.945.27.27.607.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.607-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.608-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.332 1.332 0 0 0-.945-.405c-.337 0-.675.135-.945.405-.27.27-.405.608-.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #347bff }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #36c }</style>
<path d="M5.2 18.6h15.3l-2.7-2.7V6H2.5v9.9c0 1.53 1.17 2.7 2.7 2.7zm7.542-4.95c0 .405.135.675.405.945.27.27.607.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.607-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.608-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.332 1.332 0 0 0-.945-.405c-.337 0-.675.135-.945.405-.27.27-.405.608-.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M10 8h9v2h-9V8zm0 3h9v2h-9v-2zm0 3h6v2h-6v-2zm11-8H3V4h18v2zm0 14H3v-2h18v2zM3 12l5 4V8l-5 4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M10 8h9v2h-9V8zm0 3h9v2h-9v-2zm0 3h6v2h-6v-2zm11-8H3V4h18v2zm0 14H3v-2h18v2zM3 12l5 4V8l-5 4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M14 8H5v2h9V8zm0 3H5v2h9v-2zm0 3H8v2h6v-2zM3 6h18V4H3v2zm0 14h18v-2H3v2zm18-8l-5 4V8l5 4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M14 8H5v2h9V8zm0 3H5v2h9v-2zm0 3H8v2h6v-2zM3 6h18V4H3v2zm0 14h18v-2H3v2zm18-8l-5 4V8l5 4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="outline-ltr">
<path id="text" d="M5 13h14v6H5v-6z"/>
<path id="float" d="M5 5v6h6V5H5zm5 5H6V6h4v4z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="outline-ltr">
+ <path id="text" d="M5 13h14v6H5v-6z"/>
+ <path id="float" d="M5 5v6h6V5H5zm5 5H6V6h4v4z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="outline-rtl">
<path id="text" d="M19 19H5v-6h14v6z"/>
<path id="float" d="M13 5v6h6V5h-6zm1 1h4v4h-4V6z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="outline-rtl">
+ <path id="text" d="M19 19H5v-6h14v6z"/>
+ <path id="float" d="M13 5v6h6V5h-6zm1 1h4v4h-4V6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm-2 12V9l6 4-6 4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm-2 12V9l6 4-6 4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 5c4.4 0 8 3.6 8 8s-3.6 8-8 8-8-3.6-8-8 3.6-8 8-8zm2 12V9l-6 4 6 4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 5c4.4 0 8 3.6 8 8s-3.6 8-8 8-8-3.6-8-8 3.6-8 8-8zm2 12V9l-6 4 6 4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M18 8h-1V4H7v4H3v6c0 1.7 1.3 3 3 3h1v3h10v-3h4v-6c0-1.7-1.3-3-3-3zM8 5h8v3H8V5zm8 14H8v-6h8v6z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M18 8h-1V4H7v4H3v6c0 1.7 1.3 3 3 3h1v3h10v-3h4v-6c0-1.7-1.3-3-3-3zM8 5h8v3H8V5zm8 14H8v-6h8v6z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M6 8h1V4h10v4h4v6c0 1.7-1.3 3-3 3h-1v3H7v-3H3v-6c0-1.7 1.3-3 3-3zm10-3H8v3h8V5zM8 19h8v-6H8v6z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M6 8h1V4h10v4h4v6c0 1.7-1.3 3-3 3h-1v3H7v-3H3v-6c0-1.7 1.3-3 3-3zm10-3H8v3h8V5zM8 19h8v-6H8v6z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M18 9.9c-.7 0-1.4.3-1.8.9V6h-4c.2-.4.4-.8.4-1.2 0-1.2-1-2.2-2.2-2.2-1.3-.1-2.3.9-2.3 2.2 0 .4.2.8.4 1.2H4.1v3.6l.6-.1c1.4 0 2.5 1.1 2.5 2.5s-1.1 2.5-2.5 2.5c-.2 0-.4 0-.6-.1V18H9c-.5.4-.9 1-.9 1.8 0 1.2 1 2.2 2.3 2.2 1.2 0 2.2-1 2.2-2.2 0-.7-.3-1.4-.9-1.8h4.5v-4.5c.4.5 1 .9 1.8.9 1.2 0 2.2-1 2.2-2.2 0-1.3-1-2.3-2.2-2.3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M18 9.9c-.7 0-1.4.3-1.8.9V6h-4c.2-.4.4-.8.4-1.2 0-1.2-1-2.2-2.2-2.2-1.3-.1-2.3.9-2.3 2.2 0 .4.2.8.4 1.2H4.1v3.6l.6-.1c1.4 0 2.5 1.1 2.5 2.5s-1.1 2.5-2.5 2.5c-.2 0-.4 0-.6-.1V18H9c-.5.4-.9 1-.9 1.8 0 1.2 1 2.2 2.3 2.2 1.2 0 2.2-1 2.2-2.2 0-.7-.3-1.4-.9-1.8h4.5v-4.5c.4.5 1 .9 1.8.9 1.2 0 2.2-1 2.2-2.2 0-1.3-1-2.3-2.2-2.3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M6.3 9.9c.7 0 1.4.3 1.8.9V6h4c-.2-.4-.4-.8-.4-1.2 0-1.2 1-2.2 2.2-2.2 1.3-.1 2.3.9 2.3 2.2 0 .4-.2.8-.4 1.2h4.4v3.6l-.6-.1c-1.4 0-2.5 1.1-2.5 2.5s1.1 2.5 2.5 2.5c.2 0 .4 0 .6-.1V18h-4.9c.5.4.9 1 .9 1.8 0 1.2-1 2.2-2.3 2.2-1.2 0-2.2-1-2.2-2.2 0-.7.3-1.4.9-1.8H8.1v-4.5c-.4.5-1 .9-1.8.9-1.2 0-2.2-1-2.2-2.2 0-1.3 1-2.3 2.2-2.3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M6.3 9.9c.7 0 1.4.3 1.8.9V6h4c-.2-.4-.4-.8-.4-1.2 0-1.2 1-2.2 2.2-2.2 1.3-.1 2.3.9 2.3 2.2 0 .4-.2.8-.4 1.2h4.4v3.6l-.6-.1c-1.4 0-2.5 1.1-2.5 2.5s1.1 2.5 2.5 2.5c.2 0 .4 0 .6-.1V18h-4.9c.5.4.9 1 .9 1.8 0 1.2-1 2.2-2.3 2.2-1.2 0-2.2-1-2.2-2.2 0-.7.3-1.4.9-1.8H8.1v-4.5c-.4.5-1 .9-1.8.9-1.2 0-2.2-1-2.2-2.2 0-1.3 1-2.3 2.2-2.3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="quotes">
<path id="quote" d="M6.9 8.4c-.446.55-1.974 2.6-1.9 5.7V17h4.7c.9 0 1.6-.7 1.6-1.6V11H8.2s.05-.74.6-1.4c.453-.543 1-.9 1.6-1.2.2-.1.47-.212.6-.5.127-.282.2-.5.2-.9v-.6c-1 .2-1.744.197-2.6.6-.856.403-1.272.873-1.7 1.4z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="quotes">
+ <path id="quote" d="M6.9 8.4c-.446.55-1.974 2.6-1.9 5.7V17h4.7c.9 0 1.6-.7 1.6-1.6V11H8.2s.05-.74.6-1.4c.453-.543 1-.9 1.6-1.2.2-.1.47-.212.6-.5.127-.282.2-.5.2-.9v-.6c-1 .2-1.744.197-2.6.6-.856.403-1.272.873-1.7 1.4z"/>
+ </g>
+ <use transform="translate(8)" id="quote2" width="24" height="24" xlink:href="#quote"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="quotes">
<path id="quote" d="M17.1 8.4c.446.55 1.9 2.6 1.9 5.7V17h-4.7c-.9 0-1.6-.7-1.6-1.6V11h3.1s-.05-.74-.6-1.4c-.453-.543-1-.9-1.6-1.2-.2-.1-.47-.212-.6-.5-.127-.282-.2-.5-.2-.9v-.6c1 .2 1.744.197 2.6.6.856.403 1.272.873 1.7 1.4z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="quotes">
+ <path id="quote" d="M17.1 8.4c.446.55 1.9 2.6 1.9 5.7V17h-4.7c-.9 0-1.6-.7-1.6-1.6V11h3.1s-.05-.74-.6-1.4c-.453-.543-1-.9-1.6-1.2-.2-.1-.47-.212-.6-.5-.127-.282-.2-.5-.2-.9v-.6c1 .2 1.744.197 2.6.6.856.403 1.272.873 1.7 1.4z"/>
+ </g>
+ <use transform="translate(-8)" id="quote2" width="24" height="24" xlink:href="#quote"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="quotes-add">
<path id="quote" d="M5.9 10.4c-.446.55-1.974 2.6-1.9 5.7V19h4.7c.9 0 1.593-.7 1.6-1.6V13H7.2s.05-.74.6-1.4c.453-.543 1-.9 1.6-1.2.2-.1.47-.212.6-.5.127-.282.2-.5.2-.9v-.6c-1 .2-1.744.197-2.6.6-.856.403-1.272.873-1.7 1.4z"/>
<path id="quote2" d="M15 9.344c-.476.32-.78.677-1.094 1.062A8.76 8.76 0 0 0 12 16.094V19h4.688a1.6 1.6 0 0 0 1.625-1.594V13H15V9.344z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="quotes-add">
+ <path id="quote" d="M5.9 10.4c-.446.55-1.974 2.6-1.9 5.7V19h4.7c.9 0 1.593-.7 1.6-1.6V13H7.2s.05-.74.6-1.4c.453-.543 1-.9 1.6-1.2.2-.1.47-.212.6-.5.127-.282.2-.5.2-.9v-.6c-1 .2-1.744.197-2.6.6-.856.403-1.272.873-1.7 1.4z"/>
+ <path id="quote2" d="M15 9.344c-.476.32-.78.677-1.094 1.062A8.76 8.76 0 0 0 12 16.094V19h4.688a1.6 1.6 0 0 0 1.625-1.594V13H15V9.344z"/>
+ <path id="add" d="M18 6V2h-2v4h-4v2h4v4h2V8h4V6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="quotes-add">
<path id="quote" d="M18.097 10.4c.446.55 1.974 2.6 1.9 5.7V19h-4.7c-.9 0-1.593-.7-1.6-1.6V13h3.1s-.05-.74-.6-1.4c-.453-.543-1-.9-1.6-1.2-.2-.1-.47-.212-.6-.5-.127-.282-.2-.5-.2-.9v-.6c1 .2 1.744.197 2.6.6.856.403 1.272.873 1.7 1.4z"/>
<path id="quote2" d="M8.997 9.344c.476.32.782.677 1.094 1.062A8.758 8.758 0 0 1 12 16.094V19H7.31c-.9 0-1.618-.694-1.625-1.594V13h3.312V9.344z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="quotes-add">
+ <path id="quote" d="M18.097 10.4c.446.55 1.974 2.6 1.9 5.7V19h-4.7c-.9 0-1.593-.7-1.6-1.6V13h3.1s-.05-.74-.6-1.4c-.453-.543-1-.9-1.6-1.2-.2-.1-.47-.212-.6-.5-.127-.282-.2-.5-.2-.9v-.6c1 .2 1.744.197 2.6.6.856.403 1.272.873 1.7 1.4z"/>
+ <path id="quote2" d="M8.997 9.344c.476.32.782.677 1.094 1.062A8.758 8.758 0 0 1 12 16.094V19H7.31c-.9 0-1.618-.694-1.625-1.594V13h3.312V9.344z"/>
+ <path id="add" d="M5.997 6V2h2v4h4v2h-4v4h-2V8h-4V6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="regular-expression">
<path id="left-bracket" d="M3 12.045c0-.99.15-1.915.45-2.777A6.886 6.886 0 0 1 4.764 7H6.23a7.923 7.923 0 0 0-1.25 2.374 8.563 8.563 0 0 0 .007 5.314c.29.85.7 1.622 1.23 2.312h-1.45a6.53 6.53 0 0 1-1.314-2.223 8.126 8.126 0 0 1-.45-2.732"/>
<path id="dot" d="M10 16a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="regular-expression">
+ <path id="left-bracket" d="M3 12.045c0-.99.15-1.915.45-2.777A6.886 6.886 0 0 1 4.764 7H6.23a7.923 7.923 0 0 0-1.25 2.374 8.563 8.563 0 0 0 .007 5.314c.29.85.7 1.622 1.23 2.312h-1.45a6.53 6.53 0 0 1-1.314-2.223 8.126 8.126 0 0 1-.45-2.732"/>
+ <path id="dot" d="M10 16a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
+ <path id="star" d="M14.25 7.013l-.24 2.156 2.187-.61.193 1.47-1.992.14 1.307 1.74-1.33.71-.914-1.833-.8 1.822-1.38-.698 1.296-1.74-1.98-.152.23-1.464 2.14.61-.24-2.158h1.534"/>
+ <path id="right-bracket" d="M21 12.045c0 .982-.152 1.896-.457 2.744A6.51 6.51 0 0 1 19.236 17h-1.453a8.017 8.017 0 0 0 1.225-2.31c.29-.855.434-1.74.434-2.66 0-.91-.14-1.797-.422-2.66a7.913 7.913 0 0 0-1.248-2.374h1.465a6.764 6.764 0 0 1 1.313 2.28c.3.86.45 1.782.45 2.764"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<circle cx="11.5" cy="8.5" r="2.5"/>
<path d="M16.3 8.7L17 8l-.8-.8.4-.8-1.1-.5.1-.9-1.2-.2-.1-.9-1.2.2-.4-.8-1.1.5L11 3l-.8.8-.9-.4-.5 1.1-.9-.2-.2 1.2-.9.2.2 1.2-.9.4.5 1.1L6 9l.8.8-.4.8 1.1.5-.1.9 1.2.2.1.9 1.2-.2.4.8 1.1-.5.6.8.8-.8.8.4.5-1.1.9.1.2-1.2.9-.1-.2-1.2.8-.4-.4-1zM11.5 12C9.6 12 8 10.4 8 8.5S9.6 5 11.5 5 15 6.6 15 8.5 13.4 12 11.5 12zm.5 3l-.7-.7-1.1.6-.4-.7-.8.3V23l2.5-3 2.5 3v-8.5l-1-.5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <circle cx="11.5" cy="8.5" r="2.5"/>
+ <path d="M16.3 8.7L17 8l-.8-.8.4-.8-1.1-.5.1-.9-1.2-.2-.1-.9-1.2.2-.4-.8-1.1.5L11 3l-.8.8-.9-.4-.5 1.1-.9-.2-.2 1.2-.9.2.2 1.2-.9.4.5 1.1L6 9l.8.8-.4.8 1.1.5-.1.9 1.2.2.1.9 1.2-.2.4.8 1.1-.5.6.8.8-.8.8.4.5-1.1.9.1.2-1.2.9-.1-.2-1.2.8-.4-.4-1zM11.5 12C9.6 12 8 10.4 8 8.5S9.6 5 11.5 5 15 6.6 15 8.5 13.4 12 11.5 12zm.5 3l-.7-.7-1.1.6-.4-.7-.8.3V23l2.5-3 2.5 3v-8.5l-1-.5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="search">
<path id="magnifying-glass" d="M10.5 4a6.5 6.5 0 1 0 2.844 12.344L16 19c1.4 1.4 2.5 1.5 4 0l-4.438-4.438A6.426 6.426 0 0 0 17 10.5 6.5 6.5 0 0 0 10.5 4zm0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="search">
+ <path id="magnifying-glass" d="M10.5 4a6.5 6.5 0 1 0 2.844 12.344L16 19c1.4 1.4 2.5 1.5 4 0l-4.438-4.438A6.426 6.426 0 0 0 17 10.5 6.5 6.5 0 0 0 10.5 4zm0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="search">
<path id="magnifying-glass" d="M13.5 4a6.5 6.5 0 1 1-2.844 12.344L8 19c-1.4 1.4-2.5 1.5-4 0l4.438-4.438A6.426 6.426 0 0 1 7 10.5 6.5 6.5 0 0 1 13.5 4zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="search">
+ <path id="magnifying-glass" d="M13.5 4a6.5 6.5 0 1 1-2.844 12.344L8 19c-1.4 1.4-2.5 1.5-4 0l4.438-4.438A6.426 6.426 0 0 1 7 10.5 6.5 6.5 0 0 1 13.5 4zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="secure">
<path id="lock" d="M8 5h.02v-.997c0-.057.003-1.41-.833-2.255-.434-.438-.998-.66-1.68-.66s-1.244.222-1.677.66c-.837.846-.833 2.198-.832 2.25V5H3a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1zM3.998 5V3.993c0-.01.005-1 .543-1.543.49-.485 1.45-.487 1.94-.002.543.546.545 1.536.545 1.55V5H3.998z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="secure">
+ <path id="lock" d="M8 5h.02v-.997c0-.057.003-1.41-.833-2.255-.434-.438-.998-.66-1.68-.66s-1.244.222-1.677.66c-.837.846-.833 2.198-.832 2.25V5H3a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1zM3.998 5V3.993c0-.01.005-1 .543-1.543.49-.485 1.45-.487 1.94-.002.543.546.545 1.536.545 1.55V5H3.998z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="settings">
<path id="gear" d="M3 4h3v2H3zm9 0h9v2h-9zM8 3h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm-5 8h9v2H3zm15 0h3v2h-3zm-4-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1zM3 18h6v2H3zm12 0h6v2h-6zm-4-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="settings">
+ <path id="gear" d="M3 4h3v2H3zm9 0h9v2h-9zM8 3h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm-5 8h9v2H3zm15 0h3v2h-3zm-4-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1zM3 18h6v2H3zm12 0h6v2h-6zm-4-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M0 20h24v1H0v-1zm6-8l-1-1-2 2-2-2-1 1 2 2-2 2 1 1 2-2 2 2 1-1-2-2zm15.6 3.7c-.9-.5-1.9-.5-2.7 0-1.5.9-3.1.4-3.1.4-.4-.2-.8-.4-1.1-.6 2.2-.6 4.4-1.8 6-3.9 1.1-1.2 2.5-3.9.4-6-.7-.7-1.6-1.1-2.7-1-1.4.1-2.8.9-3.9 2.1-.9 1.1-3.1 4.5-2.3 7.5 0 .1 0 .2.1.3-2.3.3-4.2.2-4.4.1v1.5c.7.1 2.7.2 5.1-.2.5.7 1.3 1.2 2.3 1.6.1 0 2.4.8 4.5-.6.5-.3.9-.1 1.1 0 .4.2.7.6.7 1H23c0-.8-.6-1.7-1.4-2.2zm-8-1.7c-.5-2.2 1.1-5.1 2-6.2.8-.9 1.8-1.5 2.8-1.6h.1c.6 0 1.1.2 1.5.6 1.6 1.6-.4 3.9-.5 4-1.5 2-3.7 3-5.8 3.5l-.1-.3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M0 20h24v1H0v-1zm6-8l-1-1-2 2-2-2-1 1 2 2-2 2 1 1 2-2 2 2 1-1-2-2zm15.6 3.7c-.9-.5-1.9-.5-2.7 0-1.5.9-3.1.4-3.1.4-.4-.2-.8-.4-1.1-.6 2.2-.6 4.4-1.8 6-3.9 1.1-1.2 2.5-3.9.4-6-.7-.7-1.6-1.1-2.7-1-1.4.1-2.8.9-3.9 2.1-.9 1.1-3.1 4.5-2.3 7.5 0 .1 0 .2.1.3-2.3.3-4.2.2-4.4.1v1.5c.7.1 2.7.2 5.1-.2.5.7 1.3 1.2 2.3 1.6.1 0 2.4.8 4.5-.6.5-.3.9-.1 1.1 0 .4.2.7.6.7 1H23c0-.8-.6-1.7-1.4-2.2zm-8-1.7c-.5-2.2 1.1-5.1 2-6.2.8-.9 1.8-1.5 2.8-1.6h.1c.6 0 1.1.2 1.5.6 1.6 1.6-.4 3.9-.5 4-1.5 2-3.7 3-5.8 3.5l-.1-.3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M24 20H0v1h24v-1zm-6-8l1-1 2 2 2-2 1 1-2 2 2 2-1 1-2-2-2 2-1-1 2-2zM2.4 15.7c.9-.5 1.9-.5 2.7 0 1.5.9 3.1.4 3.1.4.4-.2.8-.4 1.1-.6-2.2-.6-4.4-1.8-6-3.9-1.1-1.2-2.5-3.9-.4-6 .7-.7 1.6-1.1 2.7-1 1.4.1 2.8.9 3.9 2.1.9 1.1 3.1 4.5 2.3 7.5 0 .1 0 .2-.1.3 2.3.3 4.2.2 4.4.1v1.5c-.7.1-2.7.2-5.1-.2-.5.7-1.3 1.2-2.3 1.6-.1 0-2.4.8-4.5-.6-.5-.3-.9-.1-1.1 0-.4.2-.7.6-.7 1H1c0-.8.6-1.7 1.4-2.2zm8-1.7c.5-2.2-1.1-5.1-2-6.2-.8-.9-1.8-1.5-2.8-1.6h-.1c-.6 0-1.1.2-1.5.6-1.6 1.6.4 3.9.5 4 1.5 2 3.7 3 5.8 3.5l.1-.3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M24 20H0v1h24v-1zm-6-8l1-1 2 2 2-2 1 1-2 2 2 2-1 1-2-2-2 2-1-1 2-2zM2.4 15.7c.9-.5 1.9-.5 2.7 0 1.5.9 3.1.4 3.1.4.4-.2.8-.4 1.1-.6-2.2-.6-4.4-1.8-6-3.9-1.1-1.2-2.5-3.9-.4-6 .7-.7 1.6-1.1 2.7-1 1.4.1 2.8.9 3.9 2.1.9 1.1 3.1 4.5 2.3 7.5 0 .1 0 .2-.1.3 2.3.3 4.2.2 4.4.1v1.5c-.7.1-2.7.2-5.1-.2-.5.7-1.3 1.2-2.3 1.6-.1 0-2.4.8-4.5-.6-.5-.3-.9-.1-1.1 0-.4.2-.7.6-.7 1H1c0-.8.6-1.7 1.4-2.2zm8-1.7c.5-2.2-1.1-5.1-2-6.2-.8-.9-1.8-1.5-2.8-1.6h-.1c-.6 0-1.1.2-1.5.6-1.6 1.6.4 3.9.5 4 1.5 2 3.7 3 5.8 3.5l.1-.3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
<g id="down">
<path id="arrow" d="M22 3l-3.5 6L15 3z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
+ <g id="down">
+ <path id="arrow" d="M22 3l-3.5 6L15 3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
<g id="down">
<path id="arrow" d="M9 3L5.5 9 2 3z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
+ <g id="down">
+ <path id="arrow" d="M9 3L5.5 9 2 3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="special-character">
<path id="omega" d="M12 6.708c-.794 0-1.368.103-1.894.31-.525.207-.944.496-1.255.867-.31.366-.53.808-.66 1.327a7.232 7.232 0 0 0-.19 1.7c0 .512.06 1 .18 1.46.12.46.31.87.567 1.23.63.862 1.156 1.138 2.012 1.362L11 18H6v-3h.604l.53 1.353.395.053.6.044.75.035.455.01H10l-.09-.895c-.63-.094-.812-.268-1.337-.522-.525-.26-.98-.59-1.365-.99a4.428 4.428 0 0 1-.89-1.4 4.78 4.78 0 0 1-.32-1.778c0-.82.13-1.537.394-2.15a3.97 3.97 0 0 1 1.163-1.54c.507-.407 1.133-.71 1.878-.912.745-.206 1.6-.31 2.565-.31.96 0 1.81.103 2.556.31.75.2 1.38.504 1.887.912.51.407.9.92 1.16 1.54.27.614.404 1.33.404 2.15a4.79 4.79 0 0 1-.32 1.78 4.35 4.35 0 0 1-.9 1.397c-.38.4-.83.732-1.355.99-.526.255-.708.43-1.337.523l-.092.894h.66l.448-.01.75-.034.606-.044.4-.053.534-1.354H18v3h-5l.246-3.04c1.066-.11 1.337-.698 2.002-1.365.263-.36.452-.77.568-1.23.122-.46.183-.947.183-1.46 0-.62-.07-1.186-.198-1.7a3.175 3.175 0 0 0-.66-1.326c-.31-.37-.73-.66-1.255-.867-.525-.206-1.1-.31-1.894-.31"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="special-character">
+ <path id="omega" d="M12 6.708c-.794 0-1.368.103-1.894.31-.525.207-.944.496-1.255.867-.31.366-.53.808-.66 1.327a7.232 7.232 0 0 0-.19 1.7c0 .512.06 1 .18 1.46.12.46.31.87.567 1.23.63.862 1.156 1.138 2.012 1.362L11 18H6v-3h.604l.53 1.353.395.053.6.044.75.035.455.01H10l-.09-.895c-.63-.094-.812-.268-1.337-.522-.525-.26-.98-.59-1.365-.99a4.428 4.428 0 0 1-.89-1.4 4.78 4.78 0 0 1-.32-1.778c0-.82.13-1.537.394-2.15a3.97 3.97 0 0 1 1.163-1.54c.507-.407 1.133-.71 1.878-.912.745-.206 1.6-.31 2.565-.31.96 0 1.81.103 2.556.31.75.2 1.38.504 1.887.912.51.407.9.92 1.16 1.54.27.614.404 1.33.404 2.15a4.79 4.79 0 0 1-.32 1.78 4.35 4.35 0 0 1-.9 1.397c-.38.4-.83.732-1.355.99-.526.255-.708.43-1.337.523l-.092.894h.66l.448-.01.75-.034.606-.044.4-.053.534-1.354H18v3h-5l.246-3.04c1.066-.11 1.337-.698 2.002-1.365.263-.36.452-.77.568-1.23.122-.46.183-.947.183-1.46 0-.62-.07-1.186-.198-1.7a3.175 3.175 0 0 0-.66-1.326c-.31-.37-.73-.66-1.255-.867-.525-.206-1.1-.31-1.894-.31"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M19 20H2l3-3V6h17v11c0 1.7-1.3 3-3 3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M19 20H2l3-3V6h17v11c0 1.7-1.3 3-3 3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M5 20h17l-3-3V6H2v11c0 1.7 1.3 3 3 3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M5 20h17l-3-3V6H2v11c0 1.7 1.3 3 3 3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M5 6v11l-3 3h17c1.7 0 3-1.3 3-3V6H5zm8 3h1v3h3v1h-3v3h-1v-3h-3v-1h3V9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M5 6v11l-3 3h17c1.7 0 3-1.3 3-3V6H5zm8 3h1v3h3v1h-3v3h-1v-3h-3v-1h3V9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M2 6v11c0 1.7 1.3 3 3 3h17l-3-3V6H2zm8 3h1v3h3v1h-3v3h-1v-3H7v-1h3V9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M2 6v11c0 1.7 1.3 3 3 3h17l-3-3V6H2zm8 3h1v3h3v1h-3v3h-1v-3H7v-1h3V9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20 9v9l2 2H8V9h12zM3 4h12v4H7v7H1l2-2V4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20 9v9l2 2H8V9h12zM3 4h12v4H7v7H1l2-2V4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3 9v9l-2 2h14V9H3zm17-5H8v4h8v7h6l-2-2V4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3 9v9l-2 2h14V9H3zm17-5H8v4h8v7h6l-2-2V4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M12 7.4l1.7 3.6 4 .5-2.7 2.8.5 3.9-3.5-1.7-3.6 1.7.6-3.9-2.8-2.8 3.9-.5L12 7.4M12 4L9.2 9.6l-6.2.9 4.5 4.4L6.4 21l5.6-3 5.5 3-1-6.2 4.5-4.4-6.3-.9L12 4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 7.4l1.7 3.6 4 .5-2.7 2.8.5 3.9-3.5-1.7-3.6 1.7.6-3.9-2.8-2.8 3.9-.5L12 7.4M12 4L9.2 9.6l-6.2.9 4.5 4.4L6.4 21l5.6-3 5.5 3-1-6.2 4.5-4.4-6.3-.9L12 4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M12 7.4l1.7 3.6 4 .5-2.7 2.8.5 3.9-3.5-1.7-3.6 1.7.6-3.9-2.8-2.8 3.9-.5L12 7.4M12 4L9.2 9.6l-6.2.9 4.5 4.4L6.4 21l5.6-3 5.5 3-1-6.2 4.5-4.4-6.3-.9L12 4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3 11.1H9v-6h6v6z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3 11.1H9v-6h6v6z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="strikethrough-a">
<path id="strikethrough" d="M6 11h12v1H6v-1z"/>
<path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="strikethrough-a">
+ <path id="strikethrough" d="M6 11h12v1H6v-1z"/>
+ <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="strikethrough-s">
<path id="strikethrough" d="M6 12h12v1H6v-1z"/>
<path id="s" d="M12.094 6c-1.133 0-2.076.287-2.75.9-.67.613-1 1.49-1 2.52 0 .89.22 1.602.72 2.13.497.528 1.278.91 2.31 1.14l.813.182v-.03c.656.147 1.128.375 1.375.63.252.256.375.607.375 1.11 0 .573-.172.97-.53 1.26-.36.29-.895.45-1.626.45-.47 0-.962-.074-1.462-.24a7.288 7.288 0 0 1-1.562-.75l-.374-.238v2.158l.156.062c.58.237 1.144.417 1.69.54.548.12 1.07.18 1.56.18 1.287 0 2.298-.293 3-.9.71-.605 1.063-1.486 1.063-2.608 0-.943-.256-1.726-.78-2.312-.522-.592-1.306-1-2.345-1.23l-.812-.18c-.714-.148-1.202-.352-1.404-.54-.206-.202-.313-.484-.313-.934 0-.533.162-.9.5-1.17.342-.27.836-.42 1.53-.42.396 0 .82.052 1.25.18.434.128.91.334 1.407.6l.375.18V6.63s-1.19-.383-1.69-.48c-.5-.097-.983-.15-1.467-.15z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="strikethrough-s">
+ <path id="strikethrough" d="M6 12h12v1H6v-1z"/>
+ <path id="s" d="M12.094 6c-1.133 0-2.076.287-2.75.9-.67.613-1 1.49-1 2.52 0 .89.22 1.602.72 2.13.497.528 1.278.91 2.31 1.14l.813.182v-.03c.656.147 1.128.375 1.375.63.252.256.375.607.375 1.11 0 .573-.172.97-.53 1.26-.36.29-.895.45-1.626.45-.47 0-.962-.074-1.462-.24a7.288 7.288 0 0 1-1.562-.75l-.374-.238v2.158l.156.062c.58.237 1.144.417 1.69.54.548.12 1.07.18 1.56.18 1.287 0 2.298-.293 3-.9.71-.605 1.063-1.486 1.063-2.608 0-.943-.256-1.726-.78-2.312-.522-.592-1.306-1-2.345-1.23l-.812-.18c-.714-.148-1.202-.352-1.404-.54-.206-.202-.313-.484-.313-.934 0-.533.162-.9.5-1.17.342-.27.836-.42 1.53-.42.396 0 .82.052 1.25.18.434.128.91.334 1.407.6l.375.18V6.63s-1.19-.383-1.69-.48c-.5-.097-.983-.15-1.467-.15z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="strikethrough-y">
<path id="strikethrough" d="M6 11h12v1H6v-1z"/>
<path id="a" d="M7 6h1.724l3.288 4.935L15.276 6H17l-4.194 6.285V18h-1.612v-5.715L7 6"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="strikethrough-y">
+ <path id="strikethrough" d="M6 11h12v1H6v-1z"/>
+ <path id="a" d="M7 6h1.724l3.288 4.935L15.276 6H17l-4.194 6.285V18h-1.612v-5.715L7 6"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M4 9h12v2H4V9zm0 3h8v2H4v-2zm0-7h16v3H4V5zm16 14H4v-3h16v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M4 9h12v2H4V9zm0 3h8v2H4v-2zm0-7h16v3H4V5zm16 14H4v-3h16v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20 9H8v2h12V9zm0 3h-8v2h8v-2zm0-7H4v3h16V5zM4 19h16v-3H4v3z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20 9H8v2h12V9zm0 3h-8v2h8v-2zm0-7H4v3h16V5zM4 19h16v-3H4v3z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20 19H4v-2h16v2zM20 15H4v-2h16v2zM20 11H4V9h16v2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20 19H4v-2h16v2zM20 15H4v-2h16v2zM20 11H4V9h16v2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20 11H4V9h16v2zM4 12h8v2H4v-2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20 11H4V9h16v2zM4 12h8v2H4v-2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M4 11h16V9H4v2zm16 1h-8v2h8v-2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M4 11h16V9H4v2zm16 1h-8v2h8v-2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17 13H4v-3h13v3zm-5 6H4v-3h8v3zM4 7V4h16v3H4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M17 13H4v-3h13v3zm-5 6H4v-3h8v3zM4 7V4h16v3H4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 13h13v-3H7v3zm5 6h8v-3h-8v3zm8-12V4H4v3h16z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M7 13h13v-3H7v3zm5 6h8v-3h-8v3zm8-12V4H4v3h16z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path id="x" d="M14 9l-2.354 3.406L14 16h-1.2L11 13.25 9.2 16H8l2.403-3.662L8 9h1.188l1.857 2.494L12.797 9H14z"/>
<path d="M18 13l-1 1v3l1 1h-1l-.527-.46L16 18h-1l1-1v-3l-1-1h1l.485.497L17 13z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path id="x" d="M14 9l-2.354 3.406L14 16h-1.2L11 13.25 9.2 16H8l2.403-3.662L8 9h1.188l1.857 2.494L12.797 9H14z"/>
+ <path d="M18 13l-1 1v3l1 1h-1l-.527-.46L16 18h-1l1-1v-3l-1-1h1l.485.497L17 13z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path id="x" d="M12 9l2.354 3.406L12 16h1.2l1.8-2.75L16.8 16H18l-2.403-3.662L18 9h-1.188l-1.857 2.494L13.203 9H12z"/>
<path d="M8 13l1 1v3l-1 1h1l.527-.46L10 18h1l-1-1v-3l1-1h-1l-.485.497L9 13z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path id="x" d="M12 9l2.354 3.406L12 16h1.2l1.8-2.75L16.8 16H18l-2.403-3.662L18 9h-1.188l-1.857 2.494L13.203 9H12z"/>
+ <path d="M8 13l1 1v3l-1 1h1l.527-.46L10 18h1l-1-1v-3l1-1h-1l-.485.497L9 13z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M18.1 5.1c0 .3-.1.6-.3.9l-1.4 1.4-.9-.8 2.2-2.2c.3.1.4.4.4.7zm-.5 5.3h3.2c0 .3-.1.6-.4.9s-.5.4-.8.4h-2v-1.3zm-6.2-5V2.2c.3 0 .6.1.9.4s.4.5.4.8v2h-1.3zm6.4 11.7c-.3 0-.6-.1-.8-.3l-1.4-1.4.8-.8 2.2 2.2c-.2.2-.5.3-.8.3zM6.2 4.9c.3 0 .6.1.8.3l1.4 1.4-.8.9-2.2-2.3c.2-.2.5-.3.8-.3zm5.2 11.7h1.2v3.2c-.3 0-.6-.1-.9-.4s-.4-.5-.4-.8l.1-2zm-7-6.2h2v1.2H3.2c0-.3.1-.6.4-.9s.5-.3.8-.3zM6.2 16l1.4-1.4.8.8-2.2 2.2c-.2-.2-.3-.5-.3-.8s.1-.6.3-.8z"/>
<circle cx="12" cy="11" r="4"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M18.1 5.1c0 .3-.1.6-.3.9l-1.4 1.4-.9-.8 2.2-2.2c.3.1.4.4.4.7zm-.5 5.3h3.2c0 .3-.1.6-.4.9s-.5.4-.8.4h-2v-1.3zm-6.2-5V2.2c.3 0 .6.1.9.4s.4.5.4.8v2h-1.3zm6.4 11.7c-.3 0-.6-.1-.8-.3l-1.4-1.4.8-.8 2.2 2.2c-.2.2-.5.3-.8.3zM6.2 4.9c.3 0 .6.1.8.3l1.4 1.4-.8.9-2.2-2.3c.2-.2.5-.3.8-.3zm5.2 11.7h1.2v3.2c-.3 0-.6-.1-.9-.4s-.4-.5-.4-.8l.1-2zm-7-6.2h2v1.2H3.2c0-.3.1-.6.4-.9s.5-.3.8-.3zM6.2 16l1.4-1.4.8.8-2.2 2.2c-.2-.2-.3-.5-.3-.8s.1-.6.3-.8z"/>
+ <circle cx="12" cy="11" r="4"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M5.9 5.1c0 .3.1.6.3.9l1.4 1.4.9-.8-2.2-2.2c-.3.1-.4.4-.4.7zm.5 5.3H3.2c0 .3.1.6.4.9.3.3.5.4.8.4h2v-1.3zm6.2-5V2.2c-.3 0-.6.1-.9.4-.3.3-.4.5-.4.8v2h1.3zM6.2 17.1c.3 0 .6-.1.8-.3l1.4-1.4-.8-.8-2.2 2.2c.2.2.5.3.8.3zM17.8 4.9c-.3 0-.6.1-.8.3l-1.4 1.4.8.9 2.2-2.3c-.2-.2-.5-.3-.8-.3zm-5.2 11.7h-1.2v3.2c.3 0 .6-.1.9-.4.3-.3.4-.5.4-.8l-.1-2zm7-6.2h-2v1.2h3.2c0-.3-.1-.6-.4-.9-.3-.3-.5-.3-.8-.3zM17.8 16l-1.4-1.4-.8.8 2.2 2.2c.2-.2.3-.5.3-.8 0-.3-.1-.6-.3-.8z"/>
<circle cx="12" cy="11" r="4" transform="matrix(-1 0 0 1 24 0)"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M5.9 5.1c0 .3.1.6.3.9l1.4 1.4.9-.8-2.2-2.2c-.3.1-.4.4-.4.7zm.5 5.3H3.2c0 .3.1.6.4.9.3.3.5.4.8.4h2v-1.3zm6.2-5V2.2c-.3 0-.6.1-.9.4-.3.3-.4.5-.4.8v2h1.3zM6.2 17.1c.3 0 .6-.1.8-.3l1.4-1.4-.8-.8-2.2 2.2c.2.2.5.3.8.3zM17.8 4.9c-.3 0-.6.1-.8.3l-1.4 1.4.8.9 2.2-2.3c-.2-.2-.5-.3-.8-.3zm-5.2 11.7h-1.2v3.2c.3 0 .6-.1.9-.4.3-.3.4-.5.4-.8l-.1-2zm7-6.2h-2v1.2h3.2c0-.3-.1-.6-.4-.9-.3-.3-.5-.3-.8-.3zM17.8 16l-1.4-1.4-.8.8 2.2 2.2c.2-.2.3-.5.3-.8 0-.3-.1-.6-.3-.8z"/>
+ <circle cx="12" cy="11" r="4" transform="matrix(-1 0 0 1 24 0)"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path id="x" d="M14 9l-2.354 3.406L14 16h-1.2L11 13.25 9.2 16H8l2.403-3.662L8 9h1.188l1.857 2.494L12.797 9H14z"/>
<path d="M18 7l-1 1v3l1 1h-1l-.527-.46L16 12h-1l1-1V8l-1-1h1l.485.497L17 7z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path id="x" d="M14 9l-2.354 3.406L14 16h-1.2L11 13.25 9.2 16H8l2.403-3.662L8 9h1.188l1.857 2.494L12.797 9H14z"/>
+ <path d="M18 7l-1 1v3l1 1h-1l-.527-.46L16 12h-1l1-1V8l-1-1h1l.485.497L17 7z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path id="x" d="M12 9l2.354 3.406L12 16h1.2l1.8-2.75L16.8 16H18l-2.403-3.662L18 9h-1.188l-1.857 2.494L13.203 9H12z"/>
<path d="M8 7l1 1v3l-1 1h1l.527-.46L10 12h1l-1-1V8l1-1h-1l-.485.497L9 7z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path id="x" d="M12 9l2.354 3.406L12 16h1.2l1.8-2.75L16.8 16H18l-2.403-3.662L18 9h-1.188l-1.857 2.494L13.203 9H12z"/>
+ <path d="M8 7l1 1v3l-1 1h1l.527-.46L10 12h1l-1-1V8l1-1h-1l-.485.497L9 7z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="table-caption">
<path id="caption" d="M6 6h12v3H6z"/>
<path id="table" d="M4 10v7h16v-7H4zm1 1h4v2H5v-2zm5 0h4v2h-4v-2zm5 0h4v2h-4v-2zM5 14h4v2H5v-2zm5 0h4v2h-4v-2zm5 0h4v2h-4v-2z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="table-caption">
+ <path id="caption" d="M6 6h12v3H6z"/>
+ <path id="table" d="M4 10v7h16v-7H4zm1 1h4v2H5v-2zm5 0h4v2h-4v-2zm5 0h4v2h-4v-2zM5 14h4v2H5v-2zm5 0h4v2h-4v-2zm5 0h4v2h-4v-2z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="table-insert-column-ltr">
<path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
<path d="M5 5h2v14H5z" id="column"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="table-insert-column-ltr">
+ <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
+ <path d="M5 5h2v14H5z" id="column"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="table-insert-column-rtl">
<path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
<path d="M17 5h2v14h-2z" id="column"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="table-insert-column-rtl">
+ <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
+ <path d="M17 5h2v14h-2z" id="column"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="table-insert-row-after">
<path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
<path d="M5 17h14v2H5z" id="row"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="table-insert-row-after">
+ <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
+ <path d="M5 17h14v2H5z" id="row"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="table-insert-row-before">
<path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
<path d="M5 5h14v2H5z" id="row"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="table-insert-row-before">
+ <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
+ <path d="M5 5h14v2H5z" id="row"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="table-insert">
<path id="table" d="M4 6v11h15V6zm1 3h6v3H5zm7 0h6v3h-6zm-7 4h6v3H5zm7 0h6v3h-6z"/>
</g>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="table-merge-cells">
<g id="merge-cell-left">
<path id="cell-border" d="M4 7v9h7v-3l-1 .834V15H5V8h5v1.167L11 10V7z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="table-merge-cells">
+ <g id="merge-cell-left">
+ <path id="cell-border" d="M4 7v9h7v-3l-1 .834V15H5V8h5v1.167L11 10V7z"/>
+ <path id="arrow" d="M8 9v2H6v1h2v2l3-2.5z"/>
+ </g>
+ <use id="merge-cell-right" xlink:href="#merge-cell-left" transform="matrix(-1 0 0 1 24 0)"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="table-insert">
+ <path id="table" d="M4 6v11h15V6zm1 3h6v3H5zm7 0h6v3h-6zm-7 4h6v3H5zm7 0h6v3h-6z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="template-add">
<path id="add" d="M23 7h-4V3h-2v4h-4v2h4v4h2V9h4z"/>
<path id="template" d="M18 14v4H6c-1.1 0-2-.9-2-2V8h8V7H3v9c0 1.7 1.3 3 3 3h13v-5z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="template-add">
+ <path id="add" d="M23 7h-4V3h-2v4h-4v2h4v4h2V9h4z"/>
+ <path id="template" d="M18 14v4H6c-1.1 0-2-.9-2-2V8h8V7H3v9c0 1.7 1.3 3 3 3h13v-5z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="template-add">
<path id="add" d="M1 7h4V3h2v4h4v2H7v4H5V9H1z"/>
<path id="template" d="M6 14v4h12c1.1 0 2-.9 2-2V8h-8V7h9v9c0 1.7-1.3 3-3 3H5v-5z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="template-add">
+ <path id="add" d="M1 7h4V3h2v4h4v2H7v4H5V9H1z"/>
+ <path id="template" d="M6 14v4h12c1.1 0 2-.9 2-2V8h-8V7h9v9c0 1.7-1.3 3-3 3H5v-5z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 7H5V6h2l.47.5L8 6h2v1H8v10h2v1H8l-.5-.53L7 18H5v-1h2zm6.976 9v-2H11v-4h2.976V8.044L20 12.022z" id="text-dir-ltr"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 7H5V6h2l.47.5L8 6h2v1H8v10h2v1H8l-.5-.53L7 18H5v-1h2zm6.976 9v-2H11v-4h2.976V8.044L20 12.022z" id="text-dir-ltr"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M17 17h2v1h-2l-.47-.5-.53.5h-2v-1h2V7h-2V6h2l.5.53L17 6h2v1h-2zm-6.976-9v2H13v4h-2.976v1.956L4 11.978z" id="text-dir-rtl"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M17 17h2v1h-2l-.47-.5-.53.5h-2v-1h2V7h-2V6h2l.5.53L17 6h2v1h-2zm-6.976-9v2H13v4h-2.976v1.956L4 11.978z" id="text-dir-rtl"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="text-style">
<path id="a" d="M15.296 18h2.79l-1.14-12h-2.79L6 18h2.79l2.038-3h4.183l.29 3zm-3.11-5L14.5 9.6l.323 3.4H12.19z"/>
<path id="underline" d="M6 19h12v1H6v-1z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="text-style">
+ <path id="a" d="M15.296 18h2.79l-1.14-12h-2.79L6 18h2.79l2.038-3h4.183l.29 3zm-3.11-5L14.5 9.6l.323 3.4H12.19z"/>
+ <path id="underline" d="M6 19h12v1H6v-1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M6 8c0-1.1.9-2 2-2h2l1-1h2l1 1h2c1.1 0 2 .9 2 2H6zm1 1h10l-1 11H8z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M6 8c0-1.1.9-2 2-2h2l1-1h2l1 1h2c1.1 0 2 .9 2 2H6zm1 1h10l-1 11H8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M6 8c0-1.1.9-2 2-2h2l1-1h2l1 1h2c1.1 0 2 .9 2 2H6zm1 1h10l-1 11H8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M3 13.35l1.8-7.2c.2-.996.81-1.8 1.8-1.8h10.8c.99 0 1.6.867 1.8 1.8l1.8 7.2v4.5c0 .99-.81 1.8-1.8 1.8H4.8c-.99 0-1.8-.81-1.8-1.8v-4.5zm6.96 1.8h4.08c-.49.557-1.212.9-2.04.9a2.68 2.68 0 0 1-2.04-.9h4.08c.414-.472.66-1.098.66-1.8h4.14l-1.44-7.2H6.6l-1.44 7.2H9.3c0 .702.246 1.328.66 1.8z" id="tray"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M3 13.35l1.8-7.2c.2-.996.81-1.8 1.8-1.8h10.8c.99 0 1.6.867 1.8 1.8l1.8 7.2v4.5c0 .99-.81 1.8-1.8 1.8H4.8c-.99 0-1.8-.81-1.8-1.8v-4.5zm6.96 1.8h4.08c-.49.557-1.212.9-2.04.9a2.68 2.68 0 0 1-2.04-.9h4.08c.414-.472.66-1.098.66-1.8h4.14l-1.44-7.2H6.6l-1.44 7.2H9.3c0 .702.246 1.328.66 1.8z" id="tray"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M12 9V7s0-5-4.5-5S3 7 3 7h2s0-3 2.5-3S10 7 10 7v2H7v7c0 1.7 1.3 3 3 3h10V9z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 9V7s0-5-4.5-5S3 7 3 7h2s0-3 2.5-3S10 7 10 7v2H7v7c0 1.7 1.3 3 3 3h10V9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 9V7s0-5-4.5-5S3 7 3 7h2s0-3 2.5-3S10 7 10 7v2H7v7c0 1.7 1.3 3 3 3h10V9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #c33 }</style>
<path d="M11 9V7s0-5 4.5-5S20 7 20 7h-2s0-3-2.5-3S13 7 13 7v2h3v7c0 1.7-1.3 3-3 3H3V9z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M11 9V7s0-5 4.5-5S20 7 20 7h-2s0-3-2.5-3S13 7 13 7v2h3v7c0 1.7-1.3 3-3 3H3V9z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M11 9V7s0-5 4.5-5S20 7 20 7h-2s0-3-2.5-3S13 7 13 7v2h3v7c0 1.7-1.3 3-3 3H3V9z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M21 11l-6-1-3-6-3 6-6 1 4 4-1 6 6-3 6 3-1-6 4-4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M21 11l-6-1-3-6-3 6-6 1 4 4-1 6 6-3 6 3-1-6 4-4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
<path d="M21 11l-6-1-3-6-3 6-6 1 4 4-1 6 6-3 6 3-1-6 4-4z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="underline-a">
<path id="a" d="M14.424 16H16.5L13.037 6H10.96L7.5 16h2.077l.627-2h3.604l.616 2zm-3.92-3.623L12 7.997l1.51 4.38h-3z"/>
<path id="underline" d="M7 17h10v1H7v-1z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="underline-a">
+ <path id="a" d="M14.424 16H16.5L13.037 6H10.96L7.5 16h2.077l.627-2h3.604l.616 2zm-3.92-3.623L12 7.997l1.51 4.38h-3z"/>
+ <path id="underline" d="M7 17h10v1H7v-1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="underline-u">
<path id="u" d="M8 6h2v5.96c-.104 1.706.695 2 2 2.04 1.777.062 2.002-.88 2-2.04V6h2v6.123c0 1.28-.338 2.245-1.016 2.898-.672.658-1.666.98-2.98.98-1.32 0-2.32-.32-2.996-.98C8.336 14.37 8 13.41 8 12.13V6"/>
<path id="underline" d="M7 17h10v1H7v-1z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="underline-u">
+ <path id="u" d="M8 6h2v5.96c-.104 1.706.695 2 2 2.04 1.777.062 2.002-.88 2-2.04V6h2v6.123c0 1.28-.338 2.245-1.016 2.898-.672.658-1.666.98-2.98.98-1.32 0-2.32-.32-2.996-.98C8.336 14.37 8 13.41 8 12.13V6"/>
+ <path id="underline" d="M7 17h10v1H7v-1z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M12 8l8 10H4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M12 8l8 10H4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M10 13c0 1.7 1.3 3 3 3V9h3l-4.5-5L7 9h3v4zm7 0v5H7c-.6 0-1-.4-1-1v-4H4v4c0 1.9 1.3 3 3 3h12v-7h-2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M10 13c0 1.7 1.3 3 3 3V9h3l-4.5-5L7 9h3v4zm7 0v5H7c-.6 0-1-.4-1-1v-4H4v4c0 1.9 1.3 3 3 3h12v-7h-2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M13 13c0 1.7-1.3 3-3 3V9H7l4.5-5L16 9h-3v4zm-7 0v5h10c.6 0 1-.4 1-1v-4h2v4c0 1.9-1.3 3-3 3H4v-7h2z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M13 13c0 1.7-1.3 3-3 3V9H7l4.5-5L16 9h-3v4zm-7 0v5h10c.6 0 1-.4 1-1v-4h2v4c0 1.9-1.3 3-3 3H4v-7h2z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 5H4v12c0 1.7 1.3 3 3 3h12V8c0-1.7-1.3-3-3-3zm-2 4c.7 0 1.2.6 1.2 1.2s-.6 1.2-1.2 1.2-1.2-.6-1.2-1.2S13.3 9 14 9zM9 9c.7 0 1.2.6 1.2 1.2s-.5 1.3-1.2 1.3-1.2-.6-1.2-1.2S8.3 9 9 9zm7 5.4c0 .2-.1.3-.3.5-.7.6-1.6 1-2.6 1.3s-2.1.2-3.1 0-2-.9-2.7-1.5c-.1-.1-.2-.3-.2-.4s.1-.3.2-.4c.1-.1.3-.2.4-.2.2 0 .3.1.4.2.5.5 1.2.9 2.1 1.1s1.7.2 2.6 0 1.6-.5 2.1-1c.1-.1.3-.2.4-.2s.3.1.5.2.2.2.2.4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 5H4v12c0 1.7 1.3 3 3 3h12V8c0-1.7-1.3-3-3-3zm-2 4c.7 0 1.2.6 1.2 1.2s-.6 1.2-1.2 1.2-1.2-.6-1.2-1.2S13.3 9 14 9zM9 9c.7 0 1.2.6 1.2 1.2s-.5 1.3-1.2 1.3-1.2-.6-1.2-1.2S8.3 9 9 9zm7 5.4c0 .2-.1.3-.3.5-.7.6-1.6 1-2.6 1.3s-2.1.2-3.1 0-2-.9-2.7-1.5c-.1-.1-.2-.3-.2-.4s.1-.3.2-.4c.1-.1.3-.2.4-.2.2 0 .3.1.4.2.5.5 1.2.9 2.1 1.1s1.7.2 2.6 0 1.6-.5 2.1-1c.1-.1.3-.2.4-.2s.3.1.5.2.2.2.2.4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 5h12v12c0 1.7-1.3 3-3 3H4V8c0-1.7 1.3-3 3-3zm2 4c-.7 0-1.2.6-1.2 1.2s.6 1.2 1.2 1.2 1.2-.6 1.2-1.2S9.7 9 9 9zm5 0c-.7 0-1.2.6-1.2 1.2s.5 1.3 1.2 1.3 1.2-.6 1.2-1.2S14.7 9 14 9zm-7 5.4c0 .2.1.3.3.5.7.6 1.6 1 2.6 1.3 1 .3 2.1.2 3.1 0s2-.9 2.7-1.5c.1-.1.2-.3.2-.4 0-.1-.1-.3-.2-.4-.1-.1-.3-.2-.4-.2-.2 0-.3.1-.4.2-.5.5-1.2.9-2.1 1.1-.9.2-1.7.2-2.6 0-.9-.2-1.6-.5-2.1-1-.1-.1-.3-.2-.4-.2-.1 0-.3.1-.5.2s-.2.2-.2.4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 5h12v12c0 1.7-1.3 3-3 3H4V8c0-1.7 1.3-3 3-3zm2 4c-.7 0-1.2.6-1.2 1.2s.6 1.2 1.2 1.2 1.2-.6 1.2-1.2S9.7 9 9 9zm5 0c-.7 0-1.2.6-1.2 1.2s.5 1.3 1.2 1.3 1.2-.6 1.2-1.2S14.7 9 14 9zm-7 5.4c0 .2.1.3.3.5.7.6 1.6 1 2.6 1.3 1 .3 2.1.2 3.1 0s2-.9 2.7-1.5c.1-.1.2-.3.2-.4 0-.1-.1-.3-.2-.4-.1-.1-.3-.2-.4-.2-.2 0-.3.1-.4.2-.5.5-1.2.9-2.1 1.1-.9.2-1.7.2-2.6 0-.9-.2-1.6-.5-2.1-1-.1-.1-.3-.2-.4-.2-.1 0-.3.1-.5.2s-.2.2-.2.4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M18.75 17.4c-1.08-.36-3.6-1.35-3.6-1.35-.81-.27-.81-.99-.9-1.8v-.09c1.26-1.08 2.25-2.88 2.25-4.86 0-4.23-1.8-5.85-4.5-5.85-1.89 0-4.5 1.08-4.5 5.85 0 1.89.99 3.69 2.25 4.86v.09c0 .81-.09 1.53-.9 1.8 0 0-2.61.99-3.6 1.35-1.17.36-2.25.9-2.25 2.25v.9h18v-.9c0-1.08-.72-1.8-2.25-2.25z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M18.75 17.4c-1.08-.36-3.6-1.35-3.6-1.35-.81-.27-.81-.99-.9-1.8v-.09c1.26-1.08 2.25-2.88 2.25-4.86 0-4.23-1.8-5.85-4.5-5.85-1.89 0-4.5 1.08-4.5 5.85 0 1.89.99 3.69 2.25 4.86v.09c0 .81-.09 1.53-.9 1.8 0 0-2.61.99-3.6 1.35-1.17.36-2.25.9-2.25 2.25v.9h18v-.9c0-1.08-.72-1.8-2.25-2.25z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M16 5H4v12c0 1.7 1.3 3 3 3h12V8c0-1.7-1.3-3-3-3zm-9.3 5.4C6.2 10 6 9.6 6 9c.6.6 1.5.9 2.5.9s1.9-.3 2.5-.9c0 .6-.2 1-.7 1.4-.5.4-1.1.6-1.8.6s-1.3-.2-1.8-.6zm8.4 4.3c0 .2-.1.3-.3.4-1 .6-2.2.9-3.5.9-1.2 0-2.3-.3-3.3-1-.2-.1-.2-.2-.3-.4s0-.3.1-.5.2-.2.4-.3.3 0 .5.1c.8.5 1.7.8 2.8.8s2-.2 2.8-.7c.1-.1.3-.1.5-.1s.3.1.4.3l-.1.5zm1.2-4.3c-.5.4-1.1.6-1.8.6s-1.3-.2-1.8-.6S12 9.6 12 9c.6.6 1.5.9 2.5.9s1.9-.3 2.5-.9c0 .6-.2 1-.7 1.4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M16 5H4v12c0 1.7 1.3 3 3 3h12V8c0-1.7-1.3-3-3-3zm-9.3 5.4C6.2 10 6 9.6 6 9c.6.6 1.5.9 2.5.9s1.9-.3 2.5-.9c0 .6-.2 1-.7 1.4-.5.4-1.1.6-1.8.6s-1.3-.2-1.8-.6zm8.4 4.3c0 .2-.1.3-.3.4-1 .6-2.2.9-3.5.9-1.2 0-2.3-.3-3.3-1-.2-.1-.2-.2-.3-.4s0-.3.1-.5.2-.2.4-.3.3 0 .5.1c.8.5 1.7.8 2.8.8s2-.2 2.8-.7c.1-.1.3-.1.5-.1s.3.1.4.3l-.1.5zm1.2-4.3c-.5.4-1.1.6-1.8.6s-1.3-.2-1.8-.6S12 9.6 12 9c.6.6 1.5.9 2.5.9s1.9-.3 2.5-.9c0 .6-.2 1-.7 1.4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M7 5h12v12c0 1.7-1.3 3-3 3H4V8c0-1.7 1.3-3 3-3zm9.3 5.4c.5-.4.7-.8.7-1.4-.6.6-1.5.9-2.5.9S12.6 9.6 12 9c0 .6.2 1 .7 1.4.5.4 1.1.6 1.8.6s1.3-.2 1.8-.6zm-8.4 4.3c0 .2.1.3.3.4 1 .6 2.2.9 3.5.9 1.2 0 2.3-.3 3.3-1 .2-.1.2-.2.3-.4.1-.2 0-.3-.1-.5s-.2-.2-.4-.3c-.2-.1-.3 0-.5.1-.8.5-1.7.8-2.8.8-1.1 0-2-.2-2.8-.7-.1-.1-.3-.1-.5-.1s-.3.1-.4.3l.1.5zm-1.2-4.3c.5.4 1.1.6 1.8.6s1.3-.2 1.8-.6c.5-.4.7-.8.7-1.4-.6.6-1.5.9-2.5.9S6.6 9.6 6 9c0 .6.2 1 .7 1.4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M7 5h12v12c0 1.7-1.3 3-3 3H4V8c0-1.7 1.3-3 3-3zm9.3 5.4c.5-.4.7-.8.7-1.4-.6.6-1.5.9-2.5.9S12.6 9.6 12 9c0 .6.2 1 .7 1.4.5.4 1.1.6 1.8.6s1.3-.2 1.8-.6zm-8.4 4.3c0 .2.1.3.3.4 1 .6 2.2.9 3.5.9 1.2 0 2.3-.3 3.3-1 .2-.1.2-.2.3-.4.1-.2 0-.3-.1-.5s-.2-.2-.4-.3c-.2-.1-.3 0-.5.1-.8.5-1.7.8-2.8.8-1.1 0-2-.2-2.8-.7-.1-.1-.3-.1-.5-.1s-.3.1-.4.3l.1.5zm-1.2-4.3c.5.4 1.1.6 1.8.6s1.3-.2 1.8-.6c.5-.4.7-.8.7-1.4-.6.6-1.5.9-2.5.9S6.6 9.6 6 9c0 .6.2 1 .7 1.4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M5 6v11l-3 3h17c1.7 0 3-1.3 3-3V6H5zm11.2 2.5c.7 0 1.2.6 1.2 1.2s-.5 1.3-1.2 1.3-1.2-.6-1.2-1.2.6-1.3 1.2-1.3zm-5.4 0c.7 0 1.2.6 1.2 1.2s-.6 1.3-1.2 1.3-1.2-.6-1.2-1.2.5-1.3 1.2-1.3zm2.7 8.5c-5.1 0-6-5-6-5s2 1 6 1l6-1s-1 5-6 5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M5 6v11l-3 3h17c1.7 0 3-1.3 3-3V6H5zm11.2 2.5c.7 0 1.2.6 1.2 1.2s-.5 1.3-1.2 1.3-1.2-.6-1.2-1.2.6-1.3 1.2-1.3zm-5.4 0c.7 0 1.2.6 1.2 1.2s-.6 1.3-1.2 1.3-1.2-.6-1.2-1.2.5-1.3 1.2-1.3zm2.7 8.5c-5.1 0-6-5-6-5s2 1 6 1l6-1s-1 5-6 5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M19 6v11l3 3H5c-1.7 0-3-1.3-3-3V6h17zM7.8 8.5c-.7 0-1.2.6-1.2 1.2S7.1 11 7.8 11 9 10.4 9 9.8s-.6-1.3-1.2-1.3zm5.4 0c-.7 0-1.2.6-1.2 1.2s.6 1.3 1.2 1.3 1.2-.6 1.2-1.2-.5-1.3-1.2-1.3zM10.5 17c5.1 0 6-5 6-5s-2 1-6 1l-6-1s1 5 6 5z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M19 6v11l3 3H5c-1.7 0-3-1.3-3-3V6h17zM7.8 8.5c-.7 0-1.2.6-1.2 1.2S7.1 11 7.8 11 9 10.4 9 9.8s-.6-1.3-1.2-1.3zm5.4 0c-.7 0-1.2.6-1.2 1.2s.6 1.3 1.2 1.3 1.2-.6 1.2-1.2-.5-1.3-1.2-1.3zM10.5 17c5.1 0 6-5 6-5s-2 1-6 1l-6-1s1 5 6 5z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="viewCompact">
<circle cx="6" cy="6" r="2"/>
<circle cx="12" cy="6" r="2"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="viewCompact">
+ <circle cx="6" cy="6" r="2"/>
+ <circle cx="12" cy="6" r="2"/>
+ <circle cx="18" cy="6" r="2"/>
+ <circle cx="6" cy="12" r="2"/>
+ <circle cx="12" cy="12" r="2"/>
+ <circle cx="18" cy="12" r="2"/>
+ <circle cx="6" cy="18" r="2"/>
+ <circle cx="12" cy="18" r="2"/>
+ <circle cx="18" cy="18" r="2"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="viewDetails">
<circle cx="5.5" cy="8.5" r="2.5"/>
<path d="M10 6h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="viewDetails">
+ <circle cx="5.5" cy="8.5" r="2.5"/>
+ <path d="M10 6h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
+ <circle cx="5.5" cy="16.5" r="2.5"/>
+ <path d="M10 14h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="viewDetails">
<circle cx="18.5" cy="8.5" r="2.5"/>
<path d="M14 6H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="viewDetails">
+ <circle cx="18.5" cy="8.5" r="2.5"/>
+ <path d="M14 6H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
+ <circle cx="18.5" cy="16.5" r="2.5"/>
+ <path d="M14 14H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M13 14h5v1h-5v-1zm0 3h5v-1h-5v1zm0 1h5v1h-5v-1zm-1-5v3l-5 3 1-6-4-3 6-1 2-5s1.9 5 2 5l6 1-4 3h-4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M13 14h5v1h-5v-1zm0 3h5v-1h-5v1zm0 1h5v1h-5v-1zm-1-5v3l-5 3 1-6-4-3 6-1 2-5s1.9 5 2 5l6 1-4 3h-4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M11 14H6v1h5v-1zm0 3H6v-1h5v1zm0 1H6v1h5v-1zm1-5v3l5 3-1-6 4-3-6-1-2-5s-1.9 5-2 5l-6 1 4 3h4z"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M11 14H6v1h5v-1zm0 3H6v-1h5v1zm0 1H6v1h5v-1zm1-5v3l5 3-1-6 4-3-6-1-2-5s-1.9 5-2 5l-6 1 4 3h4z"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="wikiText">
<path id="opening-bracket-inner" d="M7 19h3v-2H9V7h1V5H7z"/>
<path id="closing-bracket-inner" d="M17 19h-3v-2h1V7h-1V5h3z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="wikiText">
+ <path id="opening-bracket-inner" d="M7 19h3v-2H9V7h1V5H7z"/>
+ <path id="closing-bracket-inner" d="M17 19h-3v-2h1V7h-1V5h3z"/>
+ <path id="closing-bracket-outer" d="M21 19h-3v-2h1V7h-1V5h3z"/>
+ <path id="opening-bracket-outer" d="M3 19h3v-2H5V7h1V5H3z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
<circle cx="8" cy="5" r="2"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
<circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
+ <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
<g id="window">
<path id="title" d="M7 10h10v1H7z"/>
<path id="frame" d="M16 19H8c-2.206 0-4-1.794-4-4V9c0-2.206 1.794-4 4-4h8c2.206 0 4 1.794 4 4v6c0 2.206-1.794 4-4 4zM8 7c-1.103 0-2 .897-2 2v6c0 1.103.897 2 2 2h8c1.103 0 2-.897 2-2V9c0-1.103-.897-2-2-2H8z"/>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+ <g id="window">
+ <path id="title" d="M7 10h10v1H7z"/>
+ <path id="frame" d="M16 19H8c-2.206 0-4-1.794-4-4V9c0-2.206 1.794-4 4-4h8c2.206 0 4 1.794 4 4v6c0 2.206-1.794 4-4 4zM8 7c-1.103 0-2 .897-2 2v6c0 1.103.897 2 2 2h8c1.103 0 2-.897 2-2V9c0-1.103-.897-2-2-2H8z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<path d="M6 12A6 6 0 1 1 6 0a6 6 0 0 1 0 12zM5 7h2V2H5zm0 3h2V8H5z" id="alert"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <path d="M6 12A6 6 0 1 1 6 0a6 6 0 0 1 0 12zM5 7h2V2H5zm0 3h2V8H5z" id="alert"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="down">
<path id="arrow" d="M1 4h10L6 9 1 4"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="down">
+ <path id="arrow" d="M1 4h10L6 9 1 4"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="ltr">
<path id="arrow" d="M4 1v10l5-5-5-5"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="ltr">
+ <path id="arrow" d="M4 1v10l5-5-5-5"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="rtl">
<path id="arrow" d="M8 11V1L3 6l5 5"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="rtl">
+ <path id="arrow" d="M8 11V1L3 6l5 5"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="up">
<path id="arrow" d="M1 8h10L6 3 1 8"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="up">
+ <path id="arrow" d="M1 8h10L6 3 1 8"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="clear">
<path id="circle-with-cross" d="M6 0C2.7 0 0 2.7 0 6s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zM3.5 2.5L6 5l2.5-2.5 1 1L7 6l2.5 2.5-1 1L6 7 3.5 9.5l-1-1L5 6 2.5 3.5z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="clear">
+ <path id="circle-with-cross" d="M6 0C2.7 0 0 2.7 0 6s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zM3.5 2.5L6 5l2.5-2.5 1 1L7 6l2.5 2.5-1 1L6 7 3.5 9.5l-1-1L5 6 2.5 3.5z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<path d="M5 1h2v10H5zm4.83 1.634l1 1.732-8.66 5-1-1.732zM1.17 4.366l1-1.732 8.66 5-1 1.732z" id="required"/>
</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <path d="M5 1h2v10H5zm4.83 1.634l1 1.732-8.66 5-1-1.732zM1.17 4.366l1-1.732 8.66 5-1 1.732z" id="required"/>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="search">
<path id="magnifying-glass" d="M10.37 9.474L7.994 7.1l-.17-.1a3.45 3.45 0 0 0 .644-2.01A3.478 3.478 0 1 0 4.99 8.47c.75 0 1.442-.24 2.01-.648l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27a2.21 2.21 0 1 1 2.21-2.21A2.21 2.21 0 0 1 4.99 7.21z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="search">
+ <path id="magnifying-glass" d="M10.37 9.474L7.994 7.1l-.17-.1a3.45 3.45 0 0 0 .644-2.01A3.478 3.478 0 1 0 4.99 8.47c.75 0 1.442-.24 2.01-.648l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27a2.21 2.21 0 1 1 2.21-2.21A2.21 2.21 0 0 1 4.99 7.21z"/>
+ </g>
+</svg>
<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #fff }</style>
<g id="search">
<path id="magnifying-glass" d="M1.63 9.474L4.006 7.1l.17-.1a3.45 3.45 0 0 1-.644-2.01A3.478 3.478 0 1 1 7.01 8.47 3.43 3.43 0 0 1 5 7.822l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27A2.21 2.21 0 1 0 4.8 4.994 2.21 2.21 0 0 0 7.01 7.21z"/>
</g>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #36c }</style>
+ <g id="search">
+ <path id="magnifying-glass" d="M1.63 9.474L4.006 7.1l.17-.1a3.45 3.45 0 0 1-.644-2.01A3.478 3.478 0 1 1 7.01 8.47 3.43 3.43 0 0 1 5 7.822l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27A2.21 2.21 0 1 0 4.8 4.994 2.21 2.21 0 0 0 7.01 7.21z"/>
+ </g>
+</svg>
"intro": "@import '../../../../src/styles/common';",
"variants": {
"invert": {
- "color": "#ffffff",
+ "color": "#fff",
"global": true
+ },
+ "progressive": {
+ "color": "#36c",
+ "global": true
+ },
+ "constructive": {
+ "color": "#36c"
+ },
+ "destructive": {
+ "color": "#c33"
+ },
+ "warning": {
+ "color": "#ff5d00"
}
},
"images": {
+++ /dev/null
-Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io)
-and Contributors (http://phpjs.org/authors)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+++ /dev/null
-.arrowSteps {
- list-style-type: none;
- list-style-image: none;
- border: 1px solid #666;
- position: relative;
-}
-
-.arrowSteps li {
- float: left;
- padding: 0px;
- margin: 0px;
- border: 0 none;
-}
-
-.arrowSteps li div {
- padding: 0.5em;
- text-align: center;
- white-space: nowrap;
- overflow: hidden;
-}
-
-.arrowSteps li.arrow div {
- /* @embed */
- background: url( images/jquery.arrowSteps.divider-ltr.png ) no-repeat right center;
-}
-
-/* applied to the element preceding the highlighted step */
-.arrowSteps li.arrow.tail div {
- /* @embed */
- background: url( images/jquery.arrowSteps.tail-ltr.png ) no-repeat right center;
-}
-
-/* this applies to all highlighted, including the last */
-.arrowSteps li.head div {
- /* @embed */
- background: url( images/jquery.arrowSteps.head-ltr.png ) no-repeat left center;
- font-weight: bold;
-}
-
-/* this applies to all highlighted arrows except the last */
-.arrowSteps li.arrow.head div {
- /* TODO: eliminate duplication of jquery.arrowSteps.head.png embedding */
- /* @embed */
- background: url( images/jquery.arrowSteps.head-ltr.png ) no-repeat right center;
-}
+++ /dev/null
-/*!
- * jQuery arrowSteps plugin
- * Copyright Neil Kandalgaonkar, 2010
- *
- * This work is licensed under the terms of the GNU General Public License,
- * version 2 or later.
- * (see http://www.fsf.org/licensing/licenses/gpl.html).
- * Derivative works and later versions of the code must be free software
- * licensed under the same or a compatible license.
- */
-
-/**
- * @class jQuery.plugin.arrowSteps
- */
-( function ( $ ) {
- /**
- * Show users their progress through a series of steps, via a row of items that fit
- * together like arrows. One item can be highlighted at a time.
- *
- * <ul id="robin-hood-daffy">
- * <li id="guard"><div>Guard!</div></li>
- * <li id="turn"><div>Turn!</div></li>
- * <li id="parry"><div>Parry!</div></li>
- * <li id="dodge"><div>Dodge!</div></li>
- * <li id="spin"><div>Spin!</div></li>
- * <li id="ha"><div>Ha!</div></li>
- * <li id="thrust"><div>Thrust!</div></li>
- * </ul>
- *
- * <script>
- * $( '#robin-hood-daffy' ).arrowSteps();
- * </script>
- *
- * @return {jQuery}
- * @chainable
- */
- $.fn.arrowSteps = function () {
- var $steps, width, arrowWidth, $stepDiv,
- $el = this,
- paddingSide = $( 'body' ).hasClass( 'rtl' ) ? 'padding-left' : 'padding-right';
-
- $el.addClass( 'arrowSteps' );
- $steps = $el.find( 'li' );
-
- width = parseInt( 100 / $steps.length, 10 );
- $steps.css( 'width', width + '%' );
-
- // Every step except the last one has an arrow pointing forward:
- // at the right hand side in LTR languages, and at the left hand side in RTL.
- // Also add in the padding for the calculated arrow width.
- $stepDiv = $steps.filter( ':not(:last-child)' ).addClass( 'arrow' ).find( 'div' );
-
- // Execute when complete page is fully loaded, including all frames, objects and images
- $( window ).on( 'load', function () {
- arrowWidth = parseInt( $el.outerHeight(), 10 );
- $stepDiv.css( paddingSide, arrowWidth.toString() + 'px' );
- } );
-
- $el.data( 'arrowSteps', $steps );
-
- return this;
- };
-
- /**
- * Highlights the element selected by the selector.
- *
- * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#guard' );
- * // 'Guard!' is highlighted.
- *
- * // ... user completes the 'guard' step ...
- *
- * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#turn' );
- * // 'Turn!' is highlighted.
- *
- * @param {string} selector
- */
- $.fn.arrowStepsHighlight = function ( selector ) {
- var $previous,
- $steps = this.data( 'arrowSteps' );
- $.each( $steps, function ( i, step ) {
- var $step = $( step );
- if ( $step.is( selector ) ) {
- if ( $previous ) {
- $previous.addClass( 'tail' );
- }
- $step.addClass( 'head' );
- } else {
- $step.removeClass( 'head tail lasthead' );
- }
- $previous = $step;
- } );
- };
-
- /**
- * @class jQuery
- * @mixins jQuery.plugin.arrowSteps
- */
-}( jQuery ) );
/*!
* JavaScript for Special:MovePage
*/
-jQuery( function () {
+jQuery( function ( $ ) {
// Infuse for pretty dropdown
OO.ui.infuse( 'wpNewTitle' );
// Limit to 255 bytes, not characters
OO.ui.infuse( 'wpReason' ).$input.byteLimit();
// Infuse for nicer "help" popup
- OO.ui.infuse( 'wpMovetalk-field' );
+ if ( $( '#wpMovetalk-field' ).length ) {
+ OO.ui.infuse( 'wpMovetalk-field' );
+ }
} );
+++ /dev/null
-<?php
-/**
- * AutoLoader for the testing suite.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Testing
- */
-
-global $wgAutoloadClasses;
-$testDir = __DIR__;
-
-$wgAutoloadClasses += [
-
- # tests/phpunit
- 'MediaWikiTestCase' => "$testDir/phpunit/MediaWikiTestCase.php",
- 'MediaWikiPHPUnitTestListener' => "$testDir/phpunit/MediaWikiPHPUnitTestListener.php",
- 'MediaWikiLangTestCase' => "$testDir/phpunit/MediaWikiLangTestCase.php",
- 'ResourceLoaderTestCase' => "$testDir/phpunit/ResourceLoaderTestCase.php",
- 'ResourceLoaderTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
- 'ResourceLoaderFileModuleTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
- 'EmptyResourceLoader' => "$testDir/phpunit/ResourceLoaderTestCase.php",
- 'TestUser' => "$testDir/phpunit/includes/TestUser.php",
- 'TestUserRegistry' => "$testDir/phpunit/includes/TestUserRegistry.php",
- 'LessFileCompilationTest' => "$testDir/phpunit/LessFileCompilationTest.php",
-
- # tests/phpunit/includes
- 'RevisionStorageTest' => "$testDir/phpunit/includes/RevisionStorageTest.php",
- 'TestingAccessWrapper' => "$testDir/phpunit/includes/TestingAccessWrapper.php",
- 'TestLogger' => "$testDir/phpunit/includes/TestLogger.php",
-
- # tests/phpunit/includes/api
- 'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php",
- 'ApiQueryTestBase' => "$testDir/phpunit/includes/api/query/ApiQueryTestBase.php",
- 'ApiQueryContinueTestBase' => "$testDir/phpunit/includes/api/query/ApiQueryContinueTestBase.php",
- 'ApiTestCase' => "$testDir/phpunit/includes/api/ApiTestCase.php",
- 'ApiTestCaseUpload' => "$testDir/phpunit/includes/api/ApiTestCaseUpload.php",
- 'ApiTestContext' => "$testDir/phpunit/includes/api/ApiTestContext.php",
- 'MockApi' => "$testDir/phpunit/includes/api/MockApi.php",
- 'MockApiQueryBase' => "$testDir/phpunit/includes/api/MockApiQueryBase.php",
- 'UserWrapper' => "$testDir/phpunit/includes/api/UserWrapper.php",
- 'RandomImageGenerator' => "$testDir/phpunit/includes/api/RandomImageGenerator.php",
-
- # tests/phpunit/includes/auth
- 'MediaWiki\\Auth\\AuthenticationRequestTestCase' =>
- "$testDir/phpunit/includes/auth/AuthenticationRequestTestCase.php",
-
- # tests/phpunit/includes/changes
- 'TestRecentChangesHelper' => "$testDir/phpunit/includes/changes/TestRecentChangesHelper.php",
-
- # tests/phpunit/includes/content
- 'DummyContentHandlerForTesting' =>
- "$testDir/phpunit/mocks/content/DummyContentHandlerForTesting.php",
- 'DummyContentForTesting' => "$testDir/phpunit/mocks/content/DummyContentForTesting.php",
- 'DummyNonTextContentHandler' => "$testDir/phpunit/mocks/content/DummyNonTextContentHandler.php",
- 'DummyNonTextContent' => "$testDir/phpunit/mocks/content/DummyNonTextContent.php",
- 'ContentHandlerTest' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
- 'JavaScriptContentTest' => "$testDir/phpunit/includes/content/JavaScriptContentTest.php",
- 'TextContentTest' => "$testDir/phpunit/includes/content/TextContentTest.php",
- 'WikitextContentTest' => "$testDir/phpunit/includes/content/WikitextContentTest.php",
-
- # tests/phpunit/includes/db
- 'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php",
-
- # tests/phpunit/includes/diff
- 'FakeDiffOp' => "$testDir/phpunit/includes/diff/FakeDiffOp.php",
-
- # tests/phpunit/includes/logging
- 'LogFormatterTestCase' => "$testDir/phpunit/includes/logging/LogFormatterTestCase.php",
-
- # tests/phpunit/includes/page
- 'WikiPageTest' => "$testDir/phpunit/includes/page/WikiPageTest.php",
-
- # tests/phpunit/includes/password
- 'PasswordTestCase' => "$testDir/phpunit/includes/password/PasswordTestCase.php",
-
- # tests/phpunit/includes/resourceloader
- 'ResourceLoaderImageModuleTest' =>
- "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
- 'ResourceLoaderImageModuleTestable' =>
- "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
-
- # tests/phpunit/includes/session
- 'MediaWiki\\Session\\TestBagOStuff' => "$testDir/phpunit/includes/session/TestBagOStuff.php",
- 'MediaWiki\\Session\\TestUtils' => "$testDir/phpunit/includes/session/TestUtils.php",
-
- # tests/phpunit/includes/specials
- 'SpecialPageTestBase' => "$testDir/phpunit/includes/specials/SpecialPageTestBase.php",
- 'SpecialPageExecutor' => "$testDir/phpunit/includes/specials/SpecialPageExecutor.php",
-
- # tests/phpunit/languages
- 'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",
-
- # tests/phpunit/includes/libs
- 'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php",
-
- # tests/phpunit/maintenance
- 'DumpTestCase' => "$testDir/phpunit/maintenance/DumpTestCase.php",
-
- # tests/phpunit/media
- 'FakeDimensionFile' => "$testDir/phpunit/includes/media/FakeDimensionFile.php",
- 'MediaWikiMediaTestCase' => "$testDir/phpunit/includes/media/MediaWikiMediaTestCase.php",
-
- # tests/phpunit/mocks
- 'MockFSFile' => "$testDir/phpunit/mocks/filebackend/MockFSFile.php",
- 'MockFileBackend' => "$testDir/phpunit/mocks/filebackend/MockFileBackend.php",
- 'MockBitmapHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php",
- 'MockImageHandler' => "$testDir/phpunit/mocks/media/MockImageHandler.php",
- 'MockSvgHandler' => "$testDir/phpunit/mocks/media/MockSvgHandler.php",
- 'MockDjVuHandler' => "$testDir/phpunit/mocks/media/MockDjVuHandler.php",
- 'MockOggHandler' => "$testDir/phpunit/mocks/media/MockOggHandler.php",
- 'MockMediaHandlerFactory' => "$testDir/phpunit/mocks/media/MockMediaHandlerFactory.php",
- 'MockWebRequest' => "$testDir/phpunit/mocks/MockWebRequest.php",
- 'MediaWiki\\Session\\DummySessionBackend'
- => "$testDir/phpunit/mocks/session/DummySessionBackend.php",
- 'DummySessionProvider' => "$testDir/phpunit/mocks/session/DummySessionProvider.php",
-
- # tests/parser
- 'DbTestPreviewer' => "$testDir/parser/DbTestPreviewer.php",
- 'DbTestRecorder' => "$testDir/parser/DbTestRecorder.php",
- 'DelayedParserTest' => "$testDir/parser/DelayedParserTest.php",
- 'DjVuSupport' => "$testDir/parser/DjVuSupport.php",
- 'ITestRecorder' => "$testDir/parser/ITestRecorder.php",
- 'MediaWikiParserTest' => "$testDir/phpunit/includes/parser/MediaWikiParserTest.php",
- 'NewParserTest' => "$testDir/phpunit/includes/parser/NewParserTest.php",
- 'ParserTest' => "$testDir/parser/ParserTest.php",
- 'ParserTestParserHook' => "$testDir/parser/ParserTestParserHook.php",
- 'ParserTestResult' => "$testDir/parser/ParserTestResult.php",
- 'ParserTestResultNormalizer' => "$testDir/parser/ParserTestResultNormalizer.php",
- 'TestFileDataProvider' => "$testDir/parser/TestFileDataProvider.php",
- 'TestFileIterator' => "$testDir/parser/TestFileIterator.php",
- 'TestRecorder' => "$testDir/parser/TestRecorder.php",
- 'TidySupport' => "$testDir/parser/TidySupport.php",
-
- # tests/phpunit/includes/site
- 'SiteTest' => "$testDir/phpunit/includes/site/SiteTest.php",
- 'TestSites' => "$testDir/phpunit/includes/site/TestSites.php",
-
- # tests/phpunit/includes/specialpage
- 'SpecialPageTestHelper' => "$testDir/phpunit/includes/specialpage/SpecialPageTestHelper.php",
-];
--- /dev/null
+<?php
+
+use MediaWiki\MediaWikiServices;
+
+/**
+ * Common code for test environment initialisation and teardown
+ */
+class TestSetup {
+ /**
+ * This should be called before Setup.php, e.g. from the finalSetup() method
+ * of a Maintenance subclass
+ */
+ public static function applyInitialConfig() {
+ global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgMainWANCache;
+ global $wgMainStash;
+ global $wgLanguageConverterCacheType, $wgUseDatabaseMessages;
+ global $wgLocaltimezone, $wgLocalisationCacheConf;
+ global $wgDevelopmentWarnings;
+ global $wgSessionProviders, $wgSessionPbkdf2Iterations;
+ global $wgJobTypeConf;
+ global $wgAuthManagerConfig, $wgAuth;
+
+ // wfWarn should cause tests to fail
+ $wgDevelopmentWarnings = true;
+
+ // Make sure all caches and stashes are either disabled or use
+ // in-process cache only to prevent tests from using any preconfigured
+ // cache meant for the local wiki from outside the test run.
+ // See also MediaWikiTestCase::run() which mocks CACHE_DB and APC.
+
+ // Disabled in DefaultSettings, override local settings
+ $wgMainWANCache =
+ $wgMainCacheType = CACHE_NONE;
+ // Uses CACHE_ANYTHING in DefaultSettings, use hash instead of db
+ $wgMessageCacheType =
+ $wgParserCacheType =
+ $wgSessionCacheType =
+ $wgLanguageConverterCacheType = 'hash';
+ // Uses db-replicated in DefaultSettings
+ $wgMainStash = 'hash';
+ // Use memory job queue
+ $wgJobTypeConf = [
+ 'default' => [ 'class' => 'JobQueueMemory', 'order' => 'fifo' ],
+ ];
+
+ $wgUseDatabaseMessages = false; # Set for future resets
+
+ // Assume UTC for testing purposes
+ $wgLocaltimezone = 'UTC';
+
+ $wgLocalisationCacheConf['storeClass'] = 'LCStoreNull';
+
+ // Generic MediaWiki\Session\SessionManager configuration for tests
+ // We use CookieSessionProvider because things might be expecting
+ // cookies to show up in a FauxRequest somewhere.
+ $wgSessionProviders = [
+ [
+ 'class' => MediaWiki\Session\CookieSessionProvider::class,
+ 'args' => [ [
+ 'priority' => 30,
+ 'callUserSetCookiesHook' => true,
+ ] ],
+ ],
+ ];
+
+ // Single-iteration PBKDF2 session secret derivation, for speed.
+ $wgSessionPbkdf2Iterations = 1;
+
+ // Generic AuthManager configuration for testing
+ $wgAuthManagerConfig = [
+ 'preauth' => [],
+ 'primaryauth' => [
+ [
+ 'class' => MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider::class,
+ 'args' => [ [
+ 'authoritative' => false,
+ ] ],
+ ],
+ [
+ 'class' => MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider::class,
+ 'args' => [ [
+ 'authoritative' => true,
+ ] ],
+ ],
+ ],
+ 'secondaryauth' => [],
+ ];
+ $wgAuth = new MediaWiki\Auth\AuthManagerAuthPlugin();
+
+ // Bug 44192 Do not attempt to send a real e-mail
+ Hooks::clear( 'AlternateUserMailer' );
+ Hooks::register(
+ 'AlternateUserMailer',
+ function () {
+ return false;
+ }
+ );
+ // xdebug's default of 100 is too low for MediaWiki
+ ini_set( 'xdebug.max_nesting_level', 1000 );
+
+ // Bug T116683 serialize_precision of 100
+ // may break testing against floating point values
+ // treated with PHP's serialize()
+ ini_set( 'serialize_precision', 17 );
+
+ // TODO: we should call MediaWikiTestCase::prepareServices( new GlobalVarConfig() ) here.
+ // But PHPUnit may not be loaded yet, so we have to wait until just
+ // before PHPUnit_TextUI_Command::main() is executed.
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * AutoLoader for the testing suite.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Testing
+ */
+
+global $wgAutoloadClasses;
+$testDir = __DIR__ . "/..";
+
+$wgAutoloadClasses += [
+
+ # tests/common
+ 'TestSetup' => "$testDir/common/TestSetup.php",
+
+ # tests/parser
+ 'DbTestPreviewer' => "$testDir/parser/DbTestPreviewer.php",
+ 'DbTestRecorder' => "$testDir/parser/DbTestRecorder.php",
+ 'DjVuSupport' => "$testDir/parser/DjVuSupport.php",
+ 'TestRecorder' => "$testDir/parser/TestRecorder.php",
+ 'MultiTestRecorder' => "$testDir/parser/MultiTestRecorder.php",
+ 'ParserTestRunner' => "$testDir/parser/ParserTestRunner.php",
+ 'ParserTestParserHook' => "$testDir/parser/ParserTestParserHook.php",
+ 'ParserTestPrinter' => "$testDir/parser/ParserTestPrinter.php",
+ 'ParserTestResult' => "$testDir/parser/ParserTestResult.php",
+ 'ParserTestResultNormalizer' => "$testDir/parser/ParserTestResultNormalizer.php",
+ 'PhpunitTestRecorder' => "$testDir/parser/PhpunitTestRecorder.php",
+ 'TestFileReader' => "$testDir/parser/TestFileReader.php",
+ 'TestRecorder' => "$testDir/parser/TestRecorder.php",
+ 'TidySupport' => "$testDir/parser/TidySupport.php",
+
+ # tests/phpunit
+ 'MediaWikiTestCase' => "$testDir/phpunit/MediaWikiTestCase.php",
+ 'MediaWikiPHPUnitTestListener' => "$testDir/phpunit/MediaWikiPHPUnitTestListener.php",
+ 'MediaWikiLangTestCase' => "$testDir/phpunit/MediaWikiLangTestCase.php",
+ 'ResourceLoaderTestCase' => "$testDir/phpunit/ResourceLoaderTestCase.php",
+ 'ResourceLoaderTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
+ 'ResourceLoaderFileModuleTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
+ 'EmptyResourceLoader' => "$testDir/phpunit/ResourceLoaderTestCase.php",
+ 'TestUser' => "$testDir/phpunit/includes/TestUser.php",
+ 'TestUserRegistry' => "$testDir/phpunit/includes/TestUserRegistry.php",
+ 'LessFileCompilationTest' => "$testDir/phpunit/LessFileCompilationTest.php",
+
+ # tests/phpunit/includes
+ 'RevisionStorageTest' => "$testDir/phpunit/includes/RevisionStorageTest.php",
+ 'TestingAccessWrapper' => "$testDir/phpunit/includes/TestingAccessWrapper.php",
+ 'TestLogger' => "$testDir/phpunit/includes/TestLogger.php",
+
+ # tests/phpunit/includes/api
+ 'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php",
+ 'ApiQueryTestBase' => "$testDir/phpunit/includes/api/query/ApiQueryTestBase.php",
+ 'ApiQueryContinueTestBase' => "$testDir/phpunit/includes/api/query/ApiQueryContinueTestBase.php",
+ 'ApiTestCase' => "$testDir/phpunit/includes/api/ApiTestCase.php",
+ 'ApiTestCaseUpload' => "$testDir/phpunit/includes/api/ApiTestCaseUpload.php",
+ 'ApiTestContext' => "$testDir/phpunit/includes/api/ApiTestContext.php",
+ 'MockApi' => "$testDir/phpunit/includes/api/MockApi.php",
+ 'MockApiQueryBase' => "$testDir/phpunit/includes/api/MockApiQueryBase.php",
+ 'UserWrapper' => "$testDir/phpunit/includes/api/UserWrapper.php",
+ 'RandomImageGenerator' => "$testDir/phpunit/includes/api/RandomImageGenerator.php",
+
+ # tests/phpunit/includes/auth
+ 'MediaWiki\\Auth\\AuthenticationRequestTestCase' =>
+ "$testDir/phpunit/includes/auth/AuthenticationRequestTestCase.php",
+
+ # tests/phpunit/includes/changes
+ 'TestRecentChangesHelper' => "$testDir/phpunit/includes/changes/TestRecentChangesHelper.php",
+
+ # tests/phpunit/includes/content
+ 'DummyContentHandlerForTesting' =>
+ "$testDir/phpunit/mocks/content/DummyContentHandlerForTesting.php",
+ 'DummyContentForTesting' => "$testDir/phpunit/mocks/content/DummyContentForTesting.php",
+ 'DummyNonTextContentHandler' => "$testDir/phpunit/mocks/content/DummyNonTextContentHandler.php",
+ 'DummyNonTextContent' => "$testDir/phpunit/mocks/content/DummyNonTextContent.php",
+ 'ContentHandlerTest' => "$testDir/phpunit/includes/content/ContentHandlerTest.php",
+ 'JavaScriptContentTest' => "$testDir/phpunit/includes/content/JavaScriptContentTest.php",
+ 'TextContentTest' => "$testDir/phpunit/includes/content/TextContentTest.php",
+ 'WikitextContentTest' => "$testDir/phpunit/includes/content/WikitextContentTest.php",
+
+ # tests/phpunit/includes/db
+ 'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php",
+
+ # tests/phpunit/includes/diff
+ 'FakeDiffOp' => "$testDir/phpunit/includes/diff/FakeDiffOp.php",
+
+ # tests/phpunit/includes/logging
+ 'LogFormatterTestCase' => "$testDir/phpunit/includes/logging/LogFormatterTestCase.php",
+
+ # tests/phpunit/includes/page
+ 'WikiPageTest' => "$testDir/phpunit/includes/page/WikiPageTest.php",
+
+ # tests/phpunit/includes/parser
+ 'ParserIntegrationTest' => "$testDir/phpunit/includes/parser/ParserIntegrationTest.php",
+
+ # tests/phpunit/includes/password
+ 'PasswordTestCase' => "$testDir/phpunit/includes/password/PasswordTestCase.php",
+
+ # tests/phpunit/includes/resourceloader
+ 'ResourceLoaderImageModuleTest' =>
+ "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
+ 'ResourceLoaderImageModuleTestable' =>
+ "$testDir/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php",
+
+ # tests/phpunit/includes/session
+ 'MediaWiki\\Session\\TestBagOStuff' => "$testDir/phpunit/includes/session/TestBagOStuff.php",
+ 'MediaWiki\\Session\\TestUtils' => "$testDir/phpunit/includes/session/TestUtils.php",
+
+ # tests/phpunit/includes/site
+ 'SiteTest' => "$testDir/phpunit/includes/site/SiteTest.php",
+ 'TestSites' => "$testDir/phpunit/includes/site/TestSites.php",
+
+ # tests/phpunit/includes/specialpage
+ 'SpecialPageTestHelper' => "$testDir/phpunit/includes/specialpage/SpecialPageTestHelper.php",
+
+ # tests/phpunit/includes/specials
+ 'SpecialPageTestBase' => "$testDir/phpunit/includes/specials/SpecialPageTestBase.php",
+ 'SpecialPageExecutor' => "$testDir/phpunit/includes/specials/SpecialPageExecutor.php",
+
+ # tests/phpunit/languages
+ 'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",
+
+ # tests/phpunit/includes/libs
+ 'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php",
+
+ # tests/phpunit/maintenance
+ 'DumpTestCase' => "$testDir/phpunit/maintenance/DumpTestCase.php",
+
+ # tests/phpunit/media
+ 'FakeDimensionFile' => "$testDir/phpunit/includes/media/FakeDimensionFile.php",
+ 'MediaWikiMediaTestCase' => "$testDir/phpunit/includes/media/MediaWikiMediaTestCase.php",
+
+ # tests/phpunit/mocks
+ 'MockFSFile' => "$testDir/phpunit/mocks/filebackend/MockFSFile.php",
+ 'MockFileBackend' => "$testDir/phpunit/mocks/filebackend/MockFileBackend.php",
+ 'MockBitmapHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php",
+ 'MockImageHandler' => "$testDir/phpunit/mocks/media/MockImageHandler.php",
+ 'MockSvgHandler' => "$testDir/phpunit/mocks/media/MockSvgHandler.php",
+ 'MockDjVuHandler' => "$testDir/phpunit/mocks/media/MockDjVuHandler.php",
+ 'MockOggHandler' => "$testDir/phpunit/mocks/media/MockOggHandler.php",
+ 'MockMediaHandlerFactory' => "$testDir/phpunit/mocks/media/MockMediaHandlerFactory.php",
+ 'MockWebRequest' => "$testDir/phpunit/mocks/MockWebRequest.php",
+ 'MediaWiki\\Session\\DummySessionBackend'
+ => "$testDir/phpunit/mocks/session/DummySessionBackend.php",
+ 'DummySessionProvider' => "$testDir/phpunit/mocks/session/DummySessionProvider.php",
+
+ # tests/suites
+ 'ParserTestFileSuite' => "$testDir/phpunit/suites/ParserTestFileSuite.php",
+ 'ParserTestTopLevelSuite' => "$testDir/phpunit/suites/ParserTestTopLevelSuite.php",
+];
*/
class DbTestPreviewer extends TestRecorder {
+ protected $filter; // /< Test name filter callback
protected $lb; // /< Database load balancer
protected $db; // /< Database connection to the main DB
protected $curRun; // /< run ID number for the current run
/**
* This should be called before the table prefix is changed
- * @param TestRecorder $parent
*/
- function __construct( $parent ) {
- parent::__construct( $parent );
-
- $this->lb = wfGetLBFactory()->newMainLB();
- // This connection will have the wiki's table prefix, not parsertest_
- $this->db = $this->lb->getConnection( DB_MASTER );
+ function __construct( $db, $filter = false ) {
+ $this->db = $db;
+ $this->filter = $filter;
}
/**
* and all that fun stuff
*/
function start() {
- parent::start();
-
if ( !$this->db->tableExists( 'testrun', __METHOD__ )
|| !$this->db->tableExists( 'testitem', __METHOD__ )
) {
$this->results = [];
}
- function getName( $test, $subtest ) {
- if ( $subtest ) {
- return "$test subtest #$subtest";
- } else {
- return $test;
- }
- }
-
- function record( $test, $subtest, $result ) {
- parent::record( $test, $subtest, $result );
- $this->results[ $this->getName( $test, $subtest ) ] = $result;
+ function record( $test, ParserTestResult $result ) {
+ $this->results[$test['desc']] = $result->isSuccess() ? 1 : 0;
}
function report() {
$res = $this->db->select( 'testitem', [ 'ti_name', 'ti_success' ],
[ 'ti_run' => $this->prevRun ], __METHOD__ );
+ $filter = $this->filter;
foreach ( $res as $row ) {
- if ( !$this->parent->regex
- || preg_match( "/{$this->parent->regex}/i", $row->ti_name )
- ) {
+ if ( !$filter || $filter( $row->ti_name ) ) {
$prevResults[$row->ti_name] = $row->ti_success;
}
}
}
print "\n";
- parent::report();
}
/**
. date( "d-M-Y H:i:s", strtotime( $pre->tr_date ) ) . ", " . $pre->tr_mw_version
. " and $postDate";
}
-
- /**
- * Close the DB connection
- */
- function end() {
- $this->lb->closeAll();
- parent::end();
- }
}
* @ingroup Testing
*/
-class DbTestRecorder extends DbTestPreviewer {
+class DbTestRecorder extends TestRecorder {
public $version;
+ private $db;
+
+ public function __construct( IDatabase $db ) {
+ $this->db = $db;
+ }
/**
* Set up result recording; insert a record for the run with the date
echo "OK, resuming.\n";
}
- parent::start();
-
$this->db->insert( 'testrun',
[
'tr_date' => $this->db->timestamp(),
/**
* Record an individual test item's success or failure to the db
*
- * @param string $test
- * @param bool $result
+ * @param array $test
+ * @param ParserTestResult $result
*/
- function record( $test, $subtest, $result ) {
- parent::record( $test, $subtest, $result );
-
+ function record( $test, ParserTestResult $result ) {
$this->db->insert( 'testitem',
[
'ti_run' => $this->curRun,
- 'ti_name' => $this->getName( $test, $subtest ),
- 'ti_success' => $result ? 1 : 0,
+ 'ti_name' => $test['desc'],
+ 'ti_success' => $result->isSuccess() ? 1 : 0,
],
__METHOD__ );
}
*/
function end() {
$this->db->commit( __METHOD__ );
- parent::end();
}
}
+++ /dev/null
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Testing
- */
-
-/**
- * A class to delay execution of a parser test hooks.
- */
-class DelayedParserTest {
-
- /** Initialized on construction */
- private $hooks;
- private $fnHooks;
- private $transparentHooks;
-
- public function __construct() {
- $this->reset();
- }
-
- /**
- * Init/reset or forgot about the current delayed test.
- * Call to this will erase any hooks function that were pending.
- */
- public function reset() {
- $this->hooks = [];
- $this->fnHooks = [];
- $this->transparentHooks = [];
- }
-
- /**
- * Called whenever we actually want to run the hook.
- * Should be the case if we found the parserTest is not disabled
- * @param ParserTest|NewParserTest $parserTest
- * @return bool
- * @throws MWException
- */
- public function unleash( &$parserTest ) {
- if ( !( $parserTest instanceof ParserTest || $parserTest instanceof NewParserTest ) ) {
- throw new MWException( __METHOD__ . " must be passed an instance of ParserTest or "
- . "NewParserTest classes\n" );
- }
-
- # Trigger delayed hooks. Any failure will make us abort
- foreach ( $this->hooks as $hook ) {
- $ret = $parserTest->requireHook( $hook );
- if ( !$ret ) {
- return false;
- }
- }
-
- # Trigger delayed function hooks. Any failure will make us abort
- foreach ( $this->fnHooks as $fnHook ) {
- $ret = $parserTest->requireFunctionHook( $fnHook );
- if ( !$ret ) {
- return false;
- }
- }
-
- # Trigger delayed transparent hooks. Any failure will make us abort
- foreach ( $this->transparentHooks as $hook ) {
- $ret = $parserTest->requireTransparentHook( $hook );
- if ( !$ret ) {
- return false;
- }
- }
-
- # Delayed execution was successful.
- return true;
- }
-
- /**
- * Similar to ParserTest object but does not run anything
- * Use unleash() to really execute the hook
- * @param string $hook
- */
- public function requireHook( $hook ) {
- $this->hooks[] = $hook;
- }
-
- /**
- * Similar to ParserTest object but does not run anything
- * Use unleash() to really execute the hook function
- * @param string $fnHook
- */
- public function requireFunctionHook( $fnHook ) {
- $this->fnHooks[] = $fnHook;
- }
-
- /**
- * Similar to ParserTest object but does not run anything
- * Use unleash() to really execute the hook function
- * @param string $hook
- */
- public function requireTransparentHook( $hook ) {
- $this->transparentHooks[] = $hook;
- }
-
-}
-
+++ /dev/null
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Testing
- */
-
-/**
- * Interface to record parser test results.
- *
- * The ITestRecorder is a very simple interface to record the result of
- * MediaWiki parser tests. One should call start() before running the
- * full parser tests and end() once all the tests have been finished.
- * After each test, you should use record() to keep track of your tests
- * results. Finally, report() is used to generate a summary of your
- * test run, one could dump it to the console for human consumption or
- * register the result in a database for tracking purposes.
- *
- * @since 1.22
- */
-interface ITestRecorder {
-
- /**
- * Called at beginning of the parser test run
- */
- public function start();
-
- /**
- * Called after each test
- * @param string $test
- * @param integer $subtest
- * @param bool $result
- */
- public function record( $test, $subtest, $result );
-
- /**
- * Called before finishing the test run
- */
- public function report();
-
- /**
- * Called at the end of the parser test run
- */
- public function end();
-
-}
-
--- /dev/null
+<?php
+
+/**
+ * This is a TestRecorder representing a collection of other TestRecorders.
+ * It proxies calls to all constituent objects.
+ */
+class MultiTestRecorder extends TestRecorder {
+ private $recorders = [];
+
+ public function addRecorder( TestRecorder $recorder ) {
+ $this->recorders[] = $recorder;
+ }
+
+ private function proxy( $funcName, $args ) {
+ foreach ( $this->recorders as $recorder ) {
+ call_user_func_array( [ $recorder, $funcName ], $args );
+ }
+ }
+
+ public function start() {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function startTest( $test ) {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function startSuite( $path ) {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function endSuite( $path ) {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function record( $test, ParserTestResult $result ) {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function warning( $message ) {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function skipped( $test, $subtest ) {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function report() {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+
+ public function end() {
+ $this->proxy( __FUNCTION__, func_get_args() );
+ }
+}
+++ /dev/null
-<?php
-/**
- * Helper code for the MediaWiki parser test suite. Some code is duplicated
- * in PHPUnit's NewParserTests.php, so you'll probably want to update both
- * at the same time.
- *
- * Copyright © 2004, 2010 Brion Vibber <brion@pobox.com>
- * https://www.mediawiki.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @todo Make this more independent of the configuration (and if possible the database)
- * @todo document
- * @file
- * @ingroup Testing
- */
-use MediaWiki\MediaWikiServices;
-
-/**
- * @ingroup Testing
- */
-class ParserTest {
- /**
- * @var bool $color whereas output should be colorized
- */
- private $color;
-
- /**
- * @var bool $showOutput Show test output
- */
- private $showOutput;
-
- /**
- * @var bool $useTemporaryTables Use temporary tables for the temporary database
- */
- private $useTemporaryTables = true;
-
- /**
- * @var bool $databaseSetupDone True if the database has been set up
- */
- private $databaseSetupDone = false;
-
- /**
- * Our connection to the database
- * @var DatabaseBase
- */
- private $db;
-
- /**
- * Database clone helper
- * @var CloneDatabase
- */
- private $dbClone;
-
- /**
- * @var DjVuSupport
- */
- private $djVuSupport;
-
- /**
- * @var TidySupport
- */
- private $tidySupport;
-
- /**
- * @var ITestRecorder
- */
- private $recorder;
-
- private $uploadDir = null;
-
- public $regex = "";
- private $savedGlobals = [];
- private $useDwdiff = false;
- private $markWhitespace = false;
- private $normalizationFunctions = [];
-
- /**
- * Sets terminal colorization and diff/quick modes depending on OS and
- * command-line options (--color and --quick).
- * @param array $options
- */
- public function __construct( $options = [] ) {
- # Only colorize output if stdout is a terminal.
- $this->color = !wfIsWindows() && Maintenance::posix_isatty( 1 );
-
- if ( isset( $options['color'] ) ) {
- switch ( $options['color'] ) {
- case 'no':
- $this->color = false;
- break;
- case 'yes':
- default:
- $this->color = true;
- break;
- }
- }
-
- $this->term = $this->color
- ? new AnsiTermColorer()
- : new DummyTermColorer();
-
- $this->showDiffs = !isset( $options['quick'] );
- $this->showProgress = !isset( $options['quiet'] );
- $this->showFailure = !(
- isset( $options['quiet'] )
- && ( isset( $options['record'] )
- || isset( $options['compare'] ) ) ); // redundant output
-
- $this->showOutput = isset( $options['show-output'] );
- $this->useDwdiff = isset( $options['dwdiff'] );
- $this->markWhitespace = isset( $options['mark-ws'] );
-
- if ( isset( $options['norm'] ) ) {
- foreach ( explode( ',', $options['norm'] ) as $func ) {
- if ( in_array( $func, [ 'removeTbody', 'trimWhitespace' ] ) ) {
- $this->normalizationFunctions[] = $func;
- } else {
- echo "Warning: unknown normalization option \"$func\"\n";
- }
- }
- }
-
- if ( isset( $options['filter'] ) ) {
- $options['regex'] = $options['filter'];
- }
-
- if ( isset( $options['regex'] ) ) {
- if ( isset( $options['record'] ) ) {
- echo "Warning: --record cannot be used with --regex, disabling --record\n";
- unset( $options['record'] );
- }
- $this->regex = $options['regex'];
- } else {
- # Matches anything
- $this->regex = '';
- }
-
- $this->setupRecorder( $options );
- $this->keepUploads = isset( $options['keep-uploads'] );
-
- if ( $this->keepUploads ) {
- $this->uploadDir = wfTempDir() . '/mwParser-images';
- } else {
- $this->uploadDir = wfTempDir() . "/mwParser-" . mt_rand() . "-images";
- }
-
- $this->runDisabled = isset( $options['run-disabled'] );
- $this->runParsoid = isset( $options['run-parsoid'] );
-
- $this->djVuSupport = new DjVuSupport();
- $this->tidySupport = new TidySupport( isset( $options['use-tidy-config'] ) );
- if ( !$this->tidySupport->isEnabled() ) {
- echo "Warning: tidy is not installed, skipping some tests\n";
- }
-
- $this->hooks = [];
- $this->functionHooks = [];
- $this->transparentHooks = [];
- $this->setUp();
- }
-
- function setUp() {
- global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc,
- $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory,
- $wgExtraNamespaces, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo,
- $wgExtraInterlanguageLinkPrefixes, $wgLocalInterwikis,
- $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, $wgResourceBasePath,
- $wgArticlePath, $wgScript, $wgStylePath, $wgExtensionAssetsPath,
- $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgLockManagers;
-
- $wgScriptPath = '';
- $wgScript = '/index.php';
- $wgStylePath = '/skins';
- $wgResourceBasePath = '';
- $wgExtensionAssetsPath = '/extensions';
- $wgArticlePath = '/wiki/$1';
- $wgThumbnailScriptPath = false;
- $wgLockManagers = [ [
- 'name' => 'fsLockManager',
- 'class' => 'FSLockManager',
- 'lockDirectory' => $this->uploadDir . '/lockdir',
- ], [
- 'name' => 'nullLockManager',
- 'class' => 'NullLockManager',
- ] ];
- $wgLocalFileRepo = [
- 'class' => 'LocalRepo',
- 'name' => 'local',
- 'url' => 'http://example.com/images',
- 'hashLevels' => 2,
- 'transformVia404' => false,
- 'backend' => new FSFileBackend( [
- 'name' => 'local-backend',
- 'wikiId' => wfWikiID(),
- 'containerPaths' => [
- 'local-public' => $this->uploadDir . '/public',
- 'local-thumb' => $this->uploadDir . '/thumb',
- 'local-temp' => $this->uploadDir . '/temp',
- 'local-deleted' => $this->uploadDir . '/deleted',
- ]
- ] )
- ];
- $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface';
- $wgNamespaceAliases['Image'] = NS_FILE;
- $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK;
- # add a namespace shadowing a interwiki link, to test
- # proper precedence when resolving links. (bug 51680)
- $wgExtraNamespaces[100] = 'MemoryAlpha';
- $wgExtraNamespaces[101] = 'MemoryAlpha talk';
-
- // XXX: tests won't run without this (for CACHE_DB)
- if ( $wgMainCacheType === CACHE_DB ) {
- $wgMainCacheType = CACHE_NONE;
- }
- if ( $wgMessageCacheType === CACHE_DB ) {
- $wgMessageCacheType = CACHE_NONE;
- }
- if ( $wgParserCacheType === CACHE_DB ) {
- $wgParserCacheType = CACHE_NONE;
- }
-
- DeferredUpdates::clearPendingUpdates();
- $wgMemc = wfGetMainCache(); // checks $wgMainCacheType
- $messageMemc = wfGetMessageCacheStorage();
- $parserMemc = wfGetParserCacheStorage();
-
- RequestContext::resetMain();
- $context = new RequestContext;
- $wgUser = new User;
- $wgLang = $context->getLanguage();
- $wgOut = $context->getOutput();
- $wgRequest = $context->getRequest();
- $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], [ $wgParserConf ] );
-
- if ( $wgStyleDirectory === false ) {
- $wgStyleDirectory = "$IP/skins";
- }
-
- self::setupInterwikis();
- $wgLocalInterwikis = [ 'local', 'mi' ];
- // "extra language links"
- // see https://gerrit.wikimedia.org/r/111390
- array_push( $wgExtraInterlanguageLinkPrefixes, 'mul' );
-
- // Reset namespace cache
- MWNamespace::getCanonicalNamespaces( true );
- Language::factory( 'en' )->resetNamespaces();
- }
-
- /**
- * Insert hardcoded interwiki in the lookup table.
- *
- * This function insert a set of well known interwikis that are used in
- * the parser tests. They can be considered has fixtures are injected in
- * the interwiki cache by using the 'InterwikiLoadPrefix' hook.
- * Since we are not interested in looking up interwikis in the database,
- * the hook completely replace the existing mechanism (hook returns false).
- */
- public static function setupInterwikis() {
- # Hack: insert a few Wikipedia in-project interwiki prefixes,
- # for testing inter-language links
- Hooks::register( 'InterwikiLoadPrefix', function ( $prefix, &$iwData ) {
- static $testInterwikis = [
- 'local' => [
- 'iw_url' => 'http://doesnt.matter.org/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 0 ],
- 'wikipedia' => [
- 'iw_url' => 'http://en.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 0 ],
- 'meatball' => [
- 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 0 ],
- 'memoryalpha' => [
- 'iw_url' => 'http://www.memory-alpha.org/en/index.php/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 0 ],
- 'zh' => [
- 'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ],
- 'es' => [
- 'iw_url' => 'http://es.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ],
- 'fr' => [
- 'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ],
- 'ru' => [
- 'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ],
- 'mi' => [
- 'iw_url' => 'http://mi.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ],
- 'mul' => [
- 'iw_url' => 'http://wikisource.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ],
- ];
- if ( array_key_exists( $prefix, $testInterwikis ) ) {
- $iwData = $testInterwikis[$prefix];
- }
-
- // We only want to rely on the above fixtures
- return false;
- } );// hooks::register
- }
-
- /**
- * Remove the hardcoded interwiki lookup table.
- */
- public static function tearDownInterwikis() {
- Hooks::clear( 'InterwikiLoadPrefix' );
- }
-
- /**
- * Reset the Title-related services that need resetting
- * for each test
- */
- public static function resetTitleServices() {
- $services = MediaWikiServices::getInstance();
- $services->resetServiceForTesting( 'TitleFormatter' );
- $services->resetServiceForTesting( 'TitleParser' );
- $services->resetServiceForTesting( '_MediaWikiTitleCodec' );
- $services->resetServiceForTesting( 'LinkRenderer' );
- $services->resetServiceForTesting( 'LinkRendererFactory' );
- }
-
- public function setupRecorder( $options ) {
- if ( isset( $options['record'] ) ) {
- $this->recorder = new DbTestRecorder( $this );
- $this->recorder->version = isset( $options['setversion'] ) ?
- $options['setversion'] : SpecialVersion::getVersion();
- } elseif ( isset( $options['compare'] ) ) {
- $this->recorder = new DbTestPreviewer( $this );
- } else {
- $this->recorder = new TestRecorder( $this );
- }
- }
-
- /**
- * Remove last character if it is a newline
- * @group utility
- * @param string $s
- * @return string
- */
- public static function chomp( $s ) {
- if ( substr( $s, -1 ) === "\n" ) {
- return substr( $s, 0, -1 );
- } else {
- return $s;
- }
- }
-
- /**
- * Run a series of tests listed in the given text files.
- * Each test consists of a brief description, wikitext input,
- * and the expected HTML output.
- *
- * Prints status updates on stdout and counts up the total
- * number and percentage of passed tests.
- *
- * @param array $filenames Array of strings
- * @return bool True if passed all tests, false if any tests failed.
- */
- public function runTestsFromFiles( $filenames ) {
- $ok = false;
-
- // be sure, ParserTest::addArticle has correct language set,
- // so that system messages gets into the right language cache
- $GLOBALS['wgLanguageCode'] = 'en';
- $GLOBALS['wgContLang'] = Language::factory( 'en' );
-
- $this->recorder->start();
- try {
- $this->setupDatabase();
- $ok = true;
-
- foreach ( $filenames as $filename ) {
- echo "Running parser tests from: $filename\n";
- $tests = new TestFileIterator( $filename, $this );
- $ok = $this->runTests( $tests ) && $ok;
- }
-
- $this->teardownDatabase();
- $this->recorder->report();
- } catch ( DBError $e ) {
- echo $e->getMessage();
- }
- $this->recorder->end();
-
- return $ok;
- }
-
- function runTests( $tests ) {
- $ok = true;
-
- foreach ( $tests as $t ) {
- $result =
- $this->runTest( $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] );
- $ok = $ok && $result;
- $this->recorder->record( $t['test'], $t['subtest'], $result );
- }
-
- if ( $this->showProgress ) {
- print "\n";
- }
-
- return $ok;
- }
-
- /**
- * Get a Parser object
- *
- * @param string $preprocessor
- * @return Parser
- */
- function getParser( $preprocessor = null ) {
- global $wgParserConf;
-
- $class = $wgParserConf['class'];
- $parser = new $class( [ 'preprocessorClass' => $preprocessor ] + $wgParserConf );
-
- foreach ( $this->hooks as $tag => $callback ) {
- $parser->setHook( $tag, $callback );
- }
-
- foreach ( $this->functionHooks as $tag => $bits ) {
- list( $callback, $flags ) = $bits;
- $parser->setFunctionHook( $tag, $callback, $flags );
- }
-
- foreach ( $this->transparentHooks as $tag => $callback ) {
- $parser->setTransparentTagHook( $tag, $callback );
- }
-
- Hooks::run( 'ParserTestParser', [ &$parser ] );
-
- return $parser;
- }
-
- /**
- * Run a given wikitext input through a freshly-constructed wiki parser,
- * and compare the output against the expected results.
- * Prints status and explanatory messages to stdout.
- *
- * @param string $desc Test's description
- * @param string $input Wikitext to try rendering
- * @param string $result Result to output
- * @param array $opts Test's options
- * @param string $config Overrides for global variables, one per line
- * @return bool
- */
- public function runTest( $desc, $input, $result, $opts, $config ) {
- if ( $this->showProgress ) {
- $this->showTesting( $desc );
- }
-
- $opts = $this->parseOptions( $opts );
- $context = $this->setupGlobals( $opts, $config );
-
- $user = $context->getUser();
- $options = ParserOptions::newFromContext( $context );
-
- if ( isset( $opts['djvu'] ) ) {
- if ( !$this->djVuSupport->isEnabled() ) {
- return $this->showSkipped();
- }
- }
-
- if ( isset( $opts['tidy'] ) ) {
- if ( !$this->tidySupport->isEnabled() ) {
- return $this->showSkipped();
- } else {
- $options->setTidy( true );
- }
- }
-
- if ( isset( $opts['title'] ) ) {
- $titleText = $opts['title'];
- } else {
- $titleText = 'Parser test';
- }
-
- ObjectCache::getMainWANInstance()->clearProcessCache();
- $local = isset( $opts['local'] );
- $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null;
- $parser = $this->getParser( $preprocessor );
- $title = Title::newFromText( $titleText );
-
- if ( isset( $opts['pst'] ) ) {
- $out = $parser->preSaveTransform( $input, $title, $user, $options );
- } elseif ( isset( $opts['msg'] ) ) {
- $out = $parser->transformMsg( $input, $options, $title );
- } elseif ( isset( $opts['section'] ) ) {
- $section = $opts['section'];
- $out = $parser->getSection( $input, $section );
- } elseif ( isset( $opts['replace'] ) ) {
- $section = $opts['replace'][0];
- $replace = $opts['replace'][1];
- $out = $parser->replaceSection( $input, $section, $replace );
- } elseif ( isset( $opts['comment'] ) ) {
- $out = Linker::formatComment( $input, $title, $local );
- } elseif ( isset( $opts['preload'] ) ) {
- $out = $parser->getPreloadText( $input, $title, $options );
- } else {
- $output = $parser->parse( $input, $title, $options, true, true, 1337 );
- $output->setTOCEnabled( !isset( $opts['notoc'] ) );
- $out = $output->getText();
- if ( isset( $opts['tidy'] ) ) {
- $out = preg_replace( '/\s+$/', '', $out );
- }
-
- if ( isset( $opts['showtitle'] ) ) {
- if ( $output->getTitleText() ) {
- $title = $output->getTitleText();
- }
-
- $out = "$title\n$out";
- }
-
- if ( isset( $opts['showindicators'] ) ) {
- $indicators = '';
- foreach ( $output->getIndicators() as $id => $content ) {
- $indicators .= "$id=$content\n";
- }
- $out = $indicators . $out;
- }
-
- if ( isset( $opts['ill'] ) ) {
- $out = implode( ' ', $output->getLanguageLinks() );
- } elseif ( isset( $opts['cat'] ) ) {
- $outputPage = $context->getOutput();
- $outputPage->addCategoryLinks( $output->getCategories() );
- $cats = $outputPage->getCategoryLinks();
-
- if ( isset( $cats['normal'] ) ) {
- $out = implode( ' ', $cats['normal'] );
- } else {
- $out = '';
- }
- }
- }
-
- $this->teardownGlobals();
-
- if ( count( $this->normalizationFunctions ) ) {
- $result = ParserTestResultNormalizer::normalize( $result, $this->normalizationFunctions );
- $out = ParserTestResultNormalizer::normalize( $out, $this->normalizationFunctions );
- }
-
- $testResult = new ParserTestResult( $desc );
- $testResult->expected = $result;
- $testResult->actual = $out;
-
- return $this->showTestResult( $testResult );
- }
-
- /**
- * Refactored in 1.22 to use ParserTestResult
- * @param ParserTestResult $testResult
- * @return bool
- */
- function showTestResult( ParserTestResult $testResult ) {
- if ( $testResult->isSuccess() ) {
- $this->showSuccess( $testResult );
- return true;
- } else {
- $this->showFailure( $testResult );
- return false;
- }
- }
-
- /**
- * Use a regex to find out the value of an option
- * @param string $key Name of option val to retrieve
- * @param array $opts Options array to look in
- * @param mixed $default Default value returned if not found
- * @return mixed
- */
- private static function getOptionValue( $key, $opts, $default ) {
- $key = strtolower( $key );
-
- if ( isset( $opts[$key] ) ) {
- return $opts[$key];
- } else {
- return $default;
- }
- }
-
- private function parseOptions( $instring ) {
- $opts = [];
- // foo
- // foo=bar
- // foo="bar baz"
- // foo=[[bar baz]]
- // foo=bar,"baz quux"
- // foo={...json...}
- $defs = '(?(DEFINE)
- (?<qstr> # Quoted string
- "
- (?:[^\\\\"] | \\\\.)*
- "
- )
- (?<json>
- \{ # Open bracket
- (?:
- [^"{}] | # Not a quoted string or object, or
- (?&qstr) | # A quoted string, or
- (?&json) # A json object (recursively)
- )*
- \} # Close bracket
- )
- (?<value>
- (?:
- (?&qstr) # Quoted val
- |
- \[\[
- [^]]* # Link target
- \]\]
- |
- [\w-]+ # Plain word
- |
- (?&json) # JSON object
- )
- )
- )';
- $regex = '/' . $defs . '\b
- (?<k>[\w-]+) # Key
- \b
- (?:\s*
- = # First sub-value
- \s*
- (?<v>
- (?&value)
- (?:\s*
- , # Sub-vals 1..N
- \s*
- (?&value)
- )*
- )
- )?
- /x';
- $valueregex = '/' . $defs . '(?&value)/x';
-
- if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) {
- foreach ( $matches as $bits ) {
- $key = strtolower( $bits['k'] );
- if ( !isset( $bits['v'] ) ) {
- $opts[$key] = true;
- } else {
- preg_match_all( $valueregex, $bits['v'], $vmatches );
- $opts[$key] = array_map( [ $this, 'cleanupOption' ], $vmatches[0] );
- if ( count( $opts[$key] ) == 1 ) {
- $opts[$key] = $opts[$key][0];
- }
- }
- }
- }
- return $opts;
- }
-
- private function cleanupOption( $opt ) {
- if ( substr( $opt, 0, 1 ) == '"' ) {
- return stripcslashes( substr( $opt, 1, -1 ) );
- }
-
- if ( substr( $opt, 0, 2 ) == '[[' ) {
- return substr( $opt, 2, -2 );
- }
-
- if ( substr( $opt, 0, 1 ) == '{' ) {
- return FormatJson::decode( $opt, true );
- }
- return $opt;
- }
-
- /**
- * Set up the global variables for a consistent environment for each test.
- * Ideally this should replace the global configuration entirely.
- * @param string $opts
- * @param string $config
- * @return RequestContext
- */
- public function setupGlobals( $opts = '', $config = '' ) {
- # Find out values for some special options.
- $lang =
- self::getOptionValue( 'language', $opts, 'en' );
- $variant =
- self::getOptionValue( 'variant', $opts, false );
- $maxtoclevel =
- self::getOptionValue( 'wgMaxTocLevel', $opts, 999 );
- $linkHolderBatchSize =
- self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 );
-
- $settings = [
- 'wgServer' => 'http://example.org',
- 'wgServerName' => 'example.org',
- 'wgScript' => '/index.php',
- 'wgScriptPath' => '',
- 'wgArticlePath' => '/wiki/$1',
- 'wgActionPaths' => [],
- 'wgLockManagers' => [ [
- 'name' => 'fsLockManager',
- 'class' => 'FSLockManager',
- 'lockDirectory' => $this->uploadDir . '/lockdir',
- ], [
- 'name' => 'nullLockManager',
- 'class' => 'NullLockManager',
- ] ],
- 'wgLocalFileRepo' => [
- 'class' => 'LocalRepo',
- 'name' => 'local',
- 'url' => 'http://example.com/images',
- 'hashLevels' => 2,
- 'transformVia404' => false,
- 'backend' => new FSFileBackend( [
- 'name' => 'local-backend',
- 'wikiId' => wfWikiID(),
- 'containerPaths' => [
- 'local-public' => $this->uploadDir,
- 'local-thumb' => $this->uploadDir . '/thumb',
- 'local-temp' => $this->uploadDir . '/temp',
- 'local-deleted' => $this->uploadDir . '/delete',
- ]
- ] )
- ],
- 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
- 'wgUploadNavigationUrl' => false,
- 'wgStylePath' => '/skins',
- 'wgSitename' => 'MediaWiki',
- 'wgLanguageCode' => $lang,
- 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'parsertest_' : 'pt_',
- 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ),
- 'wgLang' => null,
- 'wgContLang' => null,
- 'wgNamespacesWithSubpages' => [ 0 => isset( $opts['subpage'] ) ],
- 'wgMaxTocLevel' => $maxtoclevel,
- 'wgCapitalLinks' => true,
- 'wgNoFollowLinks' => true,
- 'wgNoFollowDomainExceptions' => [ 'no-nofollow.org' ],
- 'wgThumbnailScriptPath' => false,
- 'wgUseImageResize' => true,
- 'wgSVGConverter' => 'null',
- 'wgSVGConverters' => [ 'null' => 'echo "1">$output' ],
- 'wgLocaltimezone' => 'UTC',
- 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ),
- 'wgThumbLimits' => [ self::getOptionValue( 'thumbsize', $opts, 180 ) ],
- 'wgDefaultLanguageVariant' => $variant,
- 'wgVariantArticlePath' => false,
- 'wgGroupPermissions' => [ '*' => [
- 'createaccount' => true,
- 'read' => true,
- 'edit' => true,
- 'createpage' => true,
- 'createtalk' => true,
- ] ],
- 'wgNamespaceProtection' => [ NS_MEDIAWIKI => 'editinterface' ],
- 'wgDefaultExternalStore' => [],
- 'wgForeignFileRepos' => [],
- 'wgLinkHolderBatchSize' => $linkHolderBatchSize,
- 'wgExperimentalHtmlIds' => false,
- 'wgExternalLinkTarget' => false,
- 'wgHtml5' => true,
- 'wgAdaptiveMessageCache' => true,
- 'wgDisableLangConversion' => false,
- 'wgDisableTitleConversion' => false,
- // Tidy options.
- 'wgUseTidy' => false,
- 'wgTidyConfig' => isset( $opts['tidy'] ) ? $this->tidySupport->getConfig() : null
- ];
-
- if ( $config ) {
- $configLines = explode( "\n", $config );
-
- foreach ( $configLines as $line ) {
- list( $var, $value ) = explode( '=', $line, 2 );
-
- $settings[$var] = eval( "return $value;" );
- }
- }
-
- $this->savedGlobals = [];
-
- /** @since 1.20 */
- Hooks::run( 'ParserTestGlobals', [ &$settings ] );
-
- foreach ( $settings as $var => $val ) {
- if ( array_key_exists( $var, $GLOBALS ) ) {
- $this->savedGlobals[$var] = $GLOBALS[$var];
- }
-
- $GLOBALS[$var] = $val;
- }
-
- // Must be set before $context as user language defaults to $wgContLang
- $GLOBALS['wgContLang'] = Language::factory( $lang );
- $GLOBALS['wgMemc'] = new EmptyBagOStuff;
-
- RequestContext::resetMain();
- $context = RequestContext::getMain();
- $GLOBALS['wgLang'] = $context->getLanguage();
- $GLOBALS['wgOut'] = $context->getOutput();
- $GLOBALS['wgUser'] = $context->getUser();
-
- // We (re)set $wgThumbLimits to a single-element array above.
- $context->getUser()->setOption( 'thumbsize', 0 );
-
- global $wgHooks;
-
- $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup';
- $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp';
-
- MagicWord::clearCache();
- MWTidy::destroySingleton();
- RepoGroup::destroySingleton();
-
- self::resetTitleServices();
-
- return $context;
- }
-
- /**
- * List of temporary tables to create, without prefix.
- * Some of these probably aren't necessary.
- * @return array
- */
- private function listTables() {
- $tables = [ 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions',
- 'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks',
- 'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks',
- 'site_stats', 'ipblocks', 'image', 'oldimage',
- 'recentchanges', 'watchlist', 'interwiki', 'logging', 'log_search',
- 'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
- 'archive', 'user_groups', 'page_props', 'category'
- ];
-
- if ( in_array( $this->db->getType(), [ 'mysql', 'sqlite', 'oracle' ] ) ) {
- array_push( $tables, 'searchindex' );
- }
-
- // Allow extensions to add to the list of tables to duplicate;
- // may be necessary if they hook into page save or other code
- // which will require them while running tests.
- Hooks::run( 'ParserTestTables', [ &$tables ] );
-
- return $tables;
- }
-
- /**
- * Set up a temporary set of wiki tables to work with for the tests.
- * Currently this will only be done once per run, and any changes to
- * the db will be visible to later tests in the run.
- */
- public function setupDatabase() {
- global $wgDBprefix;
-
- if ( $this->databaseSetupDone ) {
- return;
- }
-
- $this->db = wfGetDB( DB_MASTER );
- $dbType = $this->db->getType();
-
- if ( $wgDBprefix === 'parsertest_' || ( $dbType == 'oracle' && $wgDBprefix === 'pt_' ) ) {
- throw new MWException( 'setupDatabase should be called before setupGlobals' );
- }
-
- $this->databaseSetupDone = true;
-
- # SqlBagOStuff broke when using temporary tables on r40209 (bug 15892).
- # It seems to have been fixed since (r55079?), but regressed at some point before r85701.
- # This works around it for now...
- ObjectCache::$instances[CACHE_DB] = new HashBagOStuff;
-
- # CREATE TEMPORARY TABLE breaks if there is more than one server
- if ( wfGetLB()->getServerCount() != 1 ) {
- $this->useTemporaryTables = false;
- }
-
- $temporary = $this->useTemporaryTables || $dbType == 'postgres';
- $prefix = $dbType != 'oracle' ? 'parsertest_' : 'pt_';
-
- $this->dbClone = new CloneDatabase( $this->db, $this->listTables(), $prefix );
- $this->dbClone->useTemporaryTables( $temporary );
- $this->dbClone->cloneTableStructure();
-
- if ( $dbType == 'oracle' ) {
- $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
- # Insert 0 user to prevent FK violations
-
- # Anonymous user
- $this->db->insert( 'user', [
- 'user_id' => 0,
- 'user_name' => 'Anonymous' ] );
- }
-
- # Update certain things in site_stats
- $this->db->insert( 'site_stats',
- [ 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ] );
-
- # Reinitialise the LocalisationCache to match the database state
- Language::getLocalisationCache()->unloadAll();
-
- # Clear the message cache
- MessageCache::singleton()->clear();
-
- // Remember to update newParserTests.php after changing the below
- // (and it uses a slightly different syntax just for teh lulz)
- $this->setupUploadDir();
- $user = User::createNew( 'WikiSysop' );
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
- # note that the size/width/height/bits/etc of the file
- # are actually set by inspecting the file itself; the arguments
- # to recordUpload2 have no effect. That said, we try to make things
- # match up so it is less confusing to readers of the code & tests.
- $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', [
- 'size' => 7881,
- 'width' => 1941,
- 'height' => 220,
- 'bits' => 8,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/jpeg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '1', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
-
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Thumb.png' ) );
- # again, note that size/width/height below are ignored; see above.
- $image->recordUpload2( '', 'Upload of some lame thumbnail', 'Some lame thumbnail', [
- 'size' => 22589,
- 'width' => 135,
- 'height' => 135,
- 'bits' => 8,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/png',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '2', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20130225203040' ), $user );
-
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.svg' ) );
- $image->recordUpload2( '', 'Upload of some lame SVG', 'Some lame SVG', [
- 'size' => 12345,
- 'width' => 240,
- 'height' => 180,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_DRAWING,
- 'mime' => 'image/svg+xml',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
-
- # This image will be blacklisted in [[MediaWiki:Bad image list]]
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) );
- $image->recordUpload2( '', 'zomgnotcensored', 'Borderline image', [
- 'size' => 12345,
- 'width' => 320,
- 'height' => 240,
- 'bits' => 24,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/jpeg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '3', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
-
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Video.ogv' ) );
- $image->recordUpload2( '', 'A pretty movie', 'Will it play', [
- 'size' => 12345,
- 'width' => 320,
- 'height' => 240,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_VIDEO,
- 'mime' => 'application/ogg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
-
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Audio.oga' ) );
- $image->recordUpload2( '', 'An awesome hitsong', 'Will it play', [
- 'size' => 12345,
- 'width' => 0,
- 'height' => 0,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_AUDIO,
- 'mime' => 'application/ogg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
-
- # A DjVu file
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'LoremIpsum.djvu' ) );
- $image->recordUpload2( '', 'Upload a DjVu', 'A DjVu', [
- 'size' => 3249,
- 'width' => 2480,
- 'height' => 3508,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/vnd.djvu',
- 'metadata' => '<?xml version="1.0" ?>
-<!DOCTYPE DjVuXML PUBLIC "-//W3C//DTD DjVuXML 1.1//EN" "pubtext/DjVuXML-s.dtd">
-<DjVuXML>
-<HEAD></HEAD>
-<BODY><OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-</BODY>
-</DjVuXML>',
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123600' ), $user );
- }
-
- public function teardownDatabase() {
- if ( !$this->databaseSetupDone ) {
- $this->teardownGlobals();
- return;
- }
- $this->teardownUploadDir( $this->uploadDir );
-
- $this->dbClone->destroy();
- $this->databaseSetupDone = false;
-
- if ( $this->useTemporaryTables ) {
- if ( $this->db->getType() == 'sqlite' ) {
- # Under SQLite the searchindex table is virtual and need
- # to be explicitly destroyed. See bug 29912
- # See also MediaWikiTestCase::destroyDB()
- wfDebug( __METHOD__ . " explicitly destroying sqlite virtual table parsertest_searchindex\n" );
- $this->db->query( "DROP TABLE `parsertest_searchindex`" );
- }
- # Don't need to do anything
- $this->teardownGlobals();
- return;
- }
-
- $tables = $this->listTables();
-
- foreach ( $tables as $table ) {
- if ( $this->db->getType() == 'oracle' ) {
- $this->db->query( "DROP TABLE pt_$table DROP CONSTRAINTS" );
- } else {
- $this->db->query( "DROP TABLE `parsertest_$table`" );
- }
- }
-
- if ( $this->db->getType() == 'oracle' ) {
- $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
- }
-
- $this->teardownGlobals();
- }
-
- /**
- * Create a dummy uploads directory which will contain a couple
- * of files in order to pass existence tests.
- *
- * @return string The directory
- */
- private function setupUploadDir() {
- global $IP;
-
- $dir = $this->uploadDir;
- if ( $this->keepUploads && is_dir( $dir ) ) {
- return;
- }
-
- // wfDebug( "Creating upload directory $dir\n" );
- if ( file_exists( $dir ) ) {
- wfDebug( "Already exists!\n" );
- return;
- }
-
- wfMkdirParents( $dir . '/3/3a', null, __METHOD__ );
- copy( "$IP/tests/phpunit/data/parser/headbg.jpg", "$dir/3/3a/Foobar.jpg" );
- wfMkdirParents( $dir . '/e/ea', null, __METHOD__ );
- copy( "$IP/tests/phpunit/data/parser/wiki.png", "$dir/e/ea/Thumb.png" );
- wfMkdirParents( $dir . '/0/09', null, __METHOD__ );
- copy( "$IP/tests/phpunit/data/parser/headbg.jpg", "$dir/0/09/Bad.jpg" );
- wfMkdirParents( $dir . '/f/ff', null, __METHOD__ );
- file_put_contents( "$dir/f/ff/Foobar.svg",
- '<?xml version="1.0" encoding="utf-8"?>' .
- '<svg xmlns="http://www.w3.org/2000/svg"' .
- ' version="1.1" width="240" height="180"/>' );
- wfMkdirParents( $dir . '/5/5f', null, __METHOD__ );
- copy( "$IP/tests/phpunit/data/parser/LoremIpsum.djvu", "$dir/5/5f/LoremIpsum.djvu" );
- wfMkdirParents( $dir . '/0/00', null, __METHOD__ );
- copy( "$IP/tests/phpunit/data/parser/320x240.ogv", "$dir/0/00/Video.ogv" );
- wfMkdirParents( $dir . '/4/41', null, __METHOD__ );
- copy( "$IP/tests/phpunit/data/media/say-test.ogg", "$dir/4/41/Audio.oga" );
-
- return;
- }
-
- /**
- * Restore default values and perform any necessary clean-up
- * after each test runs.
- */
- public function teardownGlobals() {
- RepoGroup::destroySingleton();
- FileBackendGroup::destroySingleton();
- LockManagerGroup::destroySingletons();
- LinkCache::singleton()->clear();
- MWTidy::destroySingleton();
-
- foreach ( $this->savedGlobals as $var => $val ) {
- $GLOBALS[$var] = $val;
- }
- }
-
- /**
- * Remove the dummy uploads directory
- * @param string $dir
- */
- private function teardownUploadDir( $dir ) {
- if ( $this->keepUploads ) {
- return;
- }
-
- // delete the files first, then the dirs.
- self::deleteFiles(
- [
- "$dir/3/3a/Foobar.jpg",
- "$dir/thumb/3/3a/Foobar.jpg/*.jpg",
- "$dir/e/ea/Thumb.png",
- "$dir/0/09/Bad.jpg",
- "$dir/5/5f/LoremIpsum.djvu",
- "$dir/thumb/5/5f/LoremIpsum.djvu/*-LoremIpsum.djvu.jpg",
- "$dir/f/ff/Foobar.svg",
- "$dir/thumb/f/ff/Foobar.svg/*-Foobar.svg.png",
- "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png",
- "$dir/0/00/Video.ogv",
- "$dir/thumb/0/00/Video.ogv/120px--Video.ogv.jpg",
- "$dir/thumb/0/00/Video.ogv/180px--Video.ogv.jpg",
- "$dir/thumb/0/00/Video.ogv/240px--Video.ogv.jpg",
- "$dir/thumb/0/00/Video.ogv/320px--Video.ogv.jpg",
- "$dir/thumb/0/00/Video.ogv/270px--Video.ogv.jpg",
- "$dir/thumb/0/00/Video.ogv/320px-seek=2-Video.ogv.jpg",
- "$dir/thumb/0/00/Video.ogv/320px-seek=3.3666666666667-Video.ogv.jpg",
- "$dir/4/41/Audio.oga",
- ]
- );
-
- self::deleteDirs(
- [
- "$dir/3/3a",
- "$dir/3",
- "$dir/thumb/3/3a/Foobar.jpg",
- "$dir/thumb/3/3a",
- "$dir/thumb/3",
- "$dir/e/ea",
- "$dir/e",
- "$dir/f/ff/",
- "$dir/f/",
- "$dir/thumb/f/ff/Foobar.svg",
- "$dir/thumb/f/ff/",
- "$dir/thumb/f/",
- "$dir/0/00/",
- "$dir/0/09/",
- "$dir/0/",
- "$dir/5/5f",
- "$dir/5",
- "$dir/thumb/0/00/Video.ogv",
- "$dir/thumb/0/00",
- "$dir/thumb/0",
- "$dir/thumb/5/5f/LoremIpsum.djvu",
- "$dir/thumb/5/5f",
- "$dir/thumb/5",
- "$dir/thumb",
- "$dir/4/41",
- "$dir/4",
- "$dir/math/f/a/5",
- "$dir/math/f/a",
- "$dir/math/f",
- "$dir/math",
- "$dir/lockdir",
- "$dir",
- ]
- );
- }
-
- /**
- * Delete the specified files, if they exist.
- * @param array $files Full paths to files to delete.
- */
- private static function deleteFiles( $files ) {
- foreach ( $files as $pattern ) {
- foreach ( glob( $pattern ) as $file ) {
- if ( file_exists( $file ) ) {
- unlink( $file );
- }
- }
- }
- }
-
- /**
- * Delete the specified directories, if they exist. Must be empty.
- * @param array $dirs Full paths to directories to delete.
- */
- private static function deleteDirs( $dirs ) {
- foreach ( $dirs as $dir ) {
- if ( is_dir( $dir ) ) {
- rmdir( $dir );
- }
- }
- }
-
- /**
- * "Running test $desc..."
- * @param string $desc
- */
- protected function showTesting( $desc ) {
- print "Running test $desc... ";
- }
-
- /**
- * Print a happy success message.
- *
- * Refactored in 1.22 to use ParserTestResult
- *
- * @param ParserTestResult $testResult
- * @return bool
- */
- protected function showSuccess( ParserTestResult $testResult ) {
- if ( $this->showProgress ) {
- print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n";
- }
-
- return true;
- }
-
- /**
- * Print a failure message and provide some explanatory output
- * about what went wrong if so configured.
- *
- * Refactored in 1.22 to use ParserTestResult
- *
- * @param ParserTestResult $testResult
- * @return bool
- */
- protected function showFailure( ParserTestResult $testResult ) {
- if ( $this->showFailure ) {
- if ( !$this->showProgress ) {
- # In quiet mode we didn't show the 'Testing' message before the
- # test, in case it succeeded. Show it now:
- $this->showTesting( $testResult->description );
- }
-
- print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n";
-
- if ( $this->showOutput ) {
- print "--- Expected ---\n{$testResult->expected}\n";
- print "--- Actual ---\n{$testResult->actual}\n";
- }
-
- if ( $this->showDiffs ) {
- print $this->quickDiff( $testResult->expected, $testResult->actual );
- if ( !$this->wellFormed( $testResult->actual ) ) {
- print "XML error: $this->mXmlError\n";
- }
- }
- }
-
- return false;
- }
-
- /**
- * Print a skipped message.
- *
- * @return bool
- */
- protected function showSkipped() {
- if ( $this->showProgress ) {
- print $this->term->color( '1;33' ) . 'SKIPPED' . $this->term->reset() . "\n";
- }
-
- return true;
- }
-
- /**
- * Run given strings through a diff and return the (colorized) output.
- * Requires writable /tmp directory and a 'diff' command in the PATH.
- *
- * @param string $input
- * @param string $output
- * @param string $inFileTail Tailing for the input file name
- * @param string $outFileTail Tailing for the output file name
- * @return string
- */
- protected function quickDiff( $input, $output,
- $inFileTail = 'expected', $outFileTail = 'actual'
- ) {
- if ( $this->markWhitespace ) {
- $pairs = [
- "\n" => '¶',
- ' ' => '·',
- "\t" => '→'
- ];
- $input = strtr( $input, $pairs );
- $output = strtr( $output, $pairs );
- }
-
- # Windows, or at least the fc utility, is retarded
- $slash = wfIsWindows() ? '\\' : '/';
- $prefix = wfTempDir() . "{$slash}mwParser-" . mt_rand();
-
- $infile = "$prefix-$inFileTail";
- $this->dumpToFile( $input, $infile );
-
- $outfile = "$prefix-$outFileTail";
- $this->dumpToFile( $output, $outfile );
-
- $shellInfile = wfEscapeShellArg( $infile );
- $shellOutfile = wfEscapeShellArg( $outfile );
-
- global $wgDiff3;
- // we assume that people with diff3 also have usual diff
- if ( $this->useDwdiff ) {
- $shellCommand = 'dwdiff -Pc';
- } else {
- $shellCommand = ( wfIsWindows() && !$wgDiff3 ) ? 'fc' : 'diff -au';
- }
-
- $diff = wfShellExec( "$shellCommand $shellInfile $shellOutfile" );
-
- unlink( $infile );
- unlink( $outfile );
-
- if ( $this->useDwdiff ) {
- return $diff;
- } else {
- return $this->colorDiff( $diff );
- }
- }
-
- /**
- * Write the given string to a file, adding a final newline.
- *
- * @param string $data
- * @param string $filename
- */
- private function dumpToFile( $data, $filename ) {
- $file = fopen( $filename, "wt" );
- fwrite( $file, $data . "\n" );
- fclose( $file );
- }
-
- /**
- * Colorize unified diff output if set for ANSI color output.
- * Subtractions are colored blue, additions red.
- *
- * @param string $text
- * @return string
- */
- protected function colorDiff( $text ) {
- return preg_replace(
- [ '/^(-.*)$/m', '/^(\+.*)$/m' ],
- [ $this->term->color( 34 ) . '$1' . $this->term->reset(),
- $this->term->color( 31 ) . '$1' . $this->term->reset() ],
- $text );
- }
-
- /**
- * Show "Reading tests from ..."
- *
- * @param string $path
- */
- public function showRunFile( $path ) {
- print $this->term->color( 1 ) .
- "Reading tests from \"$path\"..." .
- $this->term->reset() .
- "\n";
- }
-
- /**
- * Insert a temporary test article
- * @param string $name The title, including any prefix
- * @param string $text The article text
- * @param int|string $line The input line number, for reporting errors
- * @param bool|string $ignoreDuplicate Whether to silently ignore duplicate pages
- * @throws Exception
- * @throws MWException
- */
- public static function addArticle( $name, $text, $line = 'unknown', $ignoreDuplicate = '' ) {
- global $wgCapitalLinks;
-
- $oldCapitalLinks = $wgCapitalLinks;
- $wgCapitalLinks = true; // We only need this from SetupGlobals() See r70917#c8637
-
- $text = self::chomp( $text );
- $name = self::chomp( $name );
-
- $title = Title::newFromText( $name );
-
- if ( is_null( $title ) ) {
- throw new MWException( "invalid title '$name' at line $line\n" );
- }
-
- $page = WikiPage::factory( $title );
- $page->loadPageData( 'fromdbmaster' );
-
- if ( $page->exists() ) {
- if ( $ignoreDuplicate == 'ignoreduplicate' ) {
- return;
- } else {
- throw new MWException( "duplicate article '$name' at line $line\n" );
- }
- }
-
- $page->doEditContent( ContentHandler::makeContent( $text, $title ), '', EDIT_NEW );
-
- $wgCapitalLinks = $oldCapitalLinks;
- }
-
- /**
- * Steal a callback function from the primary parser, save it for
- * application to our scary parser. If the hook is not installed,
- * abort processing of this file.
- *
- * @param string $name
- * @return bool True if tag hook is present
- */
- public function requireHook( $name ) {
- global $wgParser;
-
- $wgParser->firstCallInit(); // make sure hooks are loaded.
-
- if ( isset( $wgParser->mTagHooks[$name] ) ) {
- $this->hooks[$name] = $wgParser->mTagHooks[$name];
- } else {
- echo " This test suite requires the '$name' hook extension, skipping.\n";
- return false;
- }
-
- return true;
- }
-
- /**
- * Steal a callback function from the primary parser, save it for
- * application to our scary parser. If the hook is not installed,
- * abort processing of this file.
- *
- * @param string $name
- * @return bool True if function hook is present
- */
- public function requireFunctionHook( $name ) {
- global $wgParser;
-
- $wgParser->firstCallInit(); // make sure hooks are loaded.
-
- if ( isset( $wgParser->mFunctionHooks[$name] ) ) {
- $this->functionHooks[$name] = $wgParser->mFunctionHooks[$name];
- } else {
- echo " This test suite requires the '$name' function hook extension, skipping.\n";
- return false;
- }
-
- return true;
- }
-
- /**
- * Steal a callback function from the primary parser, save it for
- * application to our scary parser. If the hook is not installed,
- * abort processing of this file.
- *
- * @param string $name
- * @return bool True if function hook is present
- */
- public function requireTransparentHook( $name ) {
- global $wgParser;
-
- $wgParser->firstCallInit(); // make sure hooks are loaded.
-
- if ( isset( $wgParser->mTransparentTagHooks[$name] ) ) {
- $this->transparentHooks[$name] = $wgParser->mTransparentTagHooks[$name];
- } else {
- echo " This test suite requires the '$name' transparent hook extension, skipping.\n";
- return false;
- }
-
- return true;
- }
-
- private function wellFormed( $text ) {
- $html =
- Sanitizer::hackDocType() .
- '<html>' .
- $text .
- '</html>';
-
- $parser = xml_parser_create( "UTF-8" );
-
- # case folding violates XML standard, turn it off
- xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
-
- if ( !xml_parse( $parser, $html, true ) ) {
- $err = xml_error_string( xml_get_error_code( $parser ) );
- $position = xml_get_current_byte_index( $parser );
- $fragment = $this->extractFragment( $html, $position );
- $this->mXmlError = "$err at byte $position:\n$fragment";
- xml_parser_free( $parser );
-
- return false;
- }
-
- xml_parser_free( $parser );
-
- return true;
- }
-
- private function extractFragment( $text, $position ) {
- $start = max( 0, $position - 10 );
- $before = $position - $start;
- $fragment = '...' .
- $this->term->color( 34 ) .
- substr( $text, $start, $before ) .
- $this->term->color( 0 ) .
- $this->term->color( 31 ) .
- $this->term->color( 1 ) .
- substr( $text, $position, 1 ) .
- $this->term->color( 0 ) .
- $this->term->color( 34 ) .
- substr( $text, $position + 1, 9 ) .
- $this->term->color( 0 ) .
- '...';
- $display = str_replace( "\n", ' ', $fragment );
- $caret = ' ' .
- str_repeat( ' ', $before ) .
- $this->term->color( 31 ) .
- '^' .
- $this->term->color( 0 );
-
- return "$display\n$caret";
- }
-
- static function getFakeTimestamp( &$parser, &$ts ) {
- $ts = 123; // parsed as '1970-01-01T00:02:03Z'
- return true;
- }
-}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Testing
+ */
+
+/**
+ * This is a TestRecorder responsible for printing information about progress,
+ * success and failure to the console. It is specific to the parserTests.php
+ * frontend.
+ */
+class ParserTestPrinter extends TestRecorder {
+ private $total;
+ private $success;
+ private $skipped;
+ private $term;
+ private $showDiffs;
+ private $showProgress;
+ private $showFailure;
+ private $showOutput;
+ private $useDwdiff;
+ private $markWhitespace;
+ private $xmlError;
+
+ function __construct( $term, $options ) {
+ $this->term = $term;
+ $options += [
+ 'showDiffs' => true,
+ 'showProgress' => true,
+ 'showFailure' => true,
+ 'showOutput' => false,
+ 'useDwdiff' => false,
+ 'markWhitespace' => false,
+ ];
+ $this->showDiffs = $options['showDiffs'];
+ $this->showProgress = $options['showProgress'];
+ $this->showFailure = $options['showFailure'];
+ $this->showOutput = $options['showOutput'];
+ $this->useDwdiff = $options['useDwdiff'];
+ $this->markWhitespace = $options['markWhitespace'];
+ }
+
+ public function start() {
+ $this->total = 0;
+ $this->success = 0;
+ $this->skipped = 0;
+ }
+
+ public function startTest( $test ) {
+ if ( $this->showProgress ) {
+ $this->showTesting( $test['desc'] );
+ }
+ }
+
+ private function showTesting( $desc ) {
+ print "Running test $desc... ";
+ }
+
+ /**
+ * Show "Reading tests from ..."
+ *
+ * @param string $path
+ */
+ public function startSuite( $path ) {
+ print $this->term->color( 1 ) .
+ "Running parser tests from \"$path\"..." .
+ $this->term->reset() .
+ "\n";
+ }
+
+ public function endSuite( $path ) {
+ print "\n";
+ }
+
+ public function record( $test, ParserTestResult $result ) {
+ $this->total++;
+ $this->success += ( $result->isSuccess() ? 1 : 0 );
+
+ if ( $result->isSuccess() ) {
+ $this->showSuccess( $result );
+ } else {
+ $this->showFailure( $result );
+ }
+ }
+
+ /**
+ * Print a happy success message.
+ *
+ * @param ParserTestResult $testResult
+ * @return bool
+ */
+ private function showSuccess( ParserTestResult $testResult ) {
+ if ( $this->showProgress ) {
+ print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n";
+ }
+ }
+
+ /**
+ * Print a failure message and provide some explanatory output
+ * about what went wrong if so configured.
+ *
+ * @param ParserTestResult $testResult
+ * @return bool
+ */
+ private function showFailure( ParserTestResult $testResult ) {
+ if ( $this->showFailure ) {
+ if ( !$this->showProgress ) {
+ # In quiet mode we didn't show the 'Testing' message before the
+ # test, in case it succeeded. Show it now:
+ $this->showTesting( $testResult->getDescription() );
+ }
+
+ print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n";
+
+ if ( $this->showOutput ) {
+ print "--- Expected ---\n{$testResult->expected}\n";
+ print "--- Actual ---\n{$testResult->actual}\n";
+ }
+
+ if ( $this->showDiffs ) {
+ print $this->quickDiff( $testResult->expected, $testResult->actual );
+ if ( !$this->wellFormed( $testResult->actual ) ) {
+ print "XML error: $this->xmlError\n";
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Run given strings through a diff and return the (colorized) output.
+ * Requires writable /tmp directory and a 'diff' command in the PATH.
+ *
+ * @param string $input
+ * @param string $output
+ * @param string $inFileTail Tailing for the input file name
+ * @param string $outFileTail Tailing for the output file name
+ * @return string
+ */
+ private function quickDiff( $input, $output,
+ $inFileTail = 'expected', $outFileTail = 'actual'
+ ) {
+ if ( $this->markWhitespace ) {
+ $pairs = [
+ "\n" => '¶',
+ ' ' => '·',
+ "\t" => '→'
+ ];
+ $input = strtr( $input, $pairs );
+ $output = strtr( $output, $pairs );
+ }
+
+ # Windows, or at least the fc utility, is retarded
+ $slash = wfIsWindows() ? '\\' : '/';
+ $prefix = wfTempDir() . "{$slash}mwParser-" . mt_rand();
+
+ $infile = "$prefix-$inFileTail";
+ $this->dumpToFile( $input, $infile );
+
+ $outfile = "$prefix-$outFileTail";
+ $this->dumpToFile( $output, $outfile );
+
+ $shellInfile = wfEscapeShellArg( $infile );
+ $shellOutfile = wfEscapeShellArg( $outfile );
+
+ global $wgDiff3;
+ // we assume that people with diff3 also have usual diff
+ if ( $this->useDwdiff ) {
+ $shellCommand = 'dwdiff -Pc';
+ } else {
+ $shellCommand = ( wfIsWindows() && !$wgDiff3 ) ? 'fc' : 'diff -au';
+ }
+
+ $diff = wfShellExec( "$shellCommand $shellInfile $shellOutfile" );
+
+ unlink( $infile );
+ unlink( $outfile );
+
+ if ( $this->useDwdiff ) {
+ return $diff;
+ } else {
+ return $this->colorDiff( $diff );
+ }
+ }
+
+ /**
+ * Write the given string to a file, adding a final newline.
+ *
+ * @param string $data
+ * @param string $filename
+ */
+ private function dumpToFile( $data, $filename ) {
+ $file = fopen( $filename, "wt" );
+ fwrite( $file, $data . "\n" );
+ fclose( $file );
+ }
+
+ /**
+ * Colorize unified diff output if set for ANSI color output.
+ * Subtractions are colored blue, additions red.
+ *
+ * @param string $text
+ * @return string
+ */
+ private function colorDiff( $text ) {
+ return preg_replace(
+ [ '/^(-.*)$/m', '/^(\+.*)$/m' ],
+ [ $this->term->color( 34 ) . '$1' . $this->term->reset(),
+ $this->term->color( 31 ) . '$1' . $this->term->reset() ],
+ $text );
+ }
+
+ private function wellFormed( $text ) {
+ $html =
+ Sanitizer::hackDocType() .
+ '<html>' .
+ $text .
+ '</html>';
+
+ $parser = xml_parser_create( "UTF-8" );
+
+ # case folding violates XML standard, turn it off
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false );
+
+ if ( !xml_parse( $parser, $html, true ) ) {
+ $err = xml_error_string( xml_get_error_code( $parser ) );
+ $position = xml_get_current_byte_index( $parser );
+ $fragment = $this->extractFragment( $html, $position );
+ $this->xmlError = "$err at byte $position:\n$fragment";
+ xml_parser_free( $parser );
+
+ return false;
+ }
+
+ xml_parser_free( $parser );
+
+ return true;
+ }
+
+ private function extractFragment( $text, $position ) {
+ $start = max( 0, $position - 10 );
+ $before = $position - $start;
+ $fragment = '...' .
+ $this->term->color( 34 ) .
+ substr( $text, $start, $before ) .
+ $this->term->color( 0 ) .
+ $this->term->color( 31 ) .
+ $this->term->color( 1 ) .
+ substr( $text, $position, 1 ) .
+ $this->term->color( 0 ) .
+ $this->term->color( 34 ) .
+ substr( $text, $position + 1, 9 ) .
+ $this->term->color( 0 ) .
+ '...';
+ $display = str_replace( "\n", ' ', $fragment );
+ $caret = ' ' .
+ str_repeat( ' ', $before ) .
+ $this->term->color( 31 ) .
+ '^' .
+ $this->term->color( 0 );
+
+ return "$display\n$caret";
+ }
+
+ /**
+ * Show a warning to the user
+ */
+ public function warning( $message ) {
+ echo "$message\n";
+ }
+
+ /**
+ * Mark a test skipped
+ */
+ public function skipped( $test, $subtest ) {
+ if ( $this->showProgress ) {
+ print $this->term->color( '1;33' ) . 'SKIPPED' . $this->term->reset() . "\n";
+ }
+ $this->skipped++;
+ }
+
+ public function report() {
+ if ( $this->total > 0 ) {
+ $this->reportPercentage( $this->success, $this->total );
+ } else {
+ print $this->term->color( 31 ) . "No tests found." . $this->term->reset() . "\n";
+ }
+ }
+
+ private function reportPercentage( $success, $total ) {
+ $ratio = wfPercent( 100 * $success / $total );
+ print $this->term->color( 1 ) . "Passed $success of $total tests ($ratio)";
+ if ( $this->skipped ) {
+ print ", skipped {$this->skipped}";
+ }
+ print "... ";
+
+ if ( $success == $total ) {
+ print $this->term->color( 32 ) . "ALL TESTS PASSED!";
+ } else {
+ $failed = $total - $success;
+ print $this->term->color( 31 ) . "$failed tests failed!";
+ }
+
+ print $this->term->reset() . "\n";
+
+ return ( $success == $total );
+ }
+}
+
* @since 1.22
*/
class ParserTestResult {
- /**
- * Description of the parser test.
- *
- * This is usually the text used to describe a parser test in the .txt
- * files. It is initialized on a construction and you most probably
- * never want to change it.
- */
- public $description;
+ /** The test info array */
+ public $test;
/** Text that was expected */
public $expected;
/** Actual text rendered */
public $actual;
/**
- * @param string $description A short text describing the parser test
- * usually the text in the parser test .txt file. The description
- * is later available using the property $description.
+ * @param array $test The test info array from TestIterator
+ * @param string $expected The normalized expected output
+ * @param string $actual The actual output
*/
- public function __construct( $description ) {
- $this->description = $description;
+ public function __construct( $test, $expected, $actual ) {
+ $this->test = $test;
+ $this->expected = $expected;
+ $this->actual = $actual;
}
/**
public function isSuccess() {
return $this->expected === $this->actual;
}
+
+ public function getDescription() {
+ return $this->test['desc'];
+ }
}
--- /dev/null
+<?php
+/**
+ * Generic backend for the MediaWiki parser test suite, used by both the
+ * standalone parserTests.php and the PHPUnit "parsertests" suite.
+ *
+ * Copyright © 2004, 2010 Brion Vibber <brion@pobox.com>
+ * https://www.mediawiki.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @todo Make this more independent of the configuration (and if possible the database)
+ * @file
+ * @ingroup Testing
+ */
+use MediaWiki\MediaWikiServices;
+
+/**
+ * @ingroup Testing
+ */
+class ParserTestRunner {
+ /**
+ * @var bool $useTemporaryTables Use temporary tables for the temporary database
+ */
+ private $useTemporaryTables = true;
+
+ /**
+ * @var array $setupDone The status of each setup function
+ */
+ private $setupDone = [
+ 'staticSetup' => false,
+ 'perTestSetup' => false,
+ 'setupDatabase' => false,
+ 'setDatabase' => false,
+ 'setupUploads' => false,
+ ];
+
+ /**
+ * Our connection to the database
+ * @var DatabaseBase
+ */
+ private $db;
+
+ /**
+ * Database clone helper
+ * @var CloneDatabase
+ */
+ private $dbClone;
+
+ /**
+ * @var DjVuSupport
+ */
+ private $djVuSupport;
+
+ /**
+ * @var TidySupport
+ */
+ private $tidySupport;
+
+ /**
+ * @var TidyDriverBase
+ */
+ private $tidyDriver = null;
+
+ /**
+ * @var TestRecorder
+ */
+ private $recorder;
+
+ /**
+ * The upload directory, or null to not set up an upload directory
+ *
+ * @var string|null
+ */
+ private $uploadDir = null;
+
+ /**
+ * The name of the file backend to use, or null to use MockFileBackend.
+ * @var string|null
+ */
+ private $fileBackendName;
+
+ /**
+ * A complete regex for filtering tests.
+ * @var string
+ */
+ private $regex;
+
+ /**
+ * A list of normalization functions to apply to the expected and actual
+ * output.
+ * @var array
+ */
+ private $normalizationFunctions = [];
+
+ /**
+ * @param TestRecorder $recorder
+ * @param array $options
+ */
+ public function __construct( TestRecorder $recorder, $options = [] ) {
+ $this->recorder = $recorder;
+
+ if ( isset( $options['norm'] ) ) {
+ foreach ( $options['norm'] as $func ) {
+ if ( in_array( $func, [ 'removeTbody', 'trimWhitespace' ] ) ) {
+ $this->normalizationFunctions[] = $func;
+ } else {
+ $this->recorder->warning(
+ "Warning: unknown normalization option \"$func\"\n" );
+ }
+ }
+ }
+
+ if ( isset( $options['regex'] ) && $options['regex'] !== false ) {
+ $this->regex = $options['regex'];
+ } else {
+ # Matches anything
+ $this->regex = '//';
+ }
+
+ $this->keepUploads = !empty( $options['keep-uploads'] );
+
+ $this->fileBackendName = isset( $options['file-backend'] ) ?
+ $options['file-backend'] : false;
+
+ $this->runDisabled = !empty( $options['run-disabled'] );
+ $this->runParsoid = !empty( $options['run-parsoid'] );
+
+ $this->djVuSupport = new DjVuSupport();
+ $this->tidySupport = new TidySupport( !empty( $options['use-tidy-config'] ) );
+ if ( !$this->tidySupport->isEnabled() ) {
+ $this->recorder->warning(
+ "Warning: tidy is not installed, skipping some tests\n" );
+ }
+
+ if ( isset( $options['upload-dir'] ) ) {
+ $this->uploadDir = $options['upload-dir'];
+ }
+ }
+
+ public function getRecorder() {
+ return $this->recorder;
+ }
+
+ /**
+ * Do any setup which can be done once for all tests, independent of test
+ * options, except for database setup.
+ *
+ * Public setup functions in this class return a ScopedCallback object. When
+ * this object is destroyed by going out of scope, teardown of the
+ * corresponding test setup is performed.
+ *
+ * Teardown objects may be chained by passing a ScopedCallback from a
+ * previous setup stage as the $nextTeardown parameter. This enforces the
+ * convention that teardown actions are taken in reverse order to the
+ * corresponding setup actions. When $nextTeardown is specified, a
+ * ScopedCallback will be returned which first tears down the current
+ * setup stage, and then tears down the previous setup stage which was
+ * specified by $nextTeardown.
+ *
+ * @param ScopedCallback|null $nextTeardown
+ * @return ScopedCallback
+ */
+ public function staticSetup( $nextTeardown = null ) {
+ // A note on coding style:
+
+ // The general idea here is to keep setup code together with
+ // corresponding teardown code, in a fine-grained manner. We have two
+ // arrays: $setup and $teardown. The code snippets in the $setup array
+ // are executed at the end of the method, before it returns, and the
+ // code snippets in the $teardown array are executed in reverse order
+ // when the ScopedCallback object is consumed.
+
+ // Because it is a common operation to save, set and restore global
+ // variables, we have an additional convention: when the array key of
+ // $setup is a string, the string is taken to be the name of the global
+ // variable, and the element value is taken to be the desired new value.
+
+ // It's acceptable to just do the setup immediately, instead of adding
+ // a closure to $setup, except when the setup action depends on global
+ // variable initialisation being done first. In this case, you have to
+ // append a closure to $setup after the global variable is appended.
+
+ // When you add to setup functions in this class, please keep associated
+ // setup and teardown actions together in the source code, and please
+ // add comments explaining why the setup action is necessary.
+
+ $setup = [];
+ $teardown = [];
+
+ $teardown[] = $this->markSetupDone( 'staticSetup' );
+
+ // Some settings which influence HTML output
+ $setup['wgSitename'] = 'MediaWiki';
+ $setup['wgServer'] = 'http://example.org';
+ $setup['wgServerName'] = 'example.org';
+ $setup['wgScriptPath'] = '';
+ $setup['wgScript'] = '/index.php';
+ $setup['wgResourceBasePath'] = '';
+ $setup['wgStylePath'] = '/skins';
+ $setup['wgExtensionAssetsPath'] = '/extensions';
+ $setup['wgArticlePath'] = '/wiki/$1';
+ $setup['wgActionPaths'] = [];
+ $setup['wgVariantArticlePath'] = false;
+ $setup['wgUploadNavigationUrl'] = false;
+ $setup['wgCapitalLinks'] = true;
+ $setup['wgNoFollowLinks'] = true;
+ $setup['wgNoFollowDomainExceptions'] = [ 'no-nofollow.org' ];
+ $setup['wgExternalLinkTarget'] = false;
+ $setup['wgExperimentalHtmlIds'] = false;
+ $setup['wgLocaltimezone'] = 'UTC';
+ $setup['wgHtml5'] = true;
+ $setup['wgDisableLangConversion'] = false;
+ $setup['wgDisableTitleConversion'] = false;
+
+ // "extra language links"
+ // see https://gerrit.wikimedia.org/r/111390
+ $setup['wgExtraInterlanguageLinkPrefixes'] = [ 'mul' ];
+
+ // All FileRepo changes should be done here by injecting services,
+ // there should be no need to change global variables.
+ RepoGroup::setSingleton( $this->createRepoGroup() );
+ $teardown[] = function () {
+ RepoGroup::destroySingleton();
+ };
+
+ // Set up null lock managers
+ $setup['wgLockManagers'] = [ [
+ 'name' => 'fsLockManager',
+ 'class' => 'NullLockManager',
+ ], [
+ 'name' => 'nullLockManager',
+ 'class' => 'NullLockManager',
+ ] ];
+ $reset = function() {
+ LockManagerGroup::destroySingletons();
+ };
+ $setup[] = $reset;
+ $teardown[] = $reset;
+
+ // This allows article insertion into the prefixed DB
+ $setup['wgDefaultExternalStore'] = false;
+
+ // This might slightly reduce memory usage
+ $setup['wgAdaptiveMessageCache'] = true;
+
+ // This is essential and overrides disabling of database messages in TestSetup
+ $setup['wgUseDatabaseMessages'] = true;
+ $reset = function () {
+ MessageCache::destroyInstance();
+ };
+ $setup[] = $reset;
+ $teardown[] = $reset;
+
+ // It's not necessary to actually convert any files
+ $setup['wgSVGConverter'] = 'null';
+ $setup['wgSVGConverters'] = [ 'null' => 'echo "1">$output' ];
+
+ // Fake constant timestamp
+ Hooks::register( 'ParserGetVariableValueTs', 'ParserTestRunner::getFakeTimestamp' );
+ $teardown[] = function () {
+ Hooks::clear( 'ParserGetVariableValueTs' );
+ };
+
+ $this->appendNamespaceSetup( $setup, $teardown );
+
+ // Set up interwikis and append teardown function
+ $teardown[] = $this->setupInterwikis();
+
+ // This affects title normalization in links. It invalidates
+ // MediaWikiTitleCodec objects.
+ $setup['wgLocalInterwikis'] = [ 'local', 'mi' ];
+ $reset = function () {
+ $this->resetTitleServices();
+ };
+ $setup[] = $reset;
+ $teardown[] = $reset;
+
+ // Set up a mock MediaHandlerFactory
+ MediaWikiServices::getInstance()->disableService( 'MediaHandlerFactory' );
+ MediaWikiServices::getInstance()->redefineService(
+ 'MediaHandlerFactory',
+ function() {
+ return new MockMediaHandlerFactory();
+ }
+ );
+ $teardown[] = function () {
+ MediaWikiServices::getInstance()->resetServiceForTesting( 'MediaHandlerFactory' );
+ };
+
+ // SqlBagOStuff broke when using temporary tables on r40209 (bug 15892).
+ // It seems to have been fixed since (r55079?), but regressed at some point before r85701.
+ // This works around it for now...
+ global $wgObjectCaches;
+ $setup['wgObjectCaches'] = [ CACHE_DB => $wgObjectCaches['hash'] ] + $wgObjectCaches;
+ if ( isset( ObjectCache::$instances[CACHE_DB] ) ) {
+ $savedCache = ObjectCache::$instances[CACHE_DB];
+ ObjectCache::$instances[CACHE_DB] = new HashBagOStuff;
+ $teardown[] = function () use ( $savedCache ) {
+ ObjectCache::$instances[CACHE_DB] = $savedCache;
+ };
+ }
+
+ $teardown[] = $this->executeSetupSnippets( $setup );
+
+ // Schedule teardown snippets in reverse order
+ return $this->createTeardownObject( $teardown, $nextTeardown );
+ }
+
+ private function appendNamespaceSetup( &$setup, &$teardown ) {
+ // Add a namespace shadowing a interwiki link, to test
+ // proper precedence when resolving links. (bug 51680)
+ $setup['wgExtraNamespaces'] = [
+ 100 => 'MemoryAlpha',
+ 101 => 'MemoryAlpha_talk'
+ ];
+ // Changing wgExtraNamespaces invalidates caches in MWNamespace and
+ // any live Language object, both on setup and teardown
+ $reset = function () {
+ MWNamespace::getCanonicalNamespaces( true );
+ $GLOBALS['wgContLang']->resetNamespaces();
+ };
+ $setup[] = $reset;
+ $teardown[] = $reset;
+ }
+
+ /**
+ * Create a RepoGroup object appropriate for the current configuration
+ * @return RepoGroup
+ */
+ protected function createRepoGroup() {
+ if ( $this->uploadDir ) {
+ if ( $this->fileBackendName ) {
+ throw new MWException( 'You cannot specify both use-filebackend and upload-dir' );
+ }
+ $backend = new FSFileBackend( [
+ 'name' => 'local-backend',
+ 'wikiId' => wfWikiID(),
+ 'basePath' => $this->uploadDir
+ ] );
+ } elseif ( $this->fileBackendName ) {
+ global $wgFileBackends;
+ $name = $this->fileBackendName;
+ $useConfig = false;
+ foreach ( $wgFileBackends as $conf ) {
+ if ( $conf['name'] === $name ) {
+ $useConfig = $conf;
+ }
+ }
+ if ( $useConfig === false ) {
+ throw new MWException( "Unable to find file backend \"$name\"" );
+ }
+ $useConfig['name'] = 'local-backend'; // swap name
+ unset( $useConfig['lockManager'] );
+ unset( $useConfig['fileJournal'] );
+ $class = $useConfig['class'];
+ $backend = new $class( $useConfig );
+ } else {
+ # Replace with a mock. We do not care about generating real
+ # files on the filesystem, just need to expose the file
+ # informations.
+ $backend = new MockFileBackend( [
+ 'name' => 'local-backend',
+ 'wikiId' => wfWikiID()
+ ] );
+ }
+
+ return new RepoGroup(
+ [
+ 'class' => 'LocalRepo',
+ 'name' => 'local',
+ 'url' => 'http://example.com/images',
+ 'hashLevels' => 2,
+ 'transformVia404' => false,
+ 'backend' => $backend
+ ],
+ []
+ );
+ }
+
+ /**
+ * Execute an array in which elements with integer keys are taken to be
+ * callable objects, and other elements are taken to be global variable
+ * set operations, with the key giving the variable name and the value
+ * giving the new global variable value. A closure is returned which, when
+ * executed, sets the global variables back to the values they had before
+ * this function was called.
+ *
+ * @see staticSetup
+ *
+ * @param array $setup
+ * @return closure
+ */
+ protected function executeSetupSnippets( $setup ) {
+ $saved = [];
+ foreach ( $setup as $name => $value ) {
+ if ( is_int( $name ) ) {
+ $value();
+ } else {
+ $saved[$name] = isset( $GLOBALS[$name] ) ? $GLOBALS[$name] : null;
+ $GLOBALS[$name] = $value;
+ }
+ }
+ return function () use ( $saved ) {
+ $this->executeSetupSnippets( $saved );
+ };
+ }
+
+ /**
+ * Take a setup array in the same format as the one given to
+ * executeSetupSnippets(), and return a ScopedCallback which, when consumed,
+ * executes the snippets in the setup array in reverse order. This is used
+ * to create "teardown objects" for the public API.
+ *
+ * @see staticSetup
+ *
+ * @param array $teardown The snippet array
+ * @param ScopedCallback|null A ScopedCallback to consume
+ * @return ScopedCallback
+ */
+ protected function createTeardownObject( $teardown, $nextTeardown ) {
+ return new ScopedCallback( function() use ( $teardown, $nextTeardown ) {
+ // Schedule teardown snippets in reverse order
+ $teardown = array_reverse( $teardown );
+
+ $this->executeSetupSnippets( $teardown );
+ if ( $nextTeardown ) {
+ ScopedCallback::consume( $nextTeardown );
+ }
+ } );
+ }
+
+ /**
+ * Set a setupDone flag to indicate that setup has been done, and return
+ * the teardown closure. If the flag was already set, throw an exception.
+ *
+ * @param string $funcName The setup function name
+ * @return closure
+ */
+ protected function markSetupDone( $funcName ) {
+ if ( $this->setupDone[$funcName] ) {
+ throw new MWException( "$funcName is already done" );
+ }
+ $this->setupDone[$funcName] = true;
+ return function () use ( $funcName ) {
+ wfDebug( "markSetupDone unmarked $funcName" );
+ $this->setupDone[$funcName] = false;
+ };
+ }
+
+ /**
+ * Ensure a given setup stage has been done, throw an exception if it has
+ * not.
+ */
+ protected function checkSetupDone( $funcName, $funcName2 = null ) {
+ if ( !$this->setupDone[$funcName]
+ && ( $funcName === null || !$this->setupDone[$funcName2] )
+ ) {
+ throw new MWException( "$funcName must be called before calling " .
+ wfGetCaller() );
+ }
+ }
+
+ /**
+ * Determine whether a particular setup function has been run
+ *
+ * @param string $funcName
+ * @return boolean
+ */
+ public function isSetupDone( $funcName ) {
+ return isset( $this->setupDone[$funcName] ) ? $this->setupDone[$funcName] : false;
+ }
+
+ /**
+ * Insert hardcoded interwiki in the lookup table.
+ *
+ * This function insert a set of well known interwikis that are used in
+ * the parser tests. They can be considered has fixtures are injected in
+ * the interwiki cache by using the 'InterwikiLoadPrefix' hook.
+ * Since we are not interested in looking up interwikis in the database,
+ * the hook completely replace the existing mechanism (hook returns false).
+ *
+ * @return closure for teardown
+ */
+ private function setupInterwikis() {
+ # Hack: insert a few Wikipedia in-project interwiki prefixes,
+ # for testing inter-language links
+ Hooks::register( 'InterwikiLoadPrefix', function ( $prefix, &$iwData ) {
+ static $testInterwikis = [
+ 'local' => [
+ 'iw_url' => 'http://doesnt.matter.org/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 0 ],
+ 'wikipedia' => [
+ 'iw_url' => 'http://en.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 0 ],
+ 'meatball' => [
+ 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 0 ],
+ 'memoryalpha' => [
+ 'iw_url' => 'http://www.memory-alpha.org/en/index.php/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 0 ],
+ 'zh' => [
+ 'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ],
+ 'es' => [
+ 'iw_url' => 'http://es.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ],
+ 'fr' => [
+ 'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ],
+ 'ru' => [
+ 'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ],
+ 'mi' => [
+ 'iw_url' => 'http://mi.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ],
+ 'mul' => [
+ 'iw_url' => 'http://wikisource.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ],
+ ];
+ if ( array_key_exists( $prefix, $testInterwikis ) ) {
+ $iwData = $testInterwikis[$prefix];
+ }
+
+ // We only want to rely on the above fixtures
+ return false;
+ } );// hooks::register
+
+ return function () {
+ // Tear down
+ Hooks::clear( 'InterwikiLoadPrefix' );
+ };
+ }
+
+ /**
+ * Reset the Title-related services that need resetting
+ * for each test
+ */
+ private function resetTitleServices() {
+ $services = MediaWikiServices::getInstance();
+ $services->resetServiceForTesting( 'TitleFormatter' );
+ $services->resetServiceForTesting( 'TitleParser' );
+ $services->resetServiceForTesting( '_MediaWikiTitleCodec' );
+ $services->resetServiceForTesting( 'LinkRenderer' );
+ $services->resetServiceForTesting( 'LinkRendererFactory' );
+ }
+
+ /**
+ * Remove last character if it is a newline
+ * @group utility
+ * @param string $s
+ * @return string
+ */
+ public static function chomp( $s ) {
+ if ( substr( $s, -1 ) === "\n" ) {
+ return substr( $s, 0, -1 );
+ } else {
+ return $s;
+ }
+ }
+
+ /**
+ * Run a series of tests listed in the given text files.
+ * Each test consists of a brief description, wikitext input,
+ * and the expected HTML output.
+ *
+ * Prints status updates on stdout and counts up the total
+ * number and percentage of passed tests.
+ *
+ * Handles all setup and teardown.
+ *
+ * @param array $filenames Array of strings
+ * @return bool True if passed all tests, false if any tests failed.
+ */
+ public function runTestsFromFiles( $filenames ) {
+ $ok = false;
+
+ $teardownGuard = $this->staticSetup();
+ $teardownGuard = $this->setupDatabase( $teardownGuard );
+ $teardownGuard = $this->setupUploads( $teardownGuard );
+
+ $this->recorder->start();
+ try {
+ $ok = true;
+
+ foreach ( $filenames as $filename ) {
+ $testFileInfo = TestFileReader::read( $filename, [
+ 'runDisabled' => $this->runDisabled,
+ 'runParsoid' => $this->runParsoid,
+ 'regex' => $this->regex ] );
+
+ // Don't start the suite if there are no enabled tests in the file
+ if ( !$testFileInfo['tests'] ) {
+ continue;
+ }
+
+ $this->recorder->startSuite( $filename );
+ $ok = $this->runTests( $testFileInfo ) && $ok;
+ $this->recorder->endSuite( $filename );
+ }
+
+ $this->recorder->report();
+ } catch ( DBError $e ) {
+ $this->recorder->warning( $e->getMessage() );
+ }
+ $this->recorder->end();
+
+ ScopedCallback::consume( $teardownGuard );
+
+ return $ok;
+ }
+
+ /**
+ * Determine whether the current parser has the hooks registered in it
+ * that are required by a file read by TestFileReader.
+ */
+ public function meetsRequirements( $requirements ) {
+ foreach ( $requirements as $requirement ) {
+ switch ( $requirement['type'] ) {
+ case 'hook':
+ $ok = $this->requireHook( $requirement['name'] );
+ break;
+ case 'functionHook':
+ $ok = $this->requireFunctionHook( $requirement['name'] );
+ break;
+ case 'transparentHook':
+ $ok = $this->requireTransparentHook( $requirement['name'] );
+ break;
+ }
+ if ( !$ok ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Run the tests from a single file. staticSetup() and setupDatabase()
+ * must have been called already.
+ *
+ * @param array $testFileInfo Parsed file info returned by TestFileReader
+ * @return bool True if passed all tests, false if any tests failed.
+ */
+ public function runTests( $testFileInfo ) {
+ $ok = true;
+
+ $this->checkSetupDone( 'staticSetup' );
+
+ // Don't add articles from the file if there are no enabled tests from the file
+ if ( !$testFileInfo['tests'] ) {
+ return true;
+ }
+
+ // If any requirements are not met, mark all tests from the file as skipped
+ if ( !$this->meetsRequirements( $testFileInfo['requirements'] ) ) {
+ foreach ( $testFileInfo['tests'] as $test ) {
+ $this->recorder->startTest( $test );
+ $this->recorder->skipped( $test, 'required extension not enabled' );
+ }
+ return true;
+ }
+
+ // Add articles
+ $this->addArticles( $testFileInfo['articles'] );
+
+ // Run tests
+ foreach ( $testFileInfo['tests'] as $test ) {
+ $this->recorder->startTest( $test );
+ $result =
+ $this->runTest( $test );
+ if ( $result !== false ) {
+ $ok = $ok && $result->isSuccess();
+ $this->recorder->record( $test, $result );
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Get a Parser object
+ *
+ * @param string $preprocessor
+ * @return Parser
+ */
+ function getParser( $preprocessor = null ) {
+ global $wgParserConf;
+
+ $class = $wgParserConf['class'];
+ $parser = new $class( [ 'preprocessorClass' => $preprocessor ] + $wgParserConf );
+ ParserTestParserHook::setup( $parser );
+
+ return $parser;
+ }
+
+ /**
+ * Run a given wikitext input through a freshly-constructed wiki parser,
+ * and compare the output against the expected results.
+ * Prints status and explanatory messages to stdout.
+ *
+ * staticSetup() and setupWikiData() must be called before this function
+ * is entered.
+ *
+ * @param array $test The test parameters:
+ * - test: The test name
+ * - desc: The subtest description
+ * - input: Wikitext to try rendering
+ * - options: Array of test options
+ * - config: Overrides for global variables, one per line
+ *
+ * @return ParserTestResult or false if skipped
+ */
+ public function runTest( $test ) {
+ wfDebug( __METHOD__.": running {$test['desc']}" );
+ $opts = $this->parseOptions( $test['options'] );
+ $teardownGuard = $this->perTestSetup( $test );
+
+ $context = RequestContext::getMain();
+ $user = $context->getUser();
+ $options = ParserOptions::newFromContext( $context );
+
+ if ( isset( $opts['djvu'] ) ) {
+ if ( !$this->djVuSupport->isEnabled() ) {
+ $this->recorder->skipped( $test,
+ 'djvu binaries do not exist or are not executable' );
+ return false;
+ }
+ }
+
+ if ( isset( $opts['tidy'] ) ) {
+ if ( !$this->tidySupport->isEnabled() ) {
+ $this->recorder->skipped( $test, 'tidy extension is not installed' );
+ return false;
+ } else {
+ $options->setTidy( true );
+ }
+ }
+
+ if ( isset( $opts['title'] ) ) {
+ $titleText = $opts['title'];
+ } else {
+ $titleText = 'Parser test';
+ }
+
+ $local = isset( $opts['local'] );
+ $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null;
+ $parser = $this->getParser( $preprocessor );
+ $title = Title::newFromText( $titleText );
+
+ if ( isset( $opts['pst'] ) ) {
+ $out = $parser->preSaveTransform( $test['input'], $title, $user, $options );
+ } elseif ( isset( $opts['msg'] ) ) {
+ $out = $parser->transformMsg( $test['input'], $options, $title );
+ } elseif ( isset( $opts['section'] ) ) {
+ $section = $opts['section'];
+ $out = $parser->getSection( $test['input'], $section );
+ } elseif ( isset( $opts['replace'] ) ) {
+ $section = $opts['replace'][0];
+ $replace = $opts['replace'][1];
+ $out = $parser->replaceSection( $test['input'], $section, $replace );
+ } elseif ( isset( $opts['comment'] ) ) {
+ $out = Linker::formatComment( $test['input'], $title, $local );
+ } elseif ( isset( $opts['preload'] ) ) {
+ $out = $parser->getPreloadText( $test['input'], $title, $options );
+ } else {
+ $output = $parser->parse( $test['input'], $title, $options, true, true, 1337 );
+ $output->setTOCEnabled( !isset( $opts['notoc'] ) );
+ $out = $output->getText();
+ if ( isset( $opts['tidy'] ) ) {
+ $out = preg_replace( '/\s+$/', '', $out );
+ }
+
+ if ( isset( $opts['showtitle'] ) ) {
+ if ( $output->getTitleText() ) {
+ $title = $output->getTitleText();
+ }
+
+ $out = "$title\n$out";
+ }
+
+ if ( isset( $opts['showindicators'] ) ) {
+ $indicators = '';
+ foreach ( $output->getIndicators() as $id => $content ) {
+ $indicators .= "$id=$content\n";
+ }
+ $out = $indicators . $out;
+ }
+
+ if ( isset( $opts['ill'] ) ) {
+ $out = implode( ' ', $output->getLanguageLinks() );
+ } elseif ( isset( $opts['cat'] ) ) {
+ $out = '';
+ foreach ( $output->getCategories() as $name => $sortkey ) {
+ if ( $out !== '' ) {
+ $out .= "\n";
+ }
+ $out .= "cat=$name sort=$sortkey";
+ }
+ }
+ }
+
+ ScopedCallback::consume( $teardownGuard );
+
+ $expected = $test['result'];
+ if ( count( $this->normalizationFunctions ) ) {
+ $expected = ParserTestResultNormalizer::normalize(
+ $test['expected'], $this->normalizationFunctions );
+ $out = ParserTestResultNormalizer::normalize( $out, $this->normalizationFunctions );
+ }
+
+ $testResult = new ParserTestResult( $test, $expected, $out );
+ return $testResult;
+ }
+
+ /**
+ * Use a regex to find out the value of an option
+ * @param string $key Name of option val to retrieve
+ * @param array $opts Options array to look in
+ * @param mixed $default Default value returned if not found
+ * @return mixed
+ */
+ private static function getOptionValue( $key, $opts, $default ) {
+ $key = strtolower( $key );
+
+ if ( isset( $opts[$key] ) ) {
+ return $opts[$key];
+ } else {
+ return $default;
+ }
+ }
+
+ /**
+ * Given the options string, return an associative array of options.
+ * @todo Move this to TestFileReader
+ *
+ * @param string $instring
+ * @return array
+ */
+ private function parseOptions( $instring ) {
+ $opts = [];
+ // foo
+ // foo=bar
+ // foo="bar baz"
+ // foo=[[bar baz]]
+ // foo=bar,"baz quux"
+ // foo={...json...}
+ $defs = '(?(DEFINE)
+ (?<qstr> # Quoted string
+ "
+ (?:[^\\\\"] | \\\\.)*
+ "
+ )
+ (?<json>
+ \{ # Open bracket
+ (?:
+ [^"{}] | # Not a quoted string or object, or
+ (?&qstr) | # A quoted string, or
+ (?&json) # A json object (recursively)
+ )*
+ \} # Close bracket
+ )
+ (?<value>
+ (?:
+ (?&qstr) # Quoted val
+ |
+ \[\[
+ [^]]* # Link target
+ \]\]
+ |
+ [\w-]+ # Plain word
+ |
+ (?&json) # JSON object
+ )
+ )
+ )';
+ $regex = '/' . $defs . '\b
+ (?<k>[\w-]+) # Key
+ \b
+ (?:\s*
+ = # First sub-value
+ \s*
+ (?<v>
+ (?&value)
+ (?:\s*
+ , # Sub-vals 1..N
+ \s*
+ (?&value)
+ )*
+ )
+ )?
+ /x';
+ $valueregex = '/' . $defs . '(?&value)/x';
+
+ if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) {
+ foreach ( $matches as $bits ) {
+ $key = strtolower( $bits['k'] );
+ if ( !isset( $bits['v'] ) ) {
+ $opts[$key] = true;
+ } else {
+ preg_match_all( $valueregex, $bits['v'], $vmatches );
+ $opts[$key] = array_map( [ $this, 'cleanupOption' ], $vmatches[0] );
+ if ( count( $opts[$key] ) == 1 ) {
+ $opts[$key] = $opts[$key][0];
+ }
+ }
+ }
+ }
+ return $opts;
+ }
+
+ private function cleanupOption( $opt ) {
+ if ( substr( $opt, 0, 1 ) == '"' ) {
+ return stripcslashes( substr( $opt, 1, -1 ) );
+ }
+
+ if ( substr( $opt, 0, 2 ) == '[[' ) {
+ return substr( $opt, 2, -2 );
+ }
+
+ if ( substr( $opt, 0, 1 ) == '{' ) {
+ return FormatJson::decode( $opt, true );
+ }
+ return $opt;
+ }
+
+ /**
+ * Do any required setup which is dependent on test options.
+ *
+ * @see staticSetup() for more information about setup/teardown
+ *
+ * @param array $test Test info supplied by TestFileReader
+ * @param callable|null $nextTeardown
+ * @return ScopedCallback
+ */
+ public function perTestSetup( $test, $nextTeardown = null ) {
+ $teardown = [];
+
+ $this->checkSetupDone( 'setupDatabase', 'setDatabase' );
+ $teardown[] = $this->markSetupDone( 'perTestSetup' );
+
+ $opts = $this->parseOptions( $test['options'] );
+ $config = $test['config'];
+
+ // Find out values for some special options.
+ $langCode =
+ self::getOptionValue( 'language', $opts, 'en' );
+ $variant =
+ self::getOptionValue( 'variant', $opts, false );
+ $maxtoclevel =
+ self::getOptionValue( 'wgMaxTocLevel', $opts, 999 );
+ $linkHolderBatchSize =
+ self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 );
+
+ $setup = [
+ 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
+ 'wgLanguageCode' => $langCode,
+ 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ),
+ 'wgNamespacesWithSubpages' => [ 0 => isset( $opts['subpage'] ) ],
+ 'wgMaxTocLevel' => $maxtoclevel,
+ 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ),
+ 'wgThumbLimits' => [ self::getOptionValue( 'thumbsize', $opts, 180 ) ],
+ 'wgDefaultLanguageVariant' => $variant,
+ 'wgLinkHolderBatchSize' => $linkHolderBatchSize,
+ // Set as a JSON object like:
+ // wgEnableMagicLinks={"ISBN":false, "PMID":false, "RFC":false}
+ 'wgEnableMagicLinks' => self::getOptionValue( 'wgEnableMagicLinks', $opts, [] )
+ + [ 'ISBN' => true, 'PMID' => true, 'RFC' => true ],
+ ];
+
+ if ( $config ) {
+ $configLines = explode( "\n", $config );
+
+ foreach ( $configLines as $line ) {
+ list( $var, $value ) = explode( '=', $line, 2 );
+ $setup[$var] = eval( "return $value;" );
+ }
+ }
+
+ /** @since 1.20 */
+ Hooks::run( 'ParserTestGlobals', [ &$setup ] );
+
+ // Create tidy driver
+ if ( isset( $opts['tidy'] ) ) {
+ // Cache a driver instance
+ if ( $this->tidyDriver === null ) {
+ $this->tidyDriver = MWTidy::factory( $this->tidySupport->getConfig() );
+ }
+ $tidy = $this->tidyDriver;
+ } else {
+ $tidy = false;
+ }
+ MWTidy::setInstance( $tidy );
+ $teardown[] = function () {
+ MWTidy::destroySingleton();
+ };
+
+ // Set content language. This invalidates the magic word cache and title services
+ wfDebug( "Setting up language $langCode" );
+ $lang = Language::factory( $langCode );
+ $setup['wgContLang'] = $lang;
+ $reset = function () {
+ MagicWord::clearCache();
+ $this->resetTitleServices();
+ };
+ $setup[] = $reset;
+ $teardown[] = $reset;
+
+ // Make a user object with the same language
+ $user = new User;
+ $user->setOption( 'language', $langCode );
+ $setup['wgLang'] = $lang;
+
+ // We (re)set $wgThumbLimits to a single-element array above.
+ $user->setOption( 'thumbsize', 0 );
+
+ $setup['wgUser'] = $user;
+
+ // And put both user and language into the context
+ $context = RequestContext::getMain();
+ $context->setUser( $user );
+ $context->setLanguage( $lang );
+ $teardown[] = function () use ( $context ) {
+ // Reset context to the restored globals
+ $context->setUser( $GLOBALS['wgUser'] );
+ $context->setLanguage( $GLOBALS['wgContLang'] );
+ };
+
+ $teardown[] = $this->executeSetupSnippets( $setup );
+
+ return $this->createTeardownObject( $teardown, $nextTeardown );
+ }
+
+ /**
+ * List of temporary tables to create, without prefix.
+ * Some of these probably aren't necessary.
+ * @return array
+ */
+ private function listTables() {
+ $tables = [ 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions',
+ 'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks',
+ 'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks',
+ 'site_stats', 'ipblocks', 'image', 'oldimage',
+ 'recentchanges', 'watchlist', 'interwiki', 'logging', 'log_search',
+ 'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
+ 'archive', 'user_groups', 'page_props', 'category'
+ ];
+
+ if ( in_array( $this->db->getType(), [ 'mysql', 'sqlite', 'oracle' ] ) ) {
+ array_push( $tables, 'searchindex' );
+ }
+
+ // Allow extensions to add to the list of tables to duplicate;
+ // may be necessary if they hook into page save or other code
+ // which will require them while running tests.
+ Hooks::run( 'ParserTestTables', [ &$tables ] );
+
+ return $tables;
+ }
+
+ public function setDatabase( IDatabase $db ) {
+ $this->db = $db;
+ $this->setupDone['setDatabase'] = true;
+ }
+
+ /**
+ * Set up temporary DB tables.
+ *
+ * For best performance, call this once only for all tests. However, it can
+ * be called at the start of each test if more isolation is desired.
+ *
+ * @todo: This is basically an unrefactored copy of
+ * MediaWikiTestCase::setupAllTestDBs. They should be factored out somehow.
+ *
+ * Do not call this function from a MediaWikiTestCase subclass, since
+ * MediaWikiTestCase does its own DB setup. Instead use setDatabase().
+ *
+ * @see staticSetup() for more information about setup/teardown
+ *
+ * @param ScopedCallback|null $nextTeardown The next teardown object
+ * @return ScopedCallback The teardown object
+ */
+ public function setupDatabase( $nextTeardown = null ) {
+ global $wgDBprefix;
+
+ $this->db = wfGetDB( DB_MASTER );
+ $dbType = $this->db->getType();
+
+ if ( $dbType == 'oracle' ) {
+ $suspiciousPrefixes = [ 'pt_', MediaWikiTestCase::ORA_DB_PREFIX ];
+ } else {
+ $suspiciousPrefixes = [ 'parsertest_', MediaWikiTestCase::DB_PREFIX ];
+ }
+ if ( in_array( $wgDBprefix, $suspiciousPrefixes ) ) {
+ throw new MWException( "\$wgDBprefix=$wgDBprefix suggests DB setup is already done" );
+ }
+
+ $teardown = [];
+
+ $teardown[] = $this->markSetupDone( 'setupDatabase' );
+
+ # CREATE TEMPORARY TABLE breaks if there is more than one server
+ if ( wfGetLB()->getServerCount() != 1 ) {
+ $this->useTemporaryTables = false;
+ }
+
+ $temporary = $this->useTemporaryTables || $dbType == 'postgres';
+ $prefix = $dbType != 'oracle' ? 'parsertest_' : 'pt_';
+
+ $this->dbClone = new CloneDatabase( $this->db, $this->listTables(), $prefix );
+ $this->dbClone->useTemporaryTables( $temporary );
+ $this->dbClone->cloneTableStructure();
+
+ if ( $dbType == 'oracle' ) {
+ $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
+ # Insert 0 user to prevent FK violations
+
+ # Anonymous user
+ $this->db->insert( 'user', [
+ 'user_id' => 0,
+ 'user_name' => 'Anonymous' ] );
+ }
+
+ $teardown[] = function () {
+ $this->teardownDatabase();
+ };
+
+ // Wipe some DB query result caches on setup and teardown
+ $reset = function () {
+ LinkCache::singleton()->clear();
+
+ // Clear the message cache
+ MessageCache::singleton()->clear();
+ };
+ $reset();
+ $teardown[] = $reset;
+ return $this->createTeardownObject( $teardown, $nextTeardown );
+ }
+
+ /**
+ * Add data about uploads to the new test DB, and set up the upload
+ * directory. This should be called after either setDatabase() or
+ * setupDatabase().
+ *
+ * @param ScopedCallback|null $nextTeardown The next teardown object
+ * @return ScopedCallback The teardown object
+ */
+ public function setupUploads( $nextTeardown = null ) {
+ $teardown = [];
+
+ $this->checkSetupDone( 'setupDatabase', 'setDatabase' );
+ $teardown[] = $this->markSetupDone( 'setupUploads' );
+
+ // Create the files in the upload directory (or pretend to create them
+ // in a MockFileBackend). Append teardown callback.
+ $teardown[] = $this->setupUploadBackend();
+
+ // Create a user
+ $user = User::createNew( 'WikiSysop' );
+
+ // Register the uploads in the database
+
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
+ # note that the size/width/height/bits/etc of the file
+ # are actually set by inspecting the file itself; the arguments
+ # to recordUpload2 have no effect. That said, we try to make things
+ # match up so it is less confusing to readers of the code & tests.
+ $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', [
+ 'size' => 7881,
+ 'width' => 1941,
+ 'height' => 220,
+ 'bits' => 8,
+ 'media_type' => MEDIATYPE_BITMAP,
+ 'mime' => 'image/jpeg',
+ 'metadata' => serialize( [] ),
+ 'sha1' => Wikimedia\base_convert( '1', 16, 36, 31 ),
+ 'fileExists' => true
+ ], $this->db->timestamp( '20010115123500' ), $user );
+
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Thumb.png' ) );
+ # again, note that size/width/height below are ignored; see above.
+ $image->recordUpload2( '', 'Upload of some lame thumbnail', 'Some lame thumbnail', [
+ 'size' => 22589,
+ 'width' => 135,
+ 'height' => 135,
+ 'bits' => 8,
+ 'media_type' => MEDIATYPE_BITMAP,
+ 'mime' => 'image/png',
+ 'metadata' => serialize( [] ),
+ 'sha1' => Wikimedia\base_convert( '2', 16, 36, 31 ),
+ 'fileExists' => true
+ ], $this->db->timestamp( '20130225203040' ), $user );
+
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.svg' ) );
+ $image->recordUpload2( '', 'Upload of some lame SVG', 'Some lame SVG', [
+ 'size' => 12345,
+ 'width' => 240,
+ 'height' => 180,
+ 'bits' => 0,
+ 'media_type' => MEDIATYPE_DRAWING,
+ 'mime' => 'image/svg+xml',
+ 'metadata' => serialize( [] ),
+ 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
+ 'fileExists' => true
+ ], $this->db->timestamp( '20010115123500' ), $user );
+
+ # This image will be blacklisted in [[MediaWiki:Bad image list]]
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) );
+ $image->recordUpload2( '', 'zomgnotcensored', 'Borderline image', [
+ 'size' => 12345,
+ 'width' => 320,
+ 'height' => 240,
+ 'bits' => 24,
+ 'media_type' => MEDIATYPE_BITMAP,
+ 'mime' => 'image/jpeg',
+ 'metadata' => serialize( [] ),
+ 'sha1' => Wikimedia\base_convert( '3', 16, 36, 31 ),
+ 'fileExists' => true
+ ], $this->db->timestamp( '20010115123500' ), $user );
+
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Video.ogv' ) );
+ $image->recordUpload2( '', 'A pretty movie', 'Will it play', [
+ 'size' => 12345,
+ 'width' => 320,
+ 'height' => 240,
+ 'bits' => 0,
+ 'media_type' => MEDIATYPE_VIDEO,
+ 'mime' => 'application/ogg',
+ 'metadata' => serialize( [] ),
+ 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
+ 'fileExists' => true
+ ], $this->db->timestamp( '20010115123500' ), $user );
+
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Audio.oga' ) );
+ $image->recordUpload2( '', 'An awesome hitsong', 'Will it play', [
+ 'size' => 12345,
+ 'width' => 0,
+ 'height' => 0,
+ 'bits' => 0,
+ 'media_type' => MEDIATYPE_AUDIO,
+ 'mime' => 'application/ogg',
+ 'metadata' => serialize( [] ),
+ 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
+ 'fileExists' => true
+ ], $this->db->timestamp( '20010115123500' ), $user );
+
+ # A DjVu file
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'LoremIpsum.djvu' ) );
+ $image->recordUpload2( '', 'Upload a DjVu', 'A DjVu', [
+ 'size' => 3249,
+ 'width' => 2480,
+ 'height' => 3508,
+ 'bits' => 0,
+ 'media_type' => MEDIATYPE_BITMAP,
+ 'mime' => 'image/vnd.djvu',
+ 'metadata' => '<?xml version="1.0" ?>
+<!DOCTYPE DjVuXML PUBLIC "-//W3C//DTD DjVuXML 1.1//EN" "pubtext/DjVuXML-s.dtd">
+<DjVuXML>
+<HEAD></HEAD>
+<BODY><OBJECT height="3508" width="2480">
+<PARAM name="DPI" value="300" />
+<PARAM name="GAMMA" value="2.2" />
+</OBJECT>
+<OBJECT height="3508" width="2480">
+<PARAM name="DPI" value="300" />
+<PARAM name="GAMMA" value="2.2" />
+</OBJECT>
+<OBJECT height="3508" width="2480">
+<PARAM name="DPI" value="300" />
+<PARAM name="GAMMA" value="2.2" />
+</OBJECT>
+<OBJECT height="3508" width="2480">
+<PARAM name="DPI" value="300" />
+<PARAM name="GAMMA" value="2.2" />
+</OBJECT>
+<OBJECT height="3508" width="2480">
+<PARAM name="DPI" value="300" />
+<PARAM name="GAMMA" value="2.2" />
+</OBJECT>
+</BODY>
+</DjVuXML>',
+ 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
+ 'fileExists' => true
+ ], $this->db->timestamp( '20010115123600' ), $user );
+
+ return $this->createTeardownObject( $teardown, $nextTeardown );
+ }
+
+ /**
+ * Helper for database teardown, called from the teardown closure. Destroy
+ * the database clone and fix up some things that CloneDatabase doesn't fix.
+ *
+ * @todo Move most things here to CloneDatabase
+ */
+ private function teardownDatabase() {
+ $this->checkSetupDone( 'setupDatabase' );
+
+ $this->dbClone->destroy();
+ $this->databaseSetupDone = false;
+
+ if ( $this->useTemporaryTables ) {
+ if ( $this->db->getType() == 'sqlite' ) {
+ # Under SQLite the searchindex table is virtual and need
+ # to be explicitly destroyed. See bug 29912
+ # See also MediaWikiTestCase::destroyDB()
+ wfDebug( __METHOD__ . " explicitly destroying sqlite virtual table parsertest_searchindex\n" );
+ $this->db->query( "DROP TABLE `parsertest_searchindex`" );
+ }
+ # Don't need to do anything
+ return;
+ }
+
+ $tables = $this->listTables();
+
+ foreach ( $tables as $table ) {
+ if ( $this->db->getType() == 'oracle' ) {
+ $this->db->query( "DROP TABLE pt_$table DROP CONSTRAINTS" );
+ } else {
+ $this->db->query( "DROP TABLE `parsertest_$table`" );
+ }
+ }
+
+ if ( $this->db->getType() == 'oracle' ) {
+ $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
+ }
+ }
+
+ /**
+ * Upload test files to the backend created by createRepoGroup().
+ *
+ * @return callable The teardown callback
+ */
+ private function setupUploadBackend() {
+ global $IP;
+
+ $repo = RepoGroup::singleton()->getLocalRepo();
+ $base = $repo->getZonePath( 'public' );
+ $backend = $repo->getBackend();
+ $backend->prepare( [ 'dir' => "$base/3/3a" ] );
+ $backend->store( [
+ 'src' => "$IP/tests/phpunit/data/parser/headbg.jpg",
+ 'dst' => "$base/3/3a/Foobar.jpg"
+ ] );
+ $backend->prepare( [ 'dir' => "$base/e/ea" ] );
+ $backend->store( [
+ 'src' => "$IP/tests/phpunit/data/parser/wiki.png",
+ 'dst' => "$base/e/ea/Thumb.png"
+ ] );
+ $backend->prepare( [ 'dir' => "$base/0/09" ] );
+ $backend->store( [
+ 'src' => "$IP/tests/phpunit/data/parser/headbg.jpg",
+ 'dst' => "$base/0/09/Bad.jpg"
+ ] );
+ $backend->prepare( [ 'dir' => "$base/5/5f" ] );
+ $backend->store( [
+ 'src' => "$IP/tests/phpunit/data/parser/LoremIpsum.djvu",
+ 'dst' => "$base/5/5f/LoremIpsum.djvu"
+ ] );
+
+ // No helpful SVG file to copy, so make one ourselves
+ $data = '<?xml version="1.0" encoding="utf-8"?>' .
+ '<svg xmlns="http://www.w3.org/2000/svg"' .
+ ' version="1.1" width="240" height="180"/>';
+
+ $backend->prepare( [ 'dir' => "$base/f/ff" ] );
+ $backend->quickCreate( [
+ 'content' => $data, 'dst' => "$base/f/ff/Foobar.svg"
+ ] );
+
+ return function () use ( $backend ) {
+ if ( $backend instanceof MockFileBackend ) {
+ // In memory backend, so dont bother cleaning them up.
+ return;
+ }
+ $this->teardownUploadBackend();
+ };
+ }
+
+ /**
+ * Remove the dummy uploads directory
+ */
+ private function teardownUploadBackend() {
+ if ( $this->keepUploads ) {
+ return;
+ }
+
+ $repo = RepoGroup::singleton()->getLocalRepo();
+ $public = $repo->getZonePath( 'public' );
+
+ $this->deleteFiles(
+ [
+ "$public/3/3a/Foobar.jpg",
+ "$public/e/ea/Thumb.png",
+ "$public/0/09/Bad.jpg",
+ "$public/5/5f/LoremIpsum.djvu",
+ "$public/f/ff/Foobar.svg",
+ "$public/0/00/Video.ogv",
+ "$public/4/41/Audio.oga",
+ ]
+ );
+ }
+
+ /**
+ * Delete the specified files and their parent directories
+ * @param array $files File backend URIs mwstore://...
+ */
+ private function deleteFiles( $files ) {
+ // Delete the files
+ $backend = RepoGroup::singleton()->getLocalRepo()->getBackend();
+ foreach ( $files as $file ) {
+ $backend->delete( [ 'src' => $file ], [ 'force' => 1 ] );
+ }
+
+ // Delete the parent directories
+ foreach ( $files as $file ) {
+ $tmp = FileBackend::parentStoragePath( $file );
+ while ( $tmp ) {
+ if ( !$backend->clean( [ 'dir' => $tmp ] )->isOK() ) {
+ break;
+ }
+ $tmp = FileBackend::parentStoragePath( $tmp );
+ }
+ }
+ }
+
+ /**
+ * Add articles to the test DB.
+ *
+ * @param $articles Article info array from TestFileReader
+ */
+ public function addArticles( $articles ) {
+ global $wgContLang;
+ $setup = [];
+ $teardown = [];
+
+ // Be sure ParserTestRunner::addArticle has correct language set,
+ // so that system messages get into the right language cache
+ if ( $wgContLang->getCode() !== 'en' ) {
+ $setup['wgLanguageCode'] = 'en';
+ $setup['wgContLang'] = Language::factory( 'en' );
+ }
+
+ // Add special namespaces, in case that hasn't been done by staticSetup() yet
+ $this->appendNamespaceSetup( $setup, $teardown );
+
+ // wgCapitalLinks obviously needs initialisation
+ $setup['wgCapitalLinks'] = true;
+
+ $teardown[] = $this->executeSetupSnippets( $setup );
+
+ foreach ( $articles as $info ) {
+ $this->addArticle( $info['name'], $info['text'], $info['file'], $info['line'] );
+ }
+
+ // Wipe WANObjectCache process cache, which is invalidated by article insertion
+ // due to T144706
+ ObjectCache::getMainWANInstance()->clearProcessCache();
+
+ $this->executeSetupSnippets( $teardown );
+ }
+
+ /**
+ * Insert a temporary test article
+ * @param string $name The title, including any prefix
+ * @param string $text The article text
+ * @param string $file The input file name
+ * @param int|string $line The input line number, for reporting errors
+ * @throws Exception
+ * @throws MWException
+ */
+ private function addArticle( $name, $text, $file, $line ) {
+ $text = self::chomp( $text );
+ $name = self::chomp( $name );
+
+ $title = Title::newFromText( $name );
+ wfDebug( __METHOD__ . ": adding $name" );
+
+ if ( is_null( $title ) ) {
+ throw new MWException( "invalid title '$name' at $file:$line\n" );
+ }
+
+ $page = WikiPage::factory( $title );
+ $page->loadPageData( 'fromdbmaster' );
+
+ if ( $page->exists() ) {
+ throw new MWException( "duplicate article '$name' at $file:$line\n" );
+ }
+
+ $status = $page->doEditContent( ContentHandler::makeContent( $text, $title ), '', EDIT_NEW );
+ if ( !$status->isOK() ) {
+ throw new MWException( $status->getWikiText( false, false, 'en' ) );
+ }
+
+ // The RepoGroup cache is invalidated by the creation of file redirects
+ if ( $title->getNamespace() === NS_IMAGE ) {
+ RepoGroup::singleton()->clearCache( $title );
+ }
+ }
+
+ /**
+ * Check if a hook is installed
+ *
+ * @param string $name
+ * @return bool True if tag hook is present
+ */
+ public function requireHook( $name ) {
+ global $wgParser;
+
+ $wgParser->firstCallInit(); // make sure hooks are loaded.
+ if ( isset( $wgParser->mTagHooks[$name] ) ) {
+ return true;
+ } else {
+ $this->recorder->warning( " This test suite requires the '$name' hook " .
+ "extension, skipping." );
+ return false;
+ }
+ }
+
+ /**
+ * Check if a function hook is installed
+ *
+ * @param string $name
+ * @return bool True if function hook is present
+ */
+ public function requireFunctionHook( $name ) {
+ global $wgParser;
+
+ $wgParser->firstCallInit(); // make sure hooks are loaded.
+
+ if ( isset( $wgParser->mFunctionHooks[$name] ) ) {
+ return true;
+ } else {
+ $this->recorder->warning( " This test suite requires the '$name' function " .
+ "hook extension, skipping." );
+ return false;
+ }
+ }
+
+ /**
+ * Check if a transparent tag hook is installed
+ *
+ * @param string $name
+ * @return bool True if function hook is present
+ */
+ public function requireTransparentHook( $name ) {
+ global $wgParser;
+
+ $wgParser->firstCallInit(); // make sure hooks are loaded.
+
+ if ( isset( $wgParser->mTransparentTagHooks[$name] ) ) {
+ return true;
+ } else {
+ $this->recorder->warning( " This test suite requires the '$name' transparent " .
+ "hook extension, skipping.\n" );
+ return false;
+ }
+ }
+
+ /**
+ * The ParserGetVariableValueTs hook, used to make sure time-related parser
+ * functions give a persistent value.
+ */
+ static function getFakeTimestamp( &$parser, &$ts ) {
+ $ts = 123; // parsed as '1970-01-01T00:02:03Z'
+ return true;
+ }
+}
--- /dev/null
+<?php
+
+class PhpunitTestRecorder extends TestRecorder {
+ private $testCase;
+
+ public function setTestCase( PHPUnit_Framework_TestCase $testCase ) {
+ $this->testCase = $testCase;
+ }
+
+ /**
+ * Mark a test skipped
+ */
+ public function skipped( $test, $reason ) {
+ $this->testCase->markTestSkipped( "SKIPPED: $reason" );
+ }
+}
-Parser tests are run using our PHPUnit test suite in tests/phpunit:
+Parser tests can be run either via PHPUnit or by using the standalone
+parserTests.php in this directory. The standalone version provides more
+options.
+
+To run parser tests via PHPUnit:
$ cd tests/phpunit
- ./phpunit.php --group Parser
+ ./phpunit.php --testsuite parsertests
-You can optionally filter by title using --regex. I.e. :
+You can optionally filter by title using --filter, e.g.
- ./phpunit.php --group Parser --regex="Bug 6200"
+ ./phpunit.php --testsuite parsertests --filter="Bug 6200"
+++ /dev/null
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Testing
- */
-
-/**
- * An iterator for use as a phpunit data provider. Provides the test arguments
- * in the order expected by NewParserTest::testParserTest().
- */
-class TestFileDataProvider extends TestFileIterator {
- function current() {
- $test = parent::current();
- if ( $test ) {
- return [
- $test['test'],
- $test['input'],
- $test['result'],
- $test['options'],
- $test['config'],
- ];
- } else {
- return $test;
- }
- }
-}
-
+++ /dev/null
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Testing
- */
-
-class TestFileIterator implements Iterator {
- private $file;
- private $fh;
- /**
- * @var ParserTest|MediaWikiParserTest An instance of ParserTest (parserTests.php)
- * or MediaWikiParserTest (phpunit)
- */
- private $parserTest;
- private $index = 0;
- private $test;
- private $section = null;
- /** String|null: current test section being analyzed */
- private $sectionData = [];
- private $lineNum;
- private $eof;
- # Create a fake parser tests which never run anything unless
- # asked to do so. This will avoid running hooks for a disabled test
- private $delayedParserTest;
- private $nextSubTest = 0;
-
- function __construct( $file, $parserTest ) {
- $this->file = $file;
- $this->fh = fopen( $this->file, "rt" );
-
- if ( !$this->fh ) {
- throw new MWException( "Couldn't open file '$file'\n" );
- }
-
- $this->parserTest = $parserTest;
- $this->delayedParserTest = new DelayedParserTest();
-
- $this->lineNum = $this->index = 0;
- }
-
- function rewind() {
- if ( fseek( $this->fh, 0 ) ) {
- throw new MWException( "Couldn't fseek to the start of '$this->file'\n" );
- }
-
- $this->index = -1;
- $this->lineNum = 0;
- $this->eof = false;
- $this->next();
-
- return true;
- }
-
- function current() {
- return $this->test;
- }
-
- function key() {
- return $this->index;
- }
-
- function next() {
- if ( $this->readNextTest() ) {
- $this->index++;
- return true;
- } else {
- $this->eof = true;
- }
- }
-
- function valid() {
- return $this->eof != true;
- }
-
- function setupCurrentTest() {
- // "input" and "result" are old section names allowed
- // for backwards-compatibility.
- $input = $this->checkSection( [ 'wikitext', 'input' ], false );
- $result = $this->checkSection( [ 'html/php', 'html/*', 'html', 'result' ], false );
- // some tests have "with tidy" and "without tidy" variants
- $tidy = $this->checkSection( [ 'html/php+tidy', 'html+tidy' ], false );
- if ( $tidy != false ) {
- if ( $this->nextSubTest == 0 ) {
- if ( $result != false ) {
- $this->nextSubTest = 1; // rerun non-tidy variant later
- }
- $result = $tidy;
- } else {
- $this->nextSubTest = 0; // go on to next test after this
- $tidy = false;
- }
- }
-
- if ( !isset( $this->sectionData['options'] ) ) {
- $this->sectionData['options'] = '';
- }
-
- if ( !isset( $this->sectionData['config'] ) ) {
- $this->sectionData['config'] = '';
- }
-
- $isDisabled = preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) &&
- !$this->parserTest->runDisabled;
- $isParsoidOnly = preg_match( '/\\bparsoid\\b/i', $this->sectionData['options'] ) &&
- $result == 'html' &&
- !$this->parserTest->runParsoid;
- $isFiltered = !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] );
- if ( $input == false || $result == false || $isDisabled || $isParsoidOnly || $isFiltered ) {
- # disabled test
- return false;
- }
-
- # We are really going to run the test, run pending hooks and hooks function
- wfDebug( __METHOD__ . " unleashing delayed test for: {$this->sectionData['test']}" );
- $hooksResult = $this->delayedParserTest->unleash( $this->parserTest );
- if ( !$hooksResult ) {
- # Some hook reported an issue. Abort.
- throw new MWException( "Problem running requested parser hook from the test file" );
- }
-
- $this->test = [
- 'test' => ParserTest::chomp( $this->sectionData['test'] ),
- 'subtest' => $this->nextSubTest,
- 'input' => ParserTest::chomp( $this->sectionData[$input] ),
- 'result' => ParserTest::chomp( $this->sectionData[$result] ),
- 'options' => ParserTest::chomp( $this->sectionData['options'] ),
- 'config' => ParserTest::chomp( $this->sectionData['config'] ),
- ];
- if ( $tidy != false ) {
- $this->test['options'] .= " tidy";
- }
- return true;
- }
-
- function readNextTest() {
- # Run additional subtests of previous test
- while ( $this->nextSubTest > 0 ) {
- if ( $this->setupCurrentTest() ) {
- return true;
- }
- }
-
- $this->clearSection();
- # Reset hooks for the delayed test object
- $this->delayedParserTest->reset();
-
- while ( false !== ( $line = fgets( $this->fh ) ) ) {
- $this->lineNum++;
- $matches = [];
-
- if ( preg_match( '/^!!\s*(\S+)/', $line, $matches ) ) {
- $this->section = strtolower( $matches[1] );
-
- if ( $this->section == 'endarticle' ) {
- $this->checkSection( 'text' );
- $this->checkSection( 'article' );
-
- $this->parserTest->addArticle(
- ParserTest::chomp( $this->sectionData['article'] ),
- $this->sectionData['text'], $this->lineNum );
-
- $this->clearSection();
-
- continue;
- }
-
- if ( $this->section == 'endhooks' ) {
- $this->checkSection( 'hooks' );
-
- foreach ( explode( "\n", $this->sectionData['hooks'] ) as $line ) {
- $line = trim( $line );
-
- if ( $line ) {
- $this->delayedParserTest->requireHook( $line );
- }
- }
-
- $this->clearSection();
-
- continue;
- }
-
- if ( $this->section == 'endfunctionhooks' ) {
- $this->checkSection( 'functionhooks' );
-
- foreach ( explode( "\n", $this->sectionData['functionhooks'] ) as $line ) {
- $line = trim( $line );
-
- if ( $line ) {
- $this->delayedParserTest->requireFunctionHook( $line );
- }
- }
-
- $this->clearSection();
-
- continue;
- }
-
- if ( $this->section == 'endtransparenthooks' ) {
- $this->checkSection( 'transparenthooks' );
-
- foreach ( explode( "\n", $this->sectionData['transparenthooks'] ) as $line ) {
- $line = trim( $line );
-
- if ( $line ) {
- $this->delayedParserTest->requireTransparentHook( $line );
- }
- }
-
- $this->clearSection();
-
- continue;
- }
-
- if ( $this->section == 'end' ) {
- $this->checkSection( 'test' );
- do {
- if ( $this->setupCurrentTest() ) {
- return true;
- }
- } while ( $this->nextSubTest > 0 );
- # go on to next test (since this was disabled)
- $this->clearSection();
- $this->delayedParserTest->reset();
- continue;
- }
-
- if ( isset( $this->sectionData[$this->section] ) ) {
- throw new MWException( "duplicate section '$this->section' "
- . "at line {$this->lineNum} of $this->file\n" );
- }
-
- $this->sectionData[$this->section] = '';
-
- continue;
- }
-
- if ( $this->section ) {
- $this->sectionData[$this->section] .= $line;
- }
- }
-
- return false;
- }
-
- /**
- * Clear section name and its data
- */
- private function clearSection() {
- $this->sectionData = [];
- $this->section = null;
-
- }
-
- /**
- * Verify the current section data has some value for the given token
- * name(s) (first parameter).
- * Throw an exception if it is not set, referencing current section
- * and adding the current file name and line number
- *
- * @param string|array $tokens Expected token(s) that should have been
- * mentioned before closing this section
- * @param bool $fatal True iff an exception should be thrown if
- * the section is not found.
- * @return bool|string
- * @throws MWException
- */
- private function checkSection( $tokens, $fatal = true ) {
- if ( is_null( $this->section ) ) {
- throw new MWException( __METHOD__ . " can not verify a null section!\n" );
- }
- if ( !is_array( $tokens ) ) {
- $tokens = [ $tokens ];
- }
- if ( count( $tokens ) == 0 ) {
- throw new MWException( __METHOD__ . " can not verify zero sections!\n" );
- }
-
- $data = $this->sectionData;
- $tokens = array_filter( $tokens, function ( $token ) use ( $data ) {
- return isset( $data[$token] );
- } );
-
- if ( count( $tokens ) == 0 ) {
- if ( !$fatal ) {
- return false;
- }
- throw new MWException( sprintf(
- "'%s' without '%s' at line %s of %s\n",
- $this->section,
- implode( ',', $tokens ),
- $this->lineNum,
- $this->file
- ) );
- }
- if ( count( $tokens ) > 1 ) {
- throw new MWException( sprintf(
- "'%s' with unexpected tokens '%s' at line %s of %s\n",
- $this->section,
- implode( ',', $tokens ),
- $this->lineNum,
- $this->file
- ) );
- }
-
- return array_values( $tokens )[0];
- }
-}
-
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Testing
+ */
+
+class TestFileReader {
+ private $file;
+ private $fh;
+ private $section = null;
+ /** String|null: current test section being analyzed */
+ private $sectionData = [];
+ private $lineNum = 0;
+ private $runDisabled;
+ private $runParsoid;
+ private $regex;
+
+ private $articles = [];
+ private $requirements = [];
+ private $tests = [];
+
+ public static function read( $file, array $options = [] ) {
+ $reader = new self( $file, $options );
+ $reader->execute();
+
+ $requirements = [];
+ foreach ( $reader->requirements as $type => $reqsOfType ) {
+ foreach ( $reqsOfType as $name => $unused ) {
+ $requirements[] = [
+ 'type' => $type,
+ 'name' => $name
+ ];
+ }
+ }
+
+ return [
+ 'requirements' => $requirements,
+ 'tests' => $reader->tests,
+ 'articles' => $reader->articles
+ ];
+ }
+
+ private function __construct( $file, $options ) {
+ $this->file = $file;
+ $this->fh = fopen( $this->file, "rt" );
+
+ if ( !$this->fh ) {
+ throw new MWException( "Couldn't open file '$file'\n" );
+ }
+
+ $options = $options + [
+ 'runDisabled' => false,
+ 'runParsoid' => false,
+ 'regex' => '//',
+ ];
+ $this->runDisabled = $options['runDisabled'];
+ $this->runParsoid = $options['runParsoid'];
+ $this->regex = $options['regex'];
+ }
+
+ private function addCurrentTest() {
+ // "input" and "result" are old section names allowed
+ // for backwards-compatibility.
+ $input = $this->checkSection( [ 'wikitext', 'input' ], false );
+ $result = $this->checkSection( [ 'html/php', 'html/*', 'html', 'result' ], false );
+ // Some tests have "with tidy" and "without tidy" variants
+ $tidy = $this->checkSection( [ 'html/php+tidy', 'html+tidy' ], false );
+
+ if ( !isset( $this->sectionData['options'] ) ) {
+ $this->sectionData['options'] = '';
+ }
+
+ if ( !isset( $this->sectionData['config'] ) ) {
+ $this->sectionData['config'] = '';
+ }
+
+ $isDisabled = preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) &&
+ !$this->runDisabled;
+ $isParsoidOnly = preg_match( '/\\bparsoid\\b/i', $this->sectionData['options'] ) &&
+ $result == 'html' &&
+ !$this->runParsoid;
+ $isFiltered = !preg_match( $this->regex, $this->sectionData['test'] );
+ if ( $input == false || $result == false || $isDisabled || $isParsoidOnly || $isFiltered ) {
+ // Disabled test
+ return;
+ }
+
+ $test = [
+ 'test' => ParserTestRunner::chomp( $this->sectionData['test'] ),
+ 'input' => ParserTestRunner::chomp( $this->sectionData[$input] ),
+ 'result' => ParserTestRunner::chomp( $this->sectionData[$result] ),
+ 'options' => ParserTestRunner::chomp( $this->sectionData['options'] ),
+ 'config' => ParserTestRunner::chomp( $this->sectionData['config'] ),
+ ];
+ $test['desc'] = $test['test'];
+ $this->tests[] = $test;
+
+ if ( $tidy !== false ) {
+ $test['options'] .= " tidy";
+ $test['desc'] .= ' (with tidy)';
+ $test['result'] = ParserTestRunner::chomp( $this->sectionData[$tidy] );
+ $this->tests[] = $test;
+ }
+ }
+
+ private function execute() {
+ while ( false !== ( $line = fgets( $this->fh ) ) ) {
+ $this->lineNum++;
+ $matches = [];
+
+ if ( preg_match( '/^!!\s*(\S+)/', $line, $matches ) ) {
+ $this->section = strtolower( $matches[1] );
+
+ if ( $this->section == 'endarticle' ) {
+ $this->checkSection( 'text' );
+ $this->checkSection( 'article' );
+
+ $this->addArticle(
+ ParserTestRunner::chomp( $this->sectionData['article'] ),
+ $this->sectionData['text'], $this->lineNum );
+
+ $this->clearSection();
+
+ continue;
+ }
+
+ if ( $this->section == 'endhooks' ) {
+ $this->checkSection( 'hooks' );
+
+ foreach ( explode( "\n", $this->sectionData['hooks'] ) as $line ) {
+ $line = trim( $line );
+
+ if ( $line ) {
+ $this->addRequirement( 'hook', $line );
+ }
+ }
+
+ $this->clearSection();
+
+ continue;
+ }
+
+ if ( $this->section == 'endfunctionhooks' ) {
+ $this->checkSection( 'functionhooks' );
+
+ foreach ( explode( "\n", $this->sectionData['functionhooks'] ) as $line ) {
+ $line = trim( $line );
+
+ if ( $line ) {
+ $this->addRequirement( 'functionHook', $line );
+ }
+ }
+
+ $this->clearSection();
+
+ continue;
+ }
+
+ if ( $this->section == 'endtransparenthooks' ) {
+ $this->checkSection( 'transparenthooks' );
+
+ foreach ( explode( "\n", $this->sectionData['transparenthooks'] ) as $line ) {
+ $line = trim( $line );
+
+ if ( $line ) {
+ $this->addRequirement( 'transparentHook', $line );
+ }
+ }
+
+ $this->clearSection();
+
+ continue;
+ }
+
+ if ( $this->section == 'end' ) {
+ $this->checkSection( 'test' );
+ $this->addCurrentTest();
+ $this->clearSection();
+ continue;
+ }
+
+ if ( isset( $this->sectionData[$this->section] ) ) {
+ throw new MWException( "duplicate section '$this->section' "
+ . "at line {$this->lineNum} of $this->file\n" );
+ }
+
+ $this->sectionData[$this->section] = '';
+
+ continue;
+ }
+
+ if ( $this->section ) {
+ $this->sectionData[$this->section] .= $line;
+ }
+ }
+ }
+
+ /**
+ * Clear section name and its data
+ */
+ private function clearSection() {
+ $this->sectionData = [];
+ $this->section = null;
+
+ }
+
+ /**
+ * Verify the current section data has some value for the given token
+ * name(s) (first parameter).
+ * Throw an exception if it is not set, referencing current section
+ * and adding the current file name and line number
+ *
+ * @param string|array $tokens Expected token(s) that should have been
+ * mentioned before closing this section
+ * @param bool $fatal True iff an exception should be thrown if
+ * the section is not found.
+ * @return bool|string
+ * @throws MWException
+ */
+ private function checkSection( $tokens, $fatal = true ) {
+ if ( is_null( $this->section ) ) {
+ throw new MWException( __METHOD__ . " can not verify a null section!\n" );
+ }
+ if ( !is_array( $tokens ) ) {
+ $tokens = [ $tokens ];
+ }
+ if ( count( $tokens ) == 0 ) {
+ throw new MWException( __METHOD__ . " can not verify zero sections!\n" );
+ }
+
+ $data = $this->sectionData;
+ $tokens = array_filter( $tokens, function ( $token ) use ( $data ) {
+ return isset( $data[$token] );
+ } );
+
+ if ( count( $tokens ) == 0 ) {
+ if ( !$fatal ) {
+ return false;
+ }
+ throw new MWException( sprintf(
+ "'%s' without '%s' at line %s of %s\n",
+ $this->section,
+ implode( ',', $tokens ),
+ $this->lineNum,
+ $this->file
+ ) );
+ }
+ if ( count( $tokens ) > 1 ) {
+ throw new MWException( sprintf(
+ "'%s' with unexpected tokens '%s' at line %s of %s\n",
+ $this->section,
+ implode( ',', $tokens ),
+ $this->lineNum,
+ $this->file
+ ) );
+ }
+
+ return array_values( $tokens )[0];
+ }
+
+ private function addArticle( $name, $text, $line ) {
+ $this->articles[] = [
+ 'name' => $name,
+ 'text' => $text,
+ 'line' => $line,
+ 'file' => $this->file
+ ];
+ }
+
+ private function addRequirement( $type, $name ) {
+ $this->requirements[$type][$name] = true;
+ }
+}
+
* @ingroup Testing
*/
-class TestRecorder implements ITestRecorder {
- public $parent;
- public $term;
+/**
+ * Interface to record parser test results.
+ *
+ * The TestRecorder is an class hierarchy to record the result of
+ * MediaWiki parser tests. One should call start() before running the
+ * full parser tests and end() once all the tests have been finished.
+ * After each test, you should use record() to keep track of your tests
+ * results. Finally, report() is used to generate a summary of your
+ * test run, one could dump it to the console for human consumption or
+ * register the result in a database for tracking purposes.
+ *
+ * @since 1.22
+ */
+abstract class TestRecorder {
- function __construct( $parent ) {
- $this->parent = $parent;
- $this->term = $parent->term;
+ /**
+ * Called at beginning of the parser test run
+ */
+ public function start() {
}
- function start() {
- $this->total = 0;
- $this->success = 0;
+ /**
+ * Called before starting a test
+ */
+ public function startTest( $test ) {
}
- function record( $test, $subtest, $result ) {
- $this->total++;
- $this->success += ( $result ? 1 : 0 );
+ /**
+ * Called before starting an input file
+ */
+ public function startSuite( $path ) {
}
- function end() {
- // dummy
+ /**
+ * Called after ending an input file
+ */
+ public function endSuite( $path ) {
}
- function report() {
- if ( $this->total > 0 ) {
- $this->reportPercentage( $this->success, $this->total );
- } else {
- throw new MWException( "No tests found.\n" );
- }
+ /**
+ * Called after each test
+ * @param array $test
+ * @param ParserTestResult $result
+ */
+ public function record( $test, ParserTestResult $result ) {
}
- function reportPercentage( $success, $total ) {
- $ratio = wfPercent( 100 * $success / $total );
- print $this->term->color( 1 ) . "Passed $success of $total tests ($ratio)... ";
+ /**
+ * Show a warning to the user
+ */
+ public function warning( $message ) {
+ }
- if ( $success == $total ) {
- print $this->term->color( 32 ) . "ALL TESTS PASSED!";
- } else {
- $failed = $total - $success;
- print $this->term->color( 31 ) . "$failed tests failed!";
- }
+ /**
+ * Mark a test skipped
+ */
+ public function skipped( $test, $subtest ) {
+ }
- print $this->term->reset() . "\n";
+ /**
+ * Called before finishing the test run
+ */
+ public function report() {
+ }
- return ( $success == $total );
+ /**
+ * Called at the end of the parser test run
+ */
+ public function end() {
}
+
}
}
function finalSetup() {
- require_once __DIR__ . '/../TestsAutoLoader.php';
+ self::requireTestsAutoloader();
+ TestSetup::applyInitialConfig();
}
function execute() {
$files = $this->getOption( 'file', [ __DIR__ . '/parserTests.txt' ] );
$this->seed = intval( $this->getOption( 'seed', 1 ) ) - 1;
- $this->parserTest = new ParserTest;
+ $this->parserTest = new ParserTestRunner(
+ new MultiTestRecorder,
+ [] );
$this->fuzzTest( $files );
}
* @param array $filenames
*/
function fuzzTest( $filenames ) {
- $GLOBALS['wgContLang'] = Language::factory( 'en' );
$dict = $this->getFuzzInput( $filenames );
$dictSize = strlen( $dict );
$logMaxLength = log( $this->maxFuzzTestLength );
- $this->parserTest->setupDatabase();
+
+ $teardown = $this->parserTest->staticSetup();
+ $teardown = $this->parserTest->setupDatabase( $teardown );
+ $teardown = $this->parserTest->setupUploads( $teardown );
+
+ $fakeTest = [
+ 'test' => '',
+ 'desc' => '',
+ 'input' => '',
+ 'result' => '',
+ 'options' => '',
+ 'config' => ''
+ ];
+
ini_set( 'memory_limit', $this->memoryLimit * 1048576 * 2 );
$numTotal = 0;
$input .= substr( $dict, $offset, $hairLength );
}
- $this->parserTest->setupGlobals();
+ $perTestTeardown = $this->parserTest->perTestSetup( $fakeTest );
$parser = $this->parserTest->getParser();
// Run the test
}
$numTotal++;
- $this->parserTest->teardownGlobals();
- $parser->__destruct();
+ ScopedCallback::consume( $perTestTeardown );
if ( $numTotal % 100 == 0 ) {
$usage = intval( memory_get_usage( true ) / $this->memoryLimit / 1048576 * 100 );
--- /dev/null
+<?php
+/**
+ * MediaWiki parser test suite
+ *
+ * Copyright © 2004 Brion Vibber <brion@pobox.com>
+ * https://www.mediawiki.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Testing
+ */
+
+// Some methods which are discouraged for normal code throw exceptions unless
+// we declare this is just a test.
+define( 'MW_PARSER_TEST', true );
+
+require __DIR__ . '/../../maintenance/Maintenance.php';
+
+class ParserTestsMaintenance extends Maintenance {
+ function __construct() {
+ parent::__construct();
+ $this->addDescription( 'Run parser tests' );
+
+ $this->addOption( 'quick', 'Suppress diff output of failed tests' );
+ $this->addOption( 'quiet', 'Suppress notification of passed tests (shows only failed tests)' );
+ $this->addOption( 'show-output', 'Show expected and actual output' );
+ $this->addOption( 'color', '[=yes|no] Override terminal detection and force ' .
+ 'color output on or off. Use wgCommandLineDarkBg = true; if your term is dark',
+ false, true );
+ $this->addOption( 'regex', 'Only run tests whose descriptions which match given regex',
+ false, true );
+ $this->addOption( 'filter', 'Alias for --regex', false, true );
+ $this->addOption( 'file', 'Run test cases from a custom file instead of parserTests.txt',
+ false, true, false, true );
+ $this->addOption( 'record', 'Record tests in database' );
+ $this->addOption( 'compare', 'Compare with recorded results, without updating the database.' );
+ $this->addOption( 'setversion', 'When using --record, set the version string to use (useful' .
+ 'with "git rev-parse HEAD" to get the exact revision)',
+ false, true );
+ $this->addOption( 'keep-uploads', 'Re-use the same upload directory for each ' .
+ 'test, don\'t delete it' );
+ $this->addOption( 'file-backend', 'Use the file backend with the given name,' .
+ 'and upload files to it, instead of creating a mock file backend.', false, true );
+ $this->addOption( 'upload-dir', 'Specify the upload directory to use. Useful in ' .
+ 'conjunction with --keep-uploads. Causes a real (non-mock) file backend to ' .
+ 'be used.', false, true );
+ $this->addOption( 'run-disabled', 'run disabled tests' );
+ $this->addOption( 'run-parsoid', 'run parsoid tests (normally disabled)' );
+ $this->addOption( 'dwdiff', 'Use dwdiff to display diff output' );
+ $this->addOption( 'mark-ws', 'Mark whitespace in diffs by replacing it with symbols' );
+ $this->addOption( 'norm', 'Apply a comma-separated list of normalization functions to ' .
+ 'both the expected and actual output in order to resolve ' .
+ 'irrelevant differences. The accepted normalization functions ' .
+ 'are: removeTbody to remove <tbody> tags; and trimWhitespace ' .
+ 'to trim whitespace from the start and end of text nodes.',
+ false, true );
+ $this->addOption( 'use-tidy-config', 'Use the wiki\'s Tidy configuration instead of known-good' .
+ 'defaults.' );
+ }
+
+ public function finalSetup() {
+ parent::finalSetup();
+ self::requireTestsAutoloader();
+ TestSetup::applyInitialConfig();
+ }
+
+ public function execute() {
+ global $wgParserTestFiles, $wgDBtype;
+
+ // Cases of weird db corruption were encountered when running tests on earlyish
+ // versions of SQLite
+ if ( $wgDBtype == 'sqlite' ) {
+ $db = wfGetDB( DB_MASTER );
+ $version = $db->getServerVersion();
+ if ( version_compare( $version, '3.6' ) < 0 ) {
+ die( "Parser tests require SQLite version 3.6 or later, you have $version\n" );
+ }
+ }
+
+ // Print out software version to assist with locating regressions
+ $version = SpecialVersion::getVersion( 'nodb' );
+ echo "This is MediaWiki version {$version}.\n\n";
+
+ // Only colorize output if stdout is a terminal.
+ $color = !wfIsWindows() && Maintenance::posix_isatty( 1 );
+
+ if ( $this->hasOption( 'color' ) ) {
+ switch ( $this->getOption( 'color' ) ) {
+ case 'no':
+ $color = false;
+ break;
+ case 'yes':
+ default:
+ $color = true;
+ break;
+ }
+ }
+
+ $record = $this->hasOption( 'record' );
+ $compare = $this->hasOption( 'compare' );
+
+ $regex = $this->getOption( 'filter', $this->getOption( 'regex', false ) );
+ if ( $regex !== false ) {
+ $regex = "/$regex/i";
+
+ if ( $record ) {
+ echo "Warning: --record cannot be used with --regex, disabling --record\n";
+ $record = false;
+ }
+ }
+
+ $term = $color
+ ? new AnsiTermColorer()
+ : new DummyTermColorer();
+
+ $recorder = new MultiTestRecorder;
+
+ $recorder->addRecorder( new ParserTestPrinter(
+ $term,
+ [
+ 'showDiffs' => !$this->hasOption( 'quick' ),
+ 'showProgress' => !$this->hasOption( 'quiet' ),
+ 'showFailure' => !$this->hasOption( 'quiet' )
+ || ( !$record && !$compare ), // redundant output
+ 'showOutput' => $this->hasOption( 'show-output' ),
+ 'useDwdiff' => $this->hasOption( 'dwdiff' ),
+ 'markWhitespace' => $this->hasOption( 'mark-ws' ),
+ ]
+ ) );
+
+ $recorderLB = false;
+ if ( $record || $compare ) {
+ $recorderLB = wfGetLBFactory()->newMainLB();
+ // This connection will have the wiki's table prefix, not parsertest_
+ $recorderDB = $recorderLB->getConnection( DB_MASTER );
+
+ // Add recorder before previewer because recorder will create the
+ // DB table if it doesn't exist
+ if ( $record ) {
+ $recorder->addRecorder( new DbTestRecorder( $recorderDB ) );
+ }
+ $recorder->addRecorder( new DbTestPreviewer(
+ $recorderDB,
+ function ( $name ) use ( $regex ) {
+ // Filter reports of old tests by the filter regex
+ if ( $regex === false ) {
+ return true;
+ } else {
+ return (bool)preg_match( $regex, $name );
+ }
+ } ) );
+ }
+
+ // Default parser tests and any set from extensions or local config
+ $files = $this->getOption( 'file', $wgParserTestFiles );
+
+ $norm = $this->hasOption( 'norm' ) ? explode( ',', $this->getOption( 'norm' ) ) : [];
+
+ $tester = new ParserTestRunner( $recorder, [
+ 'norm' => $norm,
+ 'regex' => $regex,
+ 'keep-uploads' => $this->hasOption( 'keep-uploads' ),
+ 'run-disabled' => $this->hasOption( 'run-disabled' ),
+ 'run-parsoid' => $this->hasOption( 'run-parsoid' ),
+ 'use-tidy-config' => $this->hasOption( 'use-tidy-config' ),
+ 'file-backend' => $this->getOption( 'file-backend' ),
+ 'upload-dir' => $this->getOption( 'upload-dir' ),
+ ] );
+
+ $ok = $tester->runTestsFromFiles( $files );
+ if ( $recorderLB ) {
+ $recorderLB->closeAll();
+ }
+ if ( !$ok ) {
+ exit( 1 );
+ }
+ }
+}
+
+$maintClass = 'ParserTestsMaintenance';
+require_once RUN_MAINTENANCE_IF_MAIN;
#
# You can also set the following parser properties via test options:
# wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel,
-# wgLinkHolderBatchSize, wgRawHtml, wgInterwikiMagic
+# wgLinkHolderBatchSize, wgRawHtml, wgInterwikiMagic,
+# wgEnableMagicLinks
#
# For testing purposes, temporary articles can created:
# !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle
| c</pre>
!!end
+!! test
+2g. Indented table markup mixed with indented pre content (proposed in bug 6200)
+!! wikitext
+ <table>
+ <tr>
+ <td>
+ Text that should be rendered preformatted
+ </td>
+ </tr>
+ </table>
+!! html
+ <table>
+ <tr>
+ <td>
+<pre>Text that should be rendered preformatted
+</pre>
+ </td>
+ </tr>
+ </table>
+
+!! end
+
!!test
3a. Indent-Pre and block tags (single-line html)
!! wikitext
<span typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"ho\">ha</div>"}},"i":0}}]}'>ho">ha</span>
!! end
+## We don't support roundtripping of these attributes in Parsoid.
+## Selective serialization takes care of preventing dirty diffs.
+## But, on edits, we dirty-diff the invalid attribute text.
!! test
-Indented table markup mixed with indented pre content (proposed in bug 6200)
+Invalid text in table attributes should be discarded
+!! options
+parsoid=wt2html
!! wikitext
- <table>
- <tr>
- <td>
- Text that should be rendered preformatted
- </td>
- </tr>
- </table>
-!! html
- <table>
- <tr>
- <td>
-<pre>Text that should be rendered preformatted
-</pre>
- </td>
- </tr>
- </table>
+{| <span>boo</span> style='border:1px solid black'
+| <span>boo</span> style='color:blue' | 1
+|<span>boo</span> style='color:blue'| 2
+|}
+!! html/php
+<table style="border:1px solid black">
+<tr>
+<td style="color:blue"> 1
+</td>
+<td style="color:blue"> 2
+</td></tr></table>
+!! html/parsoid
+<table style="border:1px solid black">
+<tr>
+<td style="color:blue"> 1</td>
+<td style="color:blue"> 2</td>
+</tr>
+</table>
+!! end
+
+!! test
+Invalid text in table attributes should be preserved by selective serializer
+!! options
+parsoid={
+ "modes": ["selser"],
+ "changes": [
+ ["td:first-child", "text", "abc"],
+ ["td + td", "text", "xyz"]
+ ]
+}
+!! wikitext
+{| <span>boo</span> style='border:1px solid black'
+| <span>boo</span> style='color:blue' | 1
+|<span>boo</span> style='color:blue'| 2
+|}
+!! wikitext/edited
+{| <span>boo</span> style='border:1px solid black'
+| <span>boo</span> style='color:blue' |abc
+|<span>boo</span> style='color:blue'|xyz
+|}
!! end
!! test
<p><a rel="mw:WikiLink" href="./User:Test/123" title="User:Test/123" data-parsoid='{"stx":"simple","a":{"href":"./User:Test/123"},"sa":{"href":"/123"}}'>/123</a></p>
!! end
+!! test
+Ensure that transclusion titles are not url-decoded
+!! options
+subpage title=[[Test]]
+parsoid=wt2html
+!! wikitext
+{{Bar%C3%A9}} {{/Bar%C3%A9}}
+!! html/php
+<p>{{Bar%C3%A9}} {{/Bar%C3%A9}}
+</p>
+!! html/parsoid
+<p>{{Bar%C3%A9}} {{/Bar%C3%A9}}</p>
+!! end
+
!! test
Purely hash wikilink
!! options
<p>X<a rel="mw:ExtLink" href="//tools.ietf.org/html/rfc1234">foo</a></p>
!! end
+!! test
+Magic links: All disabled (T47942)
+!! options
+wgEnableMagicLinks={"ISBN":false, "PMID":false, "RFC":false}
+!! wikitext
+ISBN 0-306-40615-2
+PMID 1234
+RFC 4321
+!! html/php
+<p>ISBN 0-306-40615-2
+PMID 1234
+RFC 4321
+</p>
+!! end
+
###
### Templates
####
!! wikitext
[[Category:MediaWiki User's Guide]]
!! html
-<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a>
+cat=MediaWiki_User's_Guide sort=
!! end
!! test
!! wikitext
[[Category:MediaWiki User's Guide|Foo]]
!! html
-<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a>
+cat=MediaWiki_User's_Guide sort=Foo
!! end
!! test
!! wikitext
[[Category:MediaWiki User's Guide|MediaWiki User's Guide]]
!! html
-<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a>
+cat=MediaWiki_User's_Guide sort=MediaWiki User's Guide
!! end
!! test
parsoid=wt2html
!! wikitext
{{../../../../More than parent}}
-!! html
+!! html/php
<p>{{../../../../More than parent}}
</p>
+!! html/parsoid
+<p>{{../../../../More than parent}}</p>
!! end
!! test
!! wikitext
[[Category:МедиаWики Усер'с Гуиде]]
!! html
-<a href="/wiki/%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%98%D0%B0:MediaWiki_User%27s_Guide" title="Категорија:MediaWiki User's Guide">MediaWiki User's Guide</a>
+cat=МедиаWики_Усер'с_Гуиде sort=
!! end
!! wikitext
[[A]][[Category:分类]]
!! html/php
-<a href="/wiki/Category:%E5%88%86%E7%B1%BB" title="Category:分类">分类</a>
+cat=分类 sort=
!! html/parsoid
<p><a rel="mw:WikiLink" href="A" title="A">A</a></p>
<link rel="mw:PageProp/Category" href="Category:分类"/>
unclosed internal link XSS (T137264)
!! wikitext
[[#%3Cscript%3Ealert(1)%3C/script%3E|
-!! html
+!! html/php
<p>[[#<script>alert(1)</script>|
</p>
+!! html/parsoid
+<p>[[#%3Cscript%3Ealert(1)%3C/script%3E|</p>
!! end
+++ /dev/null
-<?php
-/**
- * MediaWiki parser test suite
- *
- * Copyright © 2004 Brion Vibber <brion@pobox.com>
- * https://www.mediawiki.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Testing
- */
-
-define( 'MW_PARSER_TEST', true );
-
-$options = [ 'quick', 'color', 'quiet', 'help', 'show-output',
- 'record', 'run-disabled', 'run-parsoid', 'dwdiff', 'mark-ws' ];
-$optionsWithArgs = [ 'regex', 'filter', 'seed', 'setversion', 'file', 'norm' ];
-
-require_once __DIR__ . '/../maintenance/commandLine.inc';
-require_once __DIR__ . '/TestsAutoLoader.php';
-
-if ( isset( $options['help'] ) ) {
- echo <<<ENDS
-MediaWiki $wgVersion parser test suite
-Usage: php parserTests.php [options...]
-
-Options:
- --quick Suppress diff output of failed tests
- --quiet Suppress notification of passed tests (shows only failed tests)
- --show-output Show expected and actual output
- --color[=yes|no] Override terminal detection and force color output on or off
- use wgCommandLineDarkBg = true; if your term is dark
- --regex Only run tests whose descriptions which match given regex
- --filter Alias for --regex
- --file=<testfile> Run test cases from a custom file instead of parserTests.txt
- --record Record tests in database
- --compare Compare with recorded results, without updating the database.
- --setversion When using --record, set the version string to use (useful
- with git-svn so that you can get the exact revision)
- --keep-uploads Re-use the same upload directory for each test, don't delete it
- --run-disabled run disabled tests
- --run-parsoid run parsoid tests (normally disabled)
- --dwdiff Use dwdiff to display diff output
- --mark-ws Mark whitespace in diffs by replacing it with symbols
- --norm=<funcs> Apply a comma-separated list of normalization functions to
- both the expected and actual output in order to resolve
- irrelevant differences. The accepted normalization functions
- are: removeTbody to remove <tbody> tags; and trimWhitespace
- to trim whitespace from the start and end of text nodes.
- --use-tidy-config Use the wiki's Tidy configuration instead of known-good
- defaults.
- --help Show this help message
-
-ENDS;
- exit( 0 );
-}
-
-# Cases of weird db corruption were encountered when running tests on earlyish
-# versions of SQLite
-if ( $wgDBtype == 'sqlite' ) {
- $db = wfGetDB( DB_MASTER );
- $version = $db->getServerVersion();
- if ( version_compare( $version, '3.6' ) < 0 ) {
- die( "Parser tests require SQLite version 3.6 or later, you have $version\n" );
- }
-}
-
-$tester = new ParserTest( $options );
-
-if ( isset( $options['file'] ) ) {
- $files = [ $options['file'] ];
-} else {
- // Default parser tests and any set from extensions or local config
- $files = $wgParserTestFiles;
-}
-
-# Print out software version to assist with locating regressions
-$version = SpecialVersion::getVersion( 'nodb' );
-echo "This is MediaWiki version {$version}.\n\n";
-
-$ok = $tester->runTestsFromFiles( $files );
-exit( $ok ? 0 : 1 );
parser:
${PU} --group Parser
-parserfuzz:
- @echo "******************************************************************"
- @echo "* This WILL kill your computer by eating all memory AND all swap *"
- @echo "* *"
- @echo "* If you are on a production machine. ABORT NOW!! *"
- @echo "* Press control+C to stop *"
- @echo "* *"
- @echo "******************************************************************"
- ${PU} --group Parser,ParserFuzz
noparser:
- ${PU} --exclude-group Parser,Broken,ParserFuzz,Stub
+ ${PU} --exclude-group Parser,Broken,Stub
safe:
- ${PU} --exclude-group Broken,ParserFuzz,Destructive,Stub
+ ${PU} --exclude-group Broken,Destructive,Stub
databaseless:
- ${PU} --exclude-group Broken,ParserFuzz,Destructive,Database,Stub
+ ${PU} --exclude-group Broken,Destructive,Database,Stub
database:
- ${PU} --exclude-group Broken,ParserFuzz,Destructive,Stub --group Database
+ ${PU} --exclude-group Broken,Destructive,Stub --group Database
list-groups:
${PU} --list-groups
public static function setUpBeforeClass() {
parent::setUpBeforeClass();
- // NOTE: Usually, PHPUnitMaintClass::finalSetup already called this,
- // but let's make doubly sure.
- self::prepareServices( new GlobalVarConfig() );
+ // Get the service locator, and reset services if it's not done already
+ self::$serviceLocator = self::prepareServices( new GlobalVarConfig() );
}
/**
*
* @param Config $bootstrapConfig The bootstrap config to use with the new
* MediaWikiServices. Only used for the first call to this method.
+ * @return MediaWikiServices
*/
public static function prepareServices( Config $bootstrapConfig ) {
- static $servicesPrepared = false;
+ static $services = null;
- if ( $servicesPrepared ) {
- return;
- } else {
- $servicesPrepared = true;
+ if ( !$services ) {
+ $services = self::resetGlobalServices( $bootstrapConfig );
}
-
- self::resetGlobalServices( $bootstrapConfig );
+ return $services;
}
/**
* Reset global services, and install testing environment.
* This is the testing equivalent of MediaWikiServices::resetGlobalInstance().
* This should only be used to set up the testing environment, not when
- * running unit tests. Use overrideMwServices() for that.
+ * running unit tests. Use MediaWikiTestCase::overrideMwServices() for that.
*
* @see MediaWikiServices::resetGlobalInstance()
* @see prepareServices()
- * @see overrideMwServices()
+ * @see MediaWikiTestCase::overrideMwServices()
*
* @param Config|null $bootstrapConfig The bootstrap config to use with the new
* MediaWikiServices.
MediaWikiServices::resetGlobalInstance( $testConfig );
- self::$serviceLocator = MediaWikiServices::getInstance();
+ $serviceLocator = MediaWikiServices::getInstance();
self::installTestServices(
$oldConfigFactory,
- self::$serviceLocator
+ $serviceLocator
);
+ return $serviceLocator;
}
/**
* @throws MWException If the database table prefix is already $prefix
*/
public static function setupTestDB( DatabaseBase $db, $prefix ) {
+ if ( self::$dbSetup ) {
+ return;
+ }
+
if ( $db->tablePrefix() === $prefix ) {
throw new MWException(
'Cannot run unit tests, the database prefix is already "' . $prefix . '"' );
}
- if ( self::$dbSetup ) {
- return;
- }
-
// TODO: the below should be re-written as soon as LBFactory, LoadBalancer,
// and DatabaseBase no longer use global state.
--- /dev/null
+<?php
+
+/**
+ * Test class for ReverseChronologicalPagerTest methods.
+ *
+ * @group Pager
+ *
+ * @author Geoffrey Mon <geofbot@gmail.com>
+ */
+class ReverseChronologicalPagerTest extends MediaWikiLangTestCase {
+
+ /**
+ * @covers ReverseChronologicalPager::getDateCond
+ */
+ public function testGetDateCond() {
+ $pager = $this->getMockForAbstractClass( 'ReverseChronologicalPager' );
+ $timestamp = MWTimestamp::getInstance();
+ $db = wfGetDB( DB_MASTER );
+
+ $currYear = $timestamp->format( 'Y' );
+ $currMonth = $timestamp->format( 'n' );
+ $currYearTimestamp = $db->timestamp( $currYear + 1 . '0101000000' );
+
+ // Test that getDateCond sets and returns mOffset
+ $this->assertEquals( $pager->getDateCond( 2006 ), $pager->mOffset );
+
+ // Test year
+ $pager->getDateCond( 2006 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+ // Test year and month
+ $pager->getDateCond( 2006, 6 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20060701000000' ) );
+
+ // Test year, month, and day
+ $pager->getDateCond( 2006, 6, 5 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20060606000000' ) );
+
+ // Test month overflow into the next year
+ $pager->getDateCond( 2006, 12 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+ // Test day overflow to the next month
+ $pager->getDateCond( 2006, 6, 30 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20060701000000' ) );
+
+ // Test invalid year (should use current year)
+ $pager->getDateCond( -1337 );
+ $this->assertEquals( $pager->mOffset, $currYearTimestamp );
+
+ // Test invalid month
+ $pager->getDateCond( 2006, -1 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+ // Test invalid day
+ $pager->getDateCond( 2006, 6, 1337 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20060701000000' ) );
+
+ // Test no year or month (should use end of current year)
+ $pager->getDateCond();
+ $this->assertEquals( $pager->mOffset, $currYearTimestamp );
+
+ // Test last day of year
+ $pager->getDateCond( 2006, 12, 31 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+ // Test invalid day that overflows to next year
+ $pager->getDateCond( 2006, 12, 32 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( '20070101000000' ) );
+
+ // Test month past current month (should use previous year)
+ if ( $currMonth < 5 ) {
+ $pager->getDateCond( -1, 5 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( $currYear - 1 . '0601000000' ) );
+ }
+ if ( $currMonth < 12 ) {
+ $pager->getDateCond( -1, 12 );
+ $this->assertEquals( $pager->mOffset, $db->timestamp( $currYear . '0101000000' ) );
+ }
+ }
+}
+
+++ /dev/null
-<?php
-require_once __DIR__ . '/NewParserTest.php';
-
-/**
- * The UnitTest must be either a class that inherits from MediaWikiTestCase
- * or a class that provides a public static suite() method which returns
- * an PHPUnit_Framework_Test object
- *
- * @group Parser
- * @group ParserTests
- * @group Database
- */
-class MediaWikiParserTest {
-
- /**
- * @defgroup filtering_constants Filtering constants
- *
- * Limit inclusion of parser tests files coming from MediaWiki core
- * @{
- */
-
- /** Include files shipped with MediaWiki core */
- const CORE_ONLY = 1;
- /** Include non core files as set in $wgParserTestFiles */
- const NO_CORE = 2;
- /** Include anything set via $wgParserTestFiles */
- const WITH_ALL = 3; # CORE_ONLY | NO_CORE
-
- /** @} */
-
- /**
- * Get a PHPUnit test suite of parser tests. Optionally filtered with
- * $flags.
- *
- * @par Examples:
- * Get a suite of parser tests shipped by MediaWiki core:
- * @code
- * MediaWikiParserTest::suite( MediaWikiParserTest::CORE_ONLY );
- * @endcode
- * Get a suite of various parser tests, like extensions:
- * @code
- * MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE );
- * @endcode
- * Get any test defined via $wgParserTestFiles:
- * @code
- * MediaWikiParserTest::suite( MediaWikiParserTest::WITH_ALL );
- * @endcode
- *
- * @param int $flags Bitwise flag to filter out the $wgParserTestFiles that
- * will be included. Default: MediaWikiParserTest::CORE_ONLY
- *
- * @return PHPUnit_Framework_TestSuite
- */
- public static function suite( $flags = self::CORE_ONLY ) {
- if ( is_string( $flags ) ) {
- $flags = self::CORE_ONLY;
- }
- global $wgParserTestFiles, $IP;
-
- $mwTestDir = $IP . '/tests/';
-
- # Human friendly helpers
- $wantsCore = ( $flags & self::CORE_ONLY );
- $wantsRest = ( $flags & self::NO_CORE );
-
- # Will hold the .txt parser test files we will include
- $filesToTest = [];
-
- # Filter out .txt files
- foreach ( $wgParserTestFiles as $parserTestFile ) {
- $isCore = ( 0 === strpos( $parserTestFile, $mwTestDir ) );
-
- if ( $isCore && $wantsCore ) {
- self::debug( "included core parser tests: $parserTestFile" );
- $filesToTest[] = $parserTestFile;
- } elseif ( !$isCore && $wantsRest ) {
- self::debug( "included non core parser tests: $parserTestFile" );
- $filesToTest[] = $parserTestFile;
- } else {
- self::debug( "skipped parser tests: $parserTestFile" );
- }
- }
- self::debug( 'parser tests files: '
- . implode( ' ', $filesToTest ) );
-
- $suite = new PHPUnit_Framework_TestSuite;
- $testList = [];
- $counter = 0;
- foreach ( $filesToTest as $fileName ) {
- // Call the highest level directory the extension name.
- // It may or may not actually be, but it should be close
- // enough to cause there to be separate names for different
- // things, which is good enough for our purposes.
- $extensionName = basename( dirname( $fileName ) );
- $testsName = $extensionName . '__' . basename( $fileName, '.txt' );
- $escapedFileName = strtr( $fileName, [ "'" => "\\'", '\\' => '\\\\' ] );
- $parserTestClassName = ucfirst( $testsName );
-
- // Official spec for class names: http://php.net/manual/en/language.oop5.basic.php
- // Prepend 'ParserTest_' to be paranoid about it not starting with a number
- $parserTestClassName = 'ParserTest_' .
- preg_replace( '/[^a-zA-Z0-9_\x7f-\xff]/', '_', $parserTestClassName );
-
- if ( isset( $testList[$parserTestClassName] ) ) {
- // If a conflict happens, gives a very unclear fatal.
- // So as a last ditch effort to prevent that eventuality, if there
- // is a conflict, append a number.
- $counter++;
- $parserTestClassName .= $counter;
- }
- $testList[$parserTestClassName] = true;
- $parserTestClassDefinition = <<<EOT
-/**
- * @group Database
- * @group Parser
- * @group ParserTests
- * @group ParserTests_$parserTestClassName
- */
-class $parserTestClassName extends NewParserTest {
- protected \$file = '$escapedFileName';
-}
-EOT;
-
- eval( $parserTestClassDefinition );
- self::debug( "Adding test class $parserTestClassName" );
- $suite->addTestSuite( $parserTestClassName );
- }
- return $suite;
- }
-
- /**
- * Write $msg under log group 'tests-parser'
- * @param string $msg Message to log
- */
- protected static function debug( $msg ) {
- return wfDebugLog( 'tests-parser', wfGetCaller() . ' ' . $msg );
- }
-}
+++ /dev/null
-<?php
-
-use MediaWiki\MediaWikiServices;
-
-/**
- * Although marked as a stub, can work independently.
- *
- * @group Database
- * @group Parser
- * @group Stub
- *
- * @todo covers tags
- */
-class NewParserTest extends MediaWikiTestCase {
- static protected $articles = []; // Array of test articles defined by the tests
- /* The data provider is run on a different instance than the test, so it must be static
- * When running tests from several files, all tests will see all articles.
- */
- static protected $backendToUse;
-
- public $keepUploads = false;
- public $runDisabled = false;
- public $runParsoid = false;
- public $regex = '';
- public $showProgress = true;
- public $savedWeirdGlobals = [];
- public $savedGlobals = [];
- public $hooks = [];
- public $functionHooks = [];
- public $transparentHooks = [];
-
- /**
- * @var DjVuSupport
- */
- private $djVuSupport;
- /**
- * @var TidySupport
- */
- private $tidySupport;
-
- protected $file = false;
-
- public static function setUpBeforeClass() {
- // Inject ParserTest well-known interwikis
- ParserTest::setupInterwikis();
- }
-
- protected function setUp() {
- global $wgNamespaceAliases, $wgContLang;
- global $wgHooks, $IP;
-
- parent::setUp();
-
- // Setup CLI arguments
- if ( $this->getCliArg( 'regex' ) ) {
- $this->regex = $this->getCliArg( 'regex' );
- } else {
- # Matches anything
- $this->regex = '';
- }
-
- $this->keepUploads = $this->getCliArg( 'keep-uploads' );
-
- $tmpGlobals = [];
-
- $tmpGlobals['wgLanguageCode'] = 'en';
- $tmpGlobals['wgContLang'] = Language::factory( 'en' );
- $tmpGlobals['wgSitename'] = 'MediaWiki';
- $tmpGlobals['wgServer'] = 'http://example.org';
- $tmpGlobals['wgServerName'] = 'example.org';
- $tmpGlobals['wgScriptPath'] = '';
- $tmpGlobals['wgScript'] = '/index.php';
- $tmpGlobals['wgResourceBasePath'] = '';
- $tmpGlobals['wgStylePath'] = '/skins';
- $tmpGlobals['wgExtensionAssetsPath'] = '/extensions';
- $tmpGlobals['wgArticlePath'] = '/wiki/$1';
- $tmpGlobals['wgActionPaths'] = [];
- $tmpGlobals['wgVariantArticlePath'] = false;
- $tmpGlobals['wgEnableUploads'] = true;
- $tmpGlobals['wgUploadNavigationUrl'] = false;
- $tmpGlobals['wgThumbnailScriptPath'] = false;
- $tmpGlobals['wgLocalFileRepo'] = [
- 'class' => 'LocalRepo',
- 'name' => 'local',
- 'url' => 'http://example.com/images',
- 'hashLevels' => 2,
- 'transformVia404' => false,
- 'backend' => 'local-backend'
- ];
- $tmpGlobals['wgForeignFileRepos'] = [];
- $tmpGlobals['wgDefaultExternalStore'] = [];
- $tmpGlobals['wgParserCacheType'] = CACHE_NONE;
- $tmpGlobals['wgCapitalLinks'] = true;
- $tmpGlobals['wgNoFollowLinks'] = true;
- $tmpGlobals['wgNoFollowDomainExceptions'] = [ 'no-nofollow.org' ];
- $tmpGlobals['wgExternalLinkTarget'] = false;
- $tmpGlobals['wgThumbnailScriptPath'] = false;
- $tmpGlobals['wgUseImageResize'] = true;
- $tmpGlobals['wgAllowExternalImages'] = true;
- $tmpGlobals['wgRawHtml'] = false;
- $tmpGlobals['wgExperimentalHtmlIds'] = false;
- $tmpGlobals['wgAdaptiveMessageCache'] = true;
- $tmpGlobals['wgUseDatabaseMessages'] = true;
- $tmpGlobals['wgLocaltimezone'] = 'UTC';
- $tmpGlobals['wgGroupPermissions'] = [
- '*' => [
- 'createaccount' => true,
- 'read' => true,
- 'edit' => true,
- 'createpage' => true,
- 'createtalk' => true,
- ] ];
- $tmpGlobals['wgNamespaceProtection'] = [ NS_MEDIAWIKI => 'editinterface' ];
-
- $tmpGlobals['wgParser'] = new StubObject(
- 'wgParser', $GLOBALS['wgParserConf']['class'],
- [ $GLOBALS['wgParserConf'] ] );
-
- $tmpGlobals['wgFileExtensions'][] = 'svg';
- $tmpGlobals['wgSVGConverter'] = 'rsvg';
- $tmpGlobals['wgSVGConverters']['rsvg'] =
- '$path/rsvg-convert -w $width -h $height -o $output $input';
-
- if ( $GLOBALS['wgStyleDirectory'] === false ) {
- $tmpGlobals['wgStyleDirectory'] = "$IP/skins";
- }
-
- $tmpHooks = $wgHooks;
- $tmpHooks['ParserTestParser'][] = 'ParserTestParserHook::setup';
- $tmpHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp';
- $tmpGlobals['wgHooks'] = $tmpHooks;
- # add a namespace shadowing a interwiki link, to test
- # proper precedence when resolving links. (bug 51680)
- $tmpGlobals['wgExtraNamespaces'] = [
- 100 => 'MemoryAlpha',
- 101 => 'MemoryAlpha_talk'
- ];
-
- $tmpGlobals['wgLocalInterwikis'] = [ 'local', 'mi' ];
- # "extra language links"
- # see https://gerrit.wikimedia.org/r/111390
- $tmpGlobals['wgExtraInterlanguageLinkPrefixes'] = [ 'mul' ];
-
- // DjVu support
- $this->djVuSupport = new DjVuSupport();
- // Tidy support
- $this->tidySupport = new TidySupport();
- $tmpGlobals['wgTidyConfig'] = $this->tidySupport->getConfig();
- $tmpGlobals['wgUseTidy'] = false;
-
- $this->setMwGlobals( $tmpGlobals );
-
- $this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image'];
- $this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk'];
-
- $wgNamespaceAliases['Image'] = NS_FILE;
- $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK;
-
- MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
- $wgContLang->resetNamespaces(); # reset namespace cache
- ParserTest::resetTitleServices();
- MediaWikiServices::getInstance()->disableService( 'MediaHandlerFactory' );
- MediaWikiServices::getInstance()->redefineService(
- 'MediaHandlerFactory',
- function() {
- return new MockMediaHandlerFactory();
- }
- );
- }
-
- protected function tearDown() {
- global $wgNamespaceAliases, $wgContLang;
-
- $wgNamespaceAliases['Image'] = $this->savedWeirdGlobals['image_alias'];
- $wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias'];
-
- MWTidy::destroySingleton();
-
- // Restore backends
- RepoGroup::destroySingleton();
- FileBackendGroup::destroySingleton();
-
- // Remove temporary pages from the link cache
- LinkCache::singleton()->clear();
-
- // Restore message cache (temporary pages and $wgUseDatabaseMessages)
- MessageCache::destroyInstance();
- MediaWikiServices::getInstance()->resetServiceForTesting( 'MediaHandlerFactory' );
-
- parent::tearDown();
-
- MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
- $wgContLang->resetNamespaces(); # reset namespace cache
- }
-
- public static function tearDownAfterClass() {
- ParserTest::tearDownInterwikis();
- parent::tearDownAfterClass();
- }
-
- function addDBDataOnce() {
- # disabled for performance
- # $this->tablesUsed[] = 'image';
-
- # Update certain things in site_stats
- $this->db->insert( 'site_stats',
- [ 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ],
- __METHOD__,
- [ 'IGNORE' ]
- );
-
- $user = User::newFromId( 0 );
- LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision
-
- # Upload DB table entries for files.
- # We will upload the actual files later. Note that if anything causes LocalFile::load()
- # to be triggered before then, it will break via maybeUpgrade() setting the fileExists
- # member to false and storing it in cache.
- # note that the size/width/height/bits/etc of the file
- # are actually set by inspecting the file itself; the arguments
- # to recordUpload2 have no effect. That said, we try to make things
- # match up so it is less confusing to readers of the code & tests.
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
- if ( !$this->db->selectField( 'image', '1', [ 'img_name' => $image->getName() ] ) ) {
- $image->recordUpload2(
- '', // archive name
- 'Upload of some lame file',
- 'Some lame file',
- [
- 'size' => 7881,
- 'width' => 1941,
- 'height' => 220,
- 'bits' => 8,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/jpeg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '1', 16, 36, 31 ),
- 'fileExists' => true ],
- $this->db->timestamp( '20010115123500' ), $user
- );
- }
-
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Thumb.png' ) );
- if ( !$this->db->selectField( 'image', '1', [ 'img_name' => $image->getName() ] ) ) {
- $image->recordUpload2(
- '', // archive name
- 'Upload of some lame thumbnail',
- 'Some lame thumbnail',
- [
- 'size' => 22589,
- 'width' => 135,
- 'height' => 135,
- 'bits' => 8,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/png',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '2', 16, 36, 31 ),
- 'fileExists' => true ],
- $this->db->timestamp( '20130225203040' ), $user
- );
- }
-
- # This image will be blacklisted in [[MediaWiki:Bad image list]]
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) );
- if ( !$this->db->selectField( 'image', '1', [ 'img_name' => $image->getName() ] ) ) {
- $image->recordUpload2(
- '', // archive name
- 'zomgnotcensored',
- 'Borderline image',
- [
- 'size' => 12345,
- 'width' => 320,
- 'height' => 240,
- 'bits' => 24,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/jpeg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '3', 16, 36, 31 ),
- 'fileExists' => true ],
- $this->db->timestamp( '20010115123500' ), $user
- );
- }
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.svg' ) );
- if ( !$this->db->selectField( 'image', '1', [ 'img_name' => $image->getName() ] ) ) {
- $image->recordUpload2( '', 'Upload of some lame SVG', 'Some lame SVG', [
- 'size' => 12345,
- 'width' => 240,
- 'height' => 180,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_DRAWING,
- 'mime' => 'image/svg+xml',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
- }
-
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Video.ogv' ) );
- if ( !$this->db->selectField( 'image', '1', [ 'img_name' => $image->getName() ] ) ) {
- $image->recordUpload2( '', 'A pretty movie', 'Will it play', [
- 'size' => 12345,
- 'width' => 320,
- 'height' => 240,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_VIDEO,
- 'mime' => 'application/ogg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 32 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
- }
-
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Audio.oga' ) );
- if ( !$this->db->selectField( 'image', '1', [ 'img_name' => $image->getName() ] ) ) {
- $image->recordUpload2( '', 'An awesome hitsong ', 'Will it play', [
- 'size' => 12345,
- 'width' => 0,
- 'height' => 0,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_AUDIO,
- 'mime' => 'application/ogg',
- 'metadata' => serialize( [] ),
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 32 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20010115123500' ), $user );
- }
-
- # A DjVu file
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'LoremIpsum.djvu' ) );
- if ( !$this->db->selectField( 'image', '1', [ 'img_name' => $image->getName() ] ) ) {
- $image->recordUpload2( '', 'Upload a DjVu', 'A DjVu', [
- 'size' => 3249,
- 'width' => 2480,
- 'height' => 3508,
- 'bits' => 0,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/vnd.djvu',
- 'metadata' => '<?xml version="1.0" ?>
-<!DOCTYPE DjVuXML PUBLIC "-//W3C//DTD DjVuXML 1.1//EN" "pubtext/DjVuXML-s.dtd">
-<DjVuXML>
-<HEAD></HEAD>
-<BODY><OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-<OBJECT height="3508" width="2480">
-<PARAM name="DPI" value="300" />
-<PARAM name="GAMMA" value="2.2" />
-</OBJECT>
-</BODY>
-</DjVuXML>',
- 'sha1' => Wikimedia\base_convert( '', 16, 36, 31 ),
- 'fileExists' => true
- ], $this->db->timestamp( '20140115123600' ), $user );
- }
- }
-
- // ParserTest setup/teardown functions
-
- /**
- * Set up the global variables for a consistent environment for each test.
- * Ideally this should replace the global configuration entirely.
- * @param array $opts
- * @param string $config
- * @return RequestContext
- */
- protected function setupGlobals( $opts = [], $config = '' ) {
- global $wgFileBackends;
- # Find out values for some special options.
- $lang =
- self::getOptionValue( 'language', $opts, 'en' );
- $variant =
- self::getOptionValue( 'variant', $opts, false );
- $maxtoclevel =
- self::getOptionValue( 'wgMaxTocLevel', $opts, 999 );
- $linkHolderBatchSize =
- self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 );
-
- $uploadDir = $this->getUploadDir();
- if ( $this->getCliArg( 'use-filebackend' ) ) {
- if ( self::$backendToUse ) {
- $backend = self::$backendToUse;
- } else {
- $name = $this->getCliArg( 'use-filebackend' );
- $useConfig = [];
- foreach ( $wgFileBackends as $conf ) {
- if ( $conf['name'] == $name ) {
- $useConfig = $conf;
- }
- }
- $useConfig['name'] = 'local-backend'; // swap name
- unset( $useConfig['lockManager'] );
- unset( $useConfig['fileJournal'] );
- $class = $useConfig['class'];
- self::$backendToUse = new $class( $useConfig );
- $backend = self::$backendToUse;
- }
- } else {
- # Replace with a mock. We do not care about generating real
- # files on the filesystem, just need to expose the file
- # informations.
- $backend = new MockFileBackend( [
- 'name' => 'local-backend',
- 'wikiId' => wfWikiID()
- ] );
- }
-
- $settings = [
- 'wgLocalFileRepo' => [
- 'class' => 'LocalRepo',
- 'name' => 'local',
- 'url' => 'http://example.com/images',
- 'hashLevels' => 2,
- 'transformVia404' => false,
- 'backend' => $backend
- ],
- 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
- 'wgLanguageCode' => $lang,
- 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_',
- 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ),
- 'wgNamespacesWithSubpages' => [ NS_MAIN => isset( $opts['subpage'] ) ],
- 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ),
- 'wgThumbLimits' => [ self::getOptionValue( 'thumbsize', $opts, 180 ) ],
- 'wgMaxTocLevel' => $maxtoclevel,
- 'wgUseTeX' => isset( $opts['math'] ) || isset( $opts['texvc'] ),
- 'wgMathDirectory' => $uploadDir . '/math',
- 'wgDefaultLanguageVariant' => $variant,
- 'wgLinkHolderBatchSize' => $linkHolderBatchSize,
- 'wgUseTidy' => false,
- 'wgTidyConfig' => isset( $opts['tidy'] ) ? $this->tidySupport->getConfig() : null
- ];
-
- if ( $config ) {
- $configLines = explode( "\n", $config );
-
- foreach ( $configLines as $line ) {
- list( $var, $value ) = explode( '=', $line, 2 );
-
- $settings[$var] = eval( "return $value;" ); // ???
- }
- }
-
- $this->savedGlobals = [];
-
- /** @since 1.20 */
- Hooks::run( 'ParserTestGlobals', [ &$settings ] );
-
- $langObj = Language::factory( $lang );
- $settings['wgContLang'] = $langObj;
- $settings['wgLang'] = $langObj;
-
- $context = new RequestContext();
- $settings['wgOut'] = $context->getOutput();
- $settings['wgUser'] = $context->getUser();
- $settings['wgRequest'] = $context->getRequest();
-
- // We (re)set $wgThumbLimits to a single-element array above.
- $context->getUser()->setOption( 'thumbsize', 0 );
-
- foreach ( $settings as $var => $val ) {
- if ( array_key_exists( $var, $GLOBALS ) ) {
- $this->savedGlobals[$var] = $GLOBALS[$var];
- }
-
- $GLOBALS[$var] = $val;
- }
-
- MWTidy::destroySingleton();
- MagicWord::clearCache();
-
- # The entries saved into RepoGroup cache with previous globals will be wrong.
- RepoGroup::destroySingleton();
- FileBackendGroup::destroySingleton();
-
- # Create dummy files in storage
- $this->setupUploads();
-
- # Publish the articles after we have the final language set
- $this->publishTestArticles();
-
- MessageCache::destroyInstance();
-
- return $context;
- }
-
- /**
- * Get an FS upload directory (only applies to FSFileBackend)
- *
- * @return string The directory
- */
- protected function getUploadDir() {
- if ( $this->keepUploads ) {
- // Don't use getNewTempDirectory() as this is meant to persist
- $dir = wfTempDir() . '/mwParser-images';
-
- if ( is_dir( $dir ) ) {
- return $dir;
- }
- } else {
- $dir = $this->getNewTempDirectory();
- }
-
- if ( file_exists( $dir ) ) {
- wfDebug( "Already exists!\n" );
-
- return $dir;
- }
-
- return $dir;
- }
-
- /**
- * Create a dummy uploads directory which will contain a couple
- * of files in order to pass existence tests.
- *
- * @return string The directory
- */
- protected function setupUploads() {
- global $IP;
-
- $base = $this->getBaseDir();
- $backend = RepoGroup::singleton()->getLocalRepo()->getBackend();
- $backend->prepare( [ 'dir' => "$base/local-public/3/3a" ] );
- $backend->store( [
- 'src' => "$IP/tests/phpunit/data/parser/headbg.jpg",
- 'dst' => "$base/local-public/3/3a/Foobar.jpg"
- ] );
- $backend->prepare( [ 'dir' => "$base/local-public/e/ea" ] );
- $backend->store( [
- 'src' => "$IP/tests/phpunit/data/parser/wiki.png",
- 'dst' => "$base/local-public/e/ea/Thumb.png"
- ] );
- $backend->prepare( [ 'dir' => "$base/local-public/0/09" ] );
- $backend->store( [
- 'src' => "$IP/tests/phpunit/data/parser/headbg.jpg",
- 'dst' => "$base/local-public/0/09/Bad.jpg"
- ] );
- $backend->prepare( [ 'dir' => "$base/local-public/5/5f" ] );
- $backend->store( [
- 'src' => "$IP/tests/phpunit/data/parser/LoremIpsum.djvu",
- 'dst' => "$base/local-public/5/5f/LoremIpsum.djvu"
- ] );
-
- // No helpful SVG file to copy, so make one ourselves
- $data = '<?xml version="1.0" encoding="utf-8"?>' .
- '<svg xmlns="http://www.w3.org/2000/svg"' .
- ' version="1.1" width="240" height="180"/>';
-
- $backend->prepare( [ 'dir' => "$base/local-public/f/ff" ] );
- $backend->quickCreate( [
- 'content' => $data, 'dst' => "$base/local-public/f/ff/Foobar.svg"
- ] );
- }
-
- /**
- * Restore default values and perform any necessary clean-up
- * after each test runs.
- */
- protected function teardownGlobals() {
- $this->teardownUploads();
-
- foreach ( $this->savedGlobals as $var => $val ) {
- $GLOBALS[$var] = $val;
- }
- }
-
- /**
- * Remove the dummy uploads directory
- */
- private function teardownUploads() {
- if ( $this->keepUploads ) {
- return;
- }
-
- $backend = RepoGroup::singleton()->getLocalRepo()->getBackend();
- if ( $backend instanceof MockFileBackend ) {
- # In memory backend, so dont bother cleaning them up.
- return;
- }
-
- $base = $this->getBaseDir();
- // delete the files first, then the dirs.
- self::deleteFiles(
- [
- "$base/local-public/3/3a/Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/1000px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/100px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/137px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/1500px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/177px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/206px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/20px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/220px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/265px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/270px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/274px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/300px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/30px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/330px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/353px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/360px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/400px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/40px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/440px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/442px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/450px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/50px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/600px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/640px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/70px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/75px-Foobar.jpg",
- "$base/local-thumb/3/3a/Foobar.jpg/960px-Foobar.jpg",
-
- "$base/local-public/e/ea/Thumb.png",
-
- "$base/local-public/0/09/Bad.jpg",
-
- "$base/local-public/5/5f/LoremIpsum.djvu",
- "$base/local-thumb/5/5f/LoremIpsum.djvu/page2-2480px-LoremIpsum.djvu.jpg",
- "$base/local-thumb/5/5f/LoremIpsum.djvu/page2-3720px-LoremIpsum.djvu.jpg",
- "$base/local-thumb/5/5f/LoremIpsum.djvu/page2-4960px-LoremIpsum.djvu.jpg",
-
- "$base/local-public/f/ff/Foobar.svg",
- "$base/local-thumb/f/ff/Foobar.svg/180px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/270px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/3000px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/360px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/4000px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.png",
- "$base/local-thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.png",
-
- "$base/local-public/math/f/a/5/fa50b8b616463173474302ca3e63586b.png",
- ]
- );
- }
-
- /**
- * Delete the specified files, if they exist.
- * @param array $files Full paths to files to delete.
- */
- private static function deleteFiles( $files ) {
- $backend = RepoGroup::singleton()->getLocalRepo()->getBackend();
- foreach ( $files as $file ) {
- $backend->delete( [ 'src' => $file ], [ 'force' => 1 ] );
- }
- foreach ( $files as $file ) {
- $tmp = FileBackend::parentStoragePath( $file );
- while ( $tmp ) {
- if ( !$backend->clean( [ 'dir' => $tmp ] )->isOK() ) {
- break;
- }
- $tmp = FileBackend::parentStoragePath( $tmp );
- }
- }
- }
-
- protected function getBaseDir() {
- return 'mwstore://local-backend';
- }
-
- public function parserTestProvider() {
- if ( $this->file === false ) {
- global $wgParserTestFiles;
- $this->file = $wgParserTestFiles[0];
- }
-
- return new TestFileDataProvider( $this->file, $this );
- }
-
- /**
- * Set the file from whose tests will be run by this instance
- * @param string $filename
- */
- public function setParserTestFile( $filename ) {
- $this->file = $filename;
- }
-
- /**
- * @group medium
- * @group ParserTests
- * @dataProvider parserTestProvider
- * @param string $desc
- * @param string $input
- * @param string $result
- * @param array $opts
- * @param array $config
- */
- public function testParserTest( $desc, $input, $result, $opts, $config ) {
- if ( $this->regex != '' && !preg_match( '/' . $this->regex . '/', $desc ) ) {
- $this->assertTrue( true ); // XXX: don't flood output with "test made no assertions"
- // $this->markTestSkipped( 'Filtered out by the user' );
- $this->teardownGlobals();
- return;
- }
-
- if ( !$this->isWikitextNS( NS_MAIN ) ) {
- // parser tests frequently assume that the main namespace contains wikitext.
- // @todo When setting up pages, force the content model. Only skip if
- // $wgtContentModelUseDB is false.
- $this->teardownGlobals();
- $this->markTestSkipped( "Main namespace does not support wikitext,"
- . "skipping parser test: $desc" );
- }
-
- wfDebug( "Running parser test: $desc\n" );
-
- $opts = $this->parseOptions( $opts );
- $context = $this->setupGlobals( $opts, $config );
-
- $user = $context->getUser();
- $options = ParserOptions::newFromContext( $context );
-
- if ( isset( $opts['title'] ) ) {
- $titleText = $opts['title'];
- } else {
- $titleText = 'Parser test';
- }
-
- $local = isset( $opts['local'] );
- $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null;
- $parser = $this->getParser( $preprocessor );
-
- $title = Title::newFromText( $titleText );
-
- # Parser test requiring math. Make sure texvc is executable
- # or just skip such tests.
- if ( isset( $opts['math'] ) || isset( $opts['texvc'] ) ) {
- global $wgTexvc;
-
- if ( !isset( $wgTexvc ) ) {
- $this->teardownGlobals();
- $this->markTestSkipped( "SKIPPED: \$wgTexvc is not set" );
- } elseif ( !is_executable( $wgTexvc ) ) {
- $this->teardownGlobals();
- $this->markTestSkipped( "SKIPPED: texvc binary does not exist"
- . " or is not executable.\n"
- . "Current configuration is:\n\$wgTexvc = '$wgTexvc'" );
- }
- }
-
- if ( isset( $opts['djvu'] ) ) {
- if ( !$this->djVuSupport->isEnabled() ) {
- $this->teardownGlobals();
- $this->markTestSkipped( "SKIPPED: djvu binaries do not exist or are not executable.\n" );
- }
- }
-
- if ( isset( $opts['tidy'] ) ) {
- if ( !$this->tidySupport->isEnabled() ) {
- $this->teardownGlobals();
- $this->markTestSkipped( "SKIPPED: tidy extension is not installed.\n" );
- } else {
- $options->setTidy( true );
- }
- }
-
- if ( isset( $opts['pst'] ) ) {
- $out = $parser->preSaveTransform( $input, $title, $user, $options );
- } elseif ( isset( $opts['msg'] ) ) {
- $out = $parser->transformMsg( $input, $options, $title );
- } elseif ( isset( $opts['section'] ) ) {
- $section = $opts['section'];
- $out = $parser->getSection( $input, $section );
- } elseif ( isset( $opts['replace'] ) ) {
- $section = $opts['replace'][0];
- $replace = $opts['replace'][1];
- $out = $parser->replaceSection( $input, $section, $replace );
- } elseif ( isset( $opts['comment'] ) ) {
- $out = Linker::formatComment( $input, $title, $local );
- } elseif ( isset( $opts['preload'] ) ) {
- $out = $parser->getPreloadText( $input, $title, $options );
- } else {
- $output = $parser->parse( $input, $title, $options, true, true, 1337 );
- $output->setTOCEnabled( !isset( $opts['notoc'] ) );
- $out = $output->getText();
- if ( isset( $opts['tidy'] ) ) {
- $out = preg_replace( '/\s+$/', '', $out );
- }
-
- if ( isset( $opts['showtitle'] ) ) {
- if ( $output->getTitleText() ) {
- $title = $output->getTitleText();
- }
-
- $out = "$title\n$out";
- }
-
- if ( isset( $opts['showindicators'] ) ) {
- $indicators = '';
- foreach ( $output->getIndicators() as $id => $content ) {
- $indicators .= "$id=$content\n";
- }
- $out = $indicators . $out;
- }
-
- if ( isset( $opts['ill'] ) ) {
- $out = implode( ' ', $output->getLanguageLinks() );
- } elseif ( isset( $opts['cat'] ) ) {
- $outputPage = $context->getOutput();
- $outputPage->addCategoryLinks( $output->getCategories() );
- $cats = $outputPage->getCategoryLinks();
-
- if ( isset( $cats['normal'] ) ) {
- $out = implode( ' ', $cats['normal'] );
- } else {
- $out = '';
- }
- }
- $parser->mPreprocessor = null;
- }
-
- $this->teardownGlobals();
-
- $this->assertEquals( $result, $out, $desc );
- }
-
- /**
- * Get a Parser object
- * @param Preprocessor $preprocessor
- * @return Parser
- */
- function getParser( $preprocessor = null ) {
- global $wgParserConf;
-
- $class = $wgParserConf['class'];
- $parser = new $class( [ 'preprocessorClass' => $preprocessor ] + $wgParserConf );
-
- Hooks::run( 'ParserTestParser', [ &$parser ] );
-
- return $parser;
- }
-
- // Various action functions
-
- public function addArticle( $name, $text, $line ) {
- self::$articles[$name] = [ $text, $line ];
- }
-
- public function publishTestArticles() {
- if ( empty( self::$articles ) ) {
- return;
- }
-
- foreach ( self::$articles as $name => $info ) {
- list( $text, $line ) = $info;
- ParserTest::addArticle( $name, $text, $line, 'ignoreduplicate' );
- }
- }
-
- /**
- * Steal a callback function from the primary parser, save it for
- * application to our scary parser. If the hook is not installed,
- * abort processing of this file.
- *
- * @param string $name
- * @return bool True if tag hook is present
- */
- public function requireHook( $name ) {
- global $wgParser;
- $wgParser->firstCallInit(); // make sure hooks are loaded.
- return isset( $wgParser->mTagHooks[$name] );
- }
-
- public function requireFunctionHook( $name ) {
- global $wgParser;
- $wgParser->firstCallInit(); // make sure hooks are loaded.
- return isset( $wgParser->mFunctionHooks[$name] );
- }
-
- public function requireTransparentHook( $name ) {
- global $wgParser;
- $wgParser->firstCallInit(); // make sure hooks are loaded.
- return isset( $wgParser->mTransparentTagHooks[$name] );
- }
-
- // Various "cleanup" functions
-
- /**
- * Remove last character if it is a newline
- * @param string $s
- * @return string
- */
- public function removeEndingNewline( $s ) {
- if ( substr( $s, -1 ) === "\n" ) {
- return substr( $s, 0, -1 );
- } else {
- return $s;
- }
- }
-
- // Test options parser functions
-
- protected function parseOptions( $instring ) {
- $opts = [];
- // foo
- // foo=bar
- // foo="bar baz"
- // foo=[[bar baz]]
- // foo=bar,"baz quux"
- $regex = '/\b
- ([\w-]+) # Key
- \b
- (?:\s*
- = # First sub-value
- \s*
- (
- "
- [^"]* # Quoted val
- "
- |
- \[\[
- [^]]* # Link target
- \]\]
- |
- [\w-]+ # Plain word
- )
- (?:\s*
- , # Sub-vals 1..N
- \s*
- (
- "[^"]*" # Quoted val
- |
- \[\[[^]]*\]\] # Link target
- |
- [\w-]+ # Plain word
- )
- )*
- )?
- /x';
-
- if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) {
- foreach ( $matches as $bits ) {
- array_shift( $bits );
- $key = strtolower( array_shift( $bits ) );
- if ( count( $bits ) == 0 ) {
- $opts[$key] = true;
- } elseif ( count( $bits ) == 1 ) {
- $opts[$key] = $this->cleanupOption( array_shift( $bits ) );
- } else {
- // Array!
- $opts[$key] = array_map( [ $this, 'cleanupOption' ], $bits );
- }
- }
- }
-
- return $opts;
- }
-
- protected function cleanupOption( $opt ) {
- if ( substr( $opt, 0, 1 ) == '"' ) {
- return substr( $opt, 1, -1 );
- }
-
- if ( substr( $opt, 0, 2 ) == '[[' ) {
- return substr( $opt, 2, -2 );
- }
-
- return $opt;
- }
-
- /**
- * Use a regex to find out the value of an option
- * @param string $key Name of option val to retrieve
- * @param array $opts Options array to look in
- * @param mixed $default Default value returned if not found
- * @return mixed
- */
- protected static function getOptionValue( $key, $opts, $default ) {
- $key = strtolower( $key );
-
- if ( isset( $opts[$key] ) ) {
- return $opts[$key];
- } else {
- return $default;
- }
- }
-}
--- /dev/null
+<?php
+
+/**
+ * This is the TestCase subclass for running a single parser test via the
+ * ParserTestRunner integration test system.
+ *
+ * Note: the following groups are not used by PHPUnit.
+ * The list in ParserTestFileSuite::__construct() is used instead.
+ *
+ * @group Database
+ * @group Parser
+ *
+ * @todo covers tags
+ */
+class ParserIntegrationTest extends PHPUnit_Framework_TestCase {
+ /** @var array */
+ private $ptTest;
+
+ /** @var ParserTestRunner */
+ private $ptRunner;
+
+ /** @var ScopedCallback */
+ private $ptTeardownScope;
+
+ public function __construct( $runner, $fileName, $test ) {
+ parent::__construct( 'testParse', [ '[details omitted]' ],
+ basename( $fileName ) . ': ' . $test['desc'] );
+ $this->ptTest = $test;
+ $this->ptRunner = $runner;
+ }
+
+ public function testParse() {
+ $this->ptRunner->getRecorder()->setTestCase( $this );
+ $result = $this->ptRunner->runTest( $this->ptTest );
+ $this->assertEquals( $result->expected, $result->actual );
+ }
+
+ public function setUp() {
+ $this->ptTeardownScope = $this->ptRunner->staticSetup();
+ }
+
+ public function tearDown() {
+ if ( $this->ptTeardownScope ) {
+ ScopedCallback::consume( $this->ptTeardownScope );
+ }
+ }
+}
*/
public function testTemplateDependencies( $module, $expected ) {
$rl = new ResourceLoaderFileModule( $module );
+ $rl->setName( 'testing' );
$this->assertEquals( $rl->getDependencies(), $expected );
}
];
$module = new ResourceLoaderFileModule( $baseParams );
+ $module->setName( 'testing' );
$this->assertEquals(
[
'localBasePath' => $basePath,
'styles' => [ 'test.css' ],
] );
+ $testModule->setName( 'testing' );
$expectedModule = new ResourceLoaderFileModule( [
'localBasePath' => $basePath,
'styles' => [ 'expected.css' ],
] );
+ $expectedModule->setName( 'testing' );
$contextLtr = $this->getResourceLoaderContext( 'en', 'ltr' );
$contextRtl = $this->getResourceLoaderContext( 'he', 'rtl' );
*/
public function testGetTemplates( $module, $expected ) {
$rl = new ResourceLoaderFileModule( $module );
+ $rl->setName( 'testing' );
$this->assertEquals( $rl->getTemplates(), $expected );
}
'localBasePath' => $basePath,
'styles' => [ 'bom.css' ],
] );
+ $testModule->setName( 'testing' );
$this->assertEquals(
substr( file_get_contents( "$basePath/bom.css" ), 0, 10 ),
"\xef\xbb\xbf.efbbbf",
$this->assertNotNull( BotPassword::newFromCentralId( 43, 'BotPassword' ) );
}
+ /**
+ * @dataProvider provideCanonicalizeLoginData
+ */
+ public function testCanonicalizeLoginData( $username, $password, $expectedResult ) {
+ $result = BotPassword::canonicalizeLoginData( $username, $password );
+ if ( is_array( $expectedResult ) ) {
+ $this->assertArrayEquals( $expectedResult, $result, true, true );
+ } else {
+ $this->assertSame( $expectedResult, $result );
+ }
+ }
+
+ public function provideCanonicalizeLoginData() {
+ return [
+ [ 'user', 'pass', false ],
+ [ 'user', 'abc@def', false ],
+ [ 'user@bot', '12345678901234567890123456789012',
+ [ 'user@bot', '12345678901234567890123456789012', false ] ],
+ [ 'user', 'bot@12345678901234567890123456789012',
+ [ 'user@bot', '12345678901234567890123456789012', true ] ],
+ [ 'user', 'bot@12345678901234567890123456789012345',
+ [ 'user@bot', '12345678901234567890123456789012345', true ] ],
+ [ 'user', 'bot@x@12345678901234567890123456789012',
+ [ 'user@bot@x', '12345678901234567890123456789012', true ] ],
+ ];
+ }
+
public function testLogin() {
// Test failure when bot passwords aren't enabled
$this->setMwGlobals( 'wgEnableBotPasswords', false );
class PHPUnitMaintClass extends Maintenance {
public static $additionalOptions = [
- 'regex' => false,
'file' => false,
'use-filebackend' => false,
'use-bagostuff' => false,
'use-jobqueue' => false,
- 'keep-uploads' => false,
'use-normal-tables' => false,
'reuse-db' => false,
'wiki' => false,
false, # not required
false # no arg needed
);
- $this->addOption(
- 'regex',
- 'Only run parser tests that match the given regex.',
- false,
- true
- );
$this->addOption( 'file', 'File describing parser tests.', false, true );
$this->addOption( 'use-filebackend', 'Use filebackend', false, true );
$this->addOption( 'use-bagostuff', 'Use bagostuff', false, true );
$this->addOption( 'use-jobqueue', 'Use jobqueue', false, true );
- $this->addOption(
- 'keep-uploads',
- 'Re-use the same upload directory for each test, don\'t delete it.',
- false,
- false
- );
$this->addOption( 'use-normal-tables', 'Use normal DB tables.', false, false );
$this->addOption(
'reuse-db', 'Init DB only if tables are missing and keep after finish.',
public function finalSetup() {
parent::finalSetup();
- global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgMainWANCache;
- global $wgMainStash;
- global $wgLanguageConverterCacheType, $wgUseDatabaseMessages;
- global $wgLocaltimezone, $wgLocalisationCacheConf;
- global $wgDevelopmentWarnings;
- global $wgSessionProviders, $wgSessionPbkdf2Iterations;
- global $wgJobTypeConf;
- global $wgAuthManagerConfig, $wgAuth;
-
// Inject test autoloader
- require_once __DIR__ . '/../TestsAutoLoader.php';
-
- // wfWarn should cause tests to fail
- $wgDevelopmentWarnings = true;
-
- // Make sure all caches and stashes are either disabled or use
- // in-process cache only to prevent tests from using any preconfigured
- // cache meant for the local wiki from outside the test run.
- // See also MediaWikiTestCase::run() which mocks CACHE_DB and APC.
-
- // Disabled in DefaultSettings, override local settings
- $wgMainWANCache =
- $wgMainCacheType = CACHE_NONE;
- // Uses CACHE_ANYTHING in DefaultSettings, use hash instead of db
- $wgMessageCacheType =
- $wgParserCacheType =
- $wgSessionCacheType =
- $wgLanguageConverterCacheType = 'hash';
- // Uses db-replicated in DefaultSettings
- $wgMainStash = 'hash';
- // Use memory job queue
- $wgJobTypeConf = [
- 'default' => [ 'class' => 'JobQueueMemory', 'order' => 'fifo' ],
- ];
-
- $wgUseDatabaseMessages = false; # Set for future resets
-
- // Assume UTC for testing purposes
- $wgLocaltimezone = 'UTC';
-
- $wgLocalisationCacheConf['storeClass'] = 'LCStoreNull';
-
- // Generic MediaWiki\Session\SessionManager configuration for tests
- // We use CookieSessionProvider because things might be expecting
- // cookies to show up in a FauxRequest somewhere.
- $wgSessionProviders = [
- [
- 'class' => MediaWiki\Session\CookieSessionProvider::class,
- 'args' => [ [
- 'priority' => 30,
- 'callUserSetCookiesHook' => true,
- ] ],
- ],
- ];
-
- // Single-iteration PBKDF2 session secret derivation, for speed.
- $wgSessionPbkdf2Iterations = 1;
-
- // Generic AuthManager configuration for testing
- $wgAuthManagerConfig = [
- 'preauth' => [],
- 'primaryauth' => [
- [
- 'class' => MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider::class,
- 'args' => [ [
- 'authoritative' => false,
- ] ],
- ],
- [
- 'class' => MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider::class,
- 'args' => [ [
- 'authoritative' => true,
- ] ],
- ],
- ],
- 'secondaryauth' => [],
- ];
- $wgAuth = new MediaWiki\Auth\AuthManagerAuthPlugin();
-
- // Bug 44192 Do not attempt to send a real e-mail
- Hooks::clear( 'AlternateUserMailer' );
- Hooks::register(
- 'AlternateUserMailer',
- function () {
- return false;
- }
- );
- // xdebug's default of 100 is too low for MediaWiki
- ini_set( 'xdebug.max_nesting_level', 1000 );
-
- // Bug T116683 serialize_precision of 100
- // may break testing against floating point values
- // treated with PHP's serialize()
- ini_set( 'serialize_precision', 17 );
+ self::requireTestsAutoloader();
- // TODO: we should call MediaWikiTestCase::prepareServices( new GlobalVarConfig() ) here.
- // But PHPUnit may not be loaded yet, so we have to wait until just
- // before PHPUnit_TextUI_Command::main() is executed.
+ TestSetup::applyInitialConfig();
}
public function execute() {
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+class ContentHandlerSanityTest extends MediaWikiTestCase {
+
+ public static function provideHandlers() {
+ $models = ContentHandler::getContentModels();
+ $handlers = [];
+ foreach ( $models as $model ) {
+ $handlers[] = [ ContentHandler::getForModelID( $model ) ];
+ }
+
+ return $handlers;
+ }
+
+ /**
+ * @dataProvider provideHandlers
+ * @param ContentHandler $handler
+ */
+ public function testMakeEmptyContent( ContentHandler $handler ) {
+ $content = $handler->makeEmptyContent();
+ $this->assertInstanceOf( Content::class, $content );
+ if ( $handler instanceof TextContentHandler ) {
+ // TextContentHandler::getContentClass() is protected, so bypass
+ // that restriction
+ $testingWrapper = TestingAccessWrapper::newFromObject( $handler );
+ $this->assertInstanceOf( $testingWrapper->getContentClass(), $content );
+ }
+
+ $handlerClass = get_class( $handler );
+ $contentClass = get_class( $content );
+
+ $this->assertTrue(
+ $content->isValid(),
+ "$handlerClass::makeEmptyContent() did not return a valid content ($contentClass::isValid())"
+ );
+ }
+}
<testsuites>
<testsuite name="includes">
<directory>includes</directory>
+ <!-- Parser tests must be invoked via their suite -->
+ <exclude>includes/parser/ParserIntegrationTest.php</exclude>
</testsuite>
<testsuite name="languages">
<directory>languages</directory>
</testsuite>
<testsuite name="parsertests">
- <file>includes/parser/MediaWikiParserTest.php</file>
+ <file>suites/CoreParserTestSuite.php</file>
<file>suites/ExtensionsParserTestSuite.php</file>
</testsuite>
<testsuite name="skins">
<exclude>
<group>Utility</group>
<group>Broken</group>
- <group>ParserFuzz</group>
<group>Stub</group>
</exclude>
</groups>
--- /dev/null
+<?php
+
+class CoreParserTestSuite extends PHPUnit_Framework_TestSuite {
+
+ public static function suite() {
+ return ParserTestTopLevelSuite::suite( ParserTestTopLevelSuite::CORE_ONLY );
+ }
+
+}
+
class ExtensionsParserTestSuite extends PHPUnit_Framework_TestSuite {
public static function suite() {
- return MediaWikiParserTest::suite( MediaWikiParserTest::NO_CORE );
+ return ParserTestTopLevelSuite::suite( ParserTestTopLevelSuite::NO_CORE );
}
}
--- /dev/null
+<?php
+
+/**
+ * This is the suite class for running tests within a single .txt source file.
+ * It is not invoked directly. Use --filter to select files, or
+ * use parserTests.php.
+ */
+class ParserTestFileSuite extends PHPUnit_Framework_TestSuite {
+ private $ptRunner;
+ private $ptFileName;
+ private $ptFileInfo;
+
+ function __construct( $runner, $name, $fileName ) {
+ parent::__construct( $name );
+ $this->ptRunner = $runner;
+ $this->ptFileName = $fileName;
+ $this->ptFileInfo = TestFileReader::read( $this->ptFileName );
+
+ foreach ( $this->ptFileInfo['tests'] as $test ) {
+ $this->addTest( new ParserIntegrationTest( $runner, $fileName, $test ),
+ [ 'Database', 'Parser' ] );
+ }
+ }
+
+ function setUp() {
+ $this->ptRunner->addArticles( $this->ptFileInfo[ 'articles'] );
+ }
+}
--- /dev/null
+<?php
+
+/**
+ * The UnitTest must be either a class that inherits from MediaWikiTestCase
+ * or a class that provides a public static suite() method which returns
+ * an PHPUnit_Framework_Test object
+ *
+ * @group Parser
+ * @group ParserTests
+ * @group Database
+ */
+class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
+ /** @var ParserTestRunner */
+ private $ptRunner;
+
+ /** @var ScopedCallback */
+ private $ptTeardownScope;
+
+ /**
+ * @defgroup filtering_constants Filtering constants
+ *
+ * Limit inclusion of parser tests files coming from MediaWiki core
+ * @{
+ */
+
+ /** Include files shipped with MediaWiki core */
+ const CORE_ONLY = 1;
+ /** Include non core files as set in $wgParserTestFiles */
+ const NO_CORE = 2;
+ /** Include anything set via $wgParserTestFiles */
+ const WITH_ALL = 3; # CORE_ONLY | NO_CORE
+
+ /** @} */
+
+ /**
+ * Get a PHPUnit test suite of parser tests. Optionally filtered with
+ * $flags.
+ *
+ * @par Examples:
+ * Get a suite of parser tests shipped by MediaWiki core:
+ * @code
+ * ParserTestTopLevelSuite::suite( ParserTestTopLevelSuite::CORE_ONLY );
+ * @endcode
+ * Get a suite of various parser tests, like extensions:
+ * @code
+ * ParserTestTopLevelSuite::suite( ParserTestTopLevelSuite::NO_CORE );
+ * @endcode
+ * Get any test defined via $wgParserTestFiles:
+ * @code
+ * ParserTestTopLevelSuite::suite( ParserTestTopLevelSuite::WITH_ALL );
+ * @endcode
+ *
+ * @param int $flags Bitwise flag to filter out the $wgParserTestFiles that
+ * will be included. Default: ParserTestTopLevelSuite::CORE_ONLY
+ *
+ * @return PHPUnit_Framework_TestSuite
+ */
+ public static function suite( $flags = self::CORE_ONLY ) {
+ return new self( $flags );
+ }
+
+ function __construct( $flags ) {
+ parent::__construct();
+
+ $this->ptRecorder = new PhpunitTestRecorder;
+ $this->ptRunner = new ParserTestRunner( $this->ptRecorder );
+
+ if ( is_string( $flags ) ) {
+ $flags = self::CORE_ONLY;
+ }
+ global $wgParserTestFiles, $IP;
+
+ $mwTestDir = $IP . '/tests/';
+
+ # Human friendly helpers
+ $wantsCore = ( $flags & self::CORE_ONLY );
+ $wantsRest = ( $flags & self::NO_CORE );
+
+ # Will hold the .txt parser test files we will include
+ $filesToTest = [];
+
+ # Filter out .txt files
+ foreach ( $wgParserTestFiles as $parserTestFile ) {
+ $isCore = ( 0 === strpos( $parserTestFile, $mwTestDir ) );
+
+ if ( $isCore && $wantsCore ) {
+ self::debug( "included core parser tests: $parserTestFile" );
+ $filesToTest[] = $parserTestFile;
+ } elseif ( !$isCore && $wantsRest ) {
+ self::debug( "included non core parser tests: $parserTestFile" );
+ $filesToTest[] = $parserTestFile;
+ } else {
+ self::debug( "skipped parser tests: $parserTestFile" );
+ }
+ }
+ self::debug( 'parser tests files: '
+ . implode( ' ', $filesToTest ) );
+
+ $testList = [];
+ $counter = 0;
+ foreach ( $filesToTest as $fileName ) {
+ // Call the highest level directory the extension name.
+ // It may or may not actually be, but it should be close
+ // enough to cause there to be separate names for different
+ // things, which is good enough for our purposes.
+ $extensionName = basename( dirname( $fileName ) );
+ $testsName = $extensionName . '__' . basename( $fileName, '.txt' );
+ $parserTestClassName = ucfirst( $testsName );
+
+ // Official spec for class names: http://php.net/manual/en/language.oop5.basic.php
+ // Prepend 'ParserTest_' to be paranoid about it not starting with a number
+ $parserTestClassName = 'ParserTest_' .
+ preg_replace( '/[^a-zA-Z0-9_\x7f-\xff]/', '_', $parserTestClassName );
+
+ if ( isset( $testList[$parserTestClassName] ) ) {
+ // If there is a conflict, append a number.
+ $counter++;
+ $parserTestClassName .= $counter;
+ }
+ $testList[$parserTestClassName] = true;
+
+ // Previously we actually created a class here, with eval(). We now
+ // just override the name.
+
+ self::debug( "Adding test class $parserTestClassName" );
+ $this->addTest( new ParserTestFileSuite(
+ $this->ptRunner, $parserTestClassName, $fileName ) );
+ }
+ }
+
+ public function setUp() {
+ wfDebug( __METHOD__ );
+ $db = wfGetDB( DB_MASTER );
+ $type = $db->getType();
+ $prefix = $type === 'oracle' ?
+ MediaWikiTestCase::ORA_DB_PREFIX : MediaWikiTestCase::DB_PREFIX;
+ MediaWikiTestCase::setupTestDB( $db, $prefix );
+ $teardown = $this->ptRunner->setDatabase( $db );
+ $teardown = $this->ptRunner->setupUploads( $teardown );
+ $this->ptTeardownScope = $teardown;
+ }
+
+ public function tearDown() {
+ wfDebug( __METHOD__ );
+ if ( $this->ptTeardownScope ) {
+ ScopedCallback::consume( $this->ptTeardownScope );
+ }
+ }
+
+ /**
+ * Write $msg under log group 'tests-parser'
+ * @param string $msg Message to log
+ */
+ protected static function debug( $msg ) {
+ return wfDebugLog( 'tests-parser', wfGetCaller() . ' ' . $msg );
+ }
+}