<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.neverlands.ru/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.neverlands.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kolbaska</id>
		<title>Викиневер - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.neverlands.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kolbaska"/>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:Contributions/Kolbaska"/>
		<updated>2026-04-30T16:51:36Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.19.2</generator>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/bigChunkedUpload.js</id>
		<title>Участник:Kolbaska/bigChunkedUpload.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/bigChunkedUpload.js"/>
				<updated>2025-11-14T10:42:35Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: Полностью удалено содержимое страницы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js</id>
		<title>Участник:Kolbaska/common.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js"/>
				<updated>2025-11-14T04:19:06Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mw.loader.using( [ 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
    /* Begin of mw.loader.using callback */&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Map addPortletLink to mw.util&lt;br /&gt;
     * @deprecated: Use mw.util.addPortletLink instead.&lt;br /&gt;
     */&lt;br /&gt;
    mw.log.deprecate( window, 'addPortletLink', mw.util.addPortletLink, 'Use mw.util.addPortletLink instead' );&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
     * @rev 6&lt;br /&gt;
     */&lt;br /&gt;
    var extraCSS = mw.util.getParamValue( 'withCSS' ),&lt;br /&gt;
        extraJS = mw.util.getParamValue( 'withJS' );&lt;br /&gt;
&lt;br /&gt;
    if ( extraCSS ) {&lt;br /&gt;
        if ( extraCSS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.css$/ ) ) {&lt;br /&gt;
            mw.loader.load( '/index.php?title=' + extraCSS + '&amp;amp;action=raw&amp;amp;ctype=text/css', 'text/css' );&lt;br /&gt;
        } else {&lt;br /&gt;
            mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( extraJS ) {&lt;br /&gt;
        if ( extraJS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.js$/ ) ) {&lt;br /&gt;
            mw.loader.load( '/index.php?title=' + extraJS + '&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
        } else {&lt;br /&gt;
            mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Collapsible tables; reimplemented with mw-collapsible&lt;br /&gt;
     * Styling is also in place to avoid FOUC&lt;br /&gt;
     *&lt;br /&gt;
     * Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].&lt;br /&gt;
     * @version 3.0.0 (2018-05-20)&lt;br /&gt;
     * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js&lt;br /&gt;
     * @author [[User:R. Koot]]&lt;br /&gt;
     * @author [[User:Krinkle]]&lt;br /&gt;
     * @author [[User:TheDJ]]&lt;br /&gt;
     * @deprecated Since MediaWiki 1.20: Use class=&amp;quot;mw-collapsible&amp;quot; instead which&lt;br /&gt;
     * is supported in MediaWiki core. Shimmable since MediaWiki 1.32&lt;br /&gt;
     *&lt;br /&gt;
     * @param {jQuery} $content&lt;br /&gt;
     */&lt;br /&gt;
    function makeCollapsibleMwCollapsible( $content ) {&lt;br /&gt;
        var $tables = $content&lt;br /&gt;
            .find( 'table.collapsible:not(.mw-collapsible)' )&lt;br /&gt;
            .addClass( 'mw-collapsible' );&lt;br /&gt;
&lt;br /&gt;
        $.each( $tables, function ( index, table ) {&lt;br /&gt;
            // mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');&lt;br /&gt;
            if ( $( table ).hasClass( 'collapsed' ) ) {&lt;br /&gt;
                $( table ).addClass( 'mw-collapsed' );&lt;br /&gt;
                // mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
        if ( $tables.length &amp;gt; 0 ) {&lt;br /&gt;
            mw.loader.using( 'jquery.makeCollapsible' ).then( function () {&lt;br /&gt;
                $tables.makeCollapsible();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    mw.hook( 'wikipage.content' ).add( makeCollapsibleMwCollapsible );&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Add support to mw-collapsible for autocollapse, innercollapse and outercollapse&lt;br /&gt;
     *&lt;br /&gt;
     * Maintainers: TheDJ&lt;br /&gt;
     */&lt;br /&gt;
    function mwCollapsibleSetup( $collapsibleContent ) {&lt;br /&gt;
        var $element,&lt;br /&gt;
            $toggle,&lt;br /&gt;
            autoCollapseThreshold = 2;&lt;br /&gt;
        $.each( $collapsibleContent, function ( index, element ) {&lt;br /&gt;
            $element = $( element );&lt;br /&gt;
            if ( $element.hasClass( 'collapsible' ) ) {&lt;br /&gt;
                $element.find( 'tr:first &amp;gt; th:first' ).prepend( $element.find( 'tr:first &amp;gt; * &amp;gt; .mw-collapsible-toggle' ) );&lt;br /&gt;
            }&lt;br /&gt;
            if ( $collapsibleContent.length &amp;gt;= autoCollapseThreshold &amp;amp;&amp;amp; $element.hasClass( 'autocollapse' ) ) {&lt;br /&gt;
                $element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
            } else if ( $element.hasClass( 'innercollapse' ) ) {&lt;br /&gt;
                if ( $element.parents( '.outercollapse' ).length &amp;gt; 0 ) {&lt;br /&gt;
                    $element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // because of colored backgrounds, style the link in the text color&lt;br /&gt;
            // to ensure accessible contrast&lt;br /&gt;
            $toggle = $element.find( '.mw-collapsible-toggle' );&lt;br /&gt;
            if ( $toggle.length ) {&lt;br /&gt;
                // Make the toggle inherit text color (Updated for T333357 2023-04-29)&lt;br /&gt;
                if ( $toggle.parent()[ 0 ].style.color ) {&lt;br /&gt;
                    $toggle.css( 'color', 'inherit' );&lt;br /&gt;
                    $toggle.find( '.mw-collapsible-text' ).css( 'color', 'inherit' );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );&lt;br /&gt;
&lt;br /&gt;
    /* End of mw.loader.using callback */&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
importScript('User:Kolbaska/bigChunkedUpload.js');&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js</id>
		<title>Участник:Kolbaska/common.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js"/>
				<updated>2025-11-14T04:15:23Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mw.loader.using( [ 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
    /* Begin of mw.loader.using callback */&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Map addPortletLink to mw.util&lt;br /&gt;
     * @deprecated: Use mw.util.addPortletLink instead.&lt;br /&gt;
     */&lt;br /&gt;
    mw.log.deprecate( window, 'addPortletLink', mw.util.addPortletLink, 'Use mw.util.addPortletLink instead' );&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
     * @rev 6&lt;br /&gt;
     */&lt;br /&gt;
    var extraCSS = mw.util.getParamValue( 'withCSS' ),&lt;br /&gt;
        extraJS = mw.util.getParamValue( 'withJS' );&lt;br /&gt;
&lt;br /&gt;
    if ( extraCSS ) {&lt;br /&gt;
        if ( extraCSS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.css$/ ) ) {&lt;br /&gt;
            mw.loader.load( '/index.php?title=' + extraCSS + '&amp;amp;action=raw&amp;amp;ctype=text/css', 'text/css' );&lt;br /&gt;
        } else {&lt;br /&gt;
            mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( extraJS ) {&lt;br /&gt;
        if ( extraJS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.js$/ ) ) {&lt;br /&gt;
            mw.loader.load( '/index.php?title=' + extraJS + '&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
        } else {&lt;br /&gt;
            mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Collapsible tables; reimplemented with mw-collapsible&lt;br /&gt;
     * Styling is also in place to avoid FOUC&lt;br /&gt;
     *&lt;br /&gt;
     * Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].&lt;br /&gt;
     * @version 3.0.0 (2018-05-20)&lt;br /&gt;
     * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js&lt;br /&gt;
     * @author [[User:R. Koot]]&lt;br /&gt;
     * @author [[User:Krinkle]]&lt;br /&gt;
     * @author [[User:TheDJ]]&lt;br /&gt;
     * @deprecated Since MediaWiki 1.20: Use class=&amp;quot;mw-collapsible&amp;quot; instead which&lt;br /&gt;
     * is supported in MediaWiki core. Shimmable since MediaWiki 1.32&lt;br /&gt;
     *&lt;br /&gt;
     * @param {jQuery} $content&lt;br /&gt;
     */&lt;br /&gt;
    function makeCollapsibleMwCollapsible( $content ) {&lt;br /&gt;
        var $tables = $content&lt;br /&gt;
            .find( 'table.collapsible:not(.mw-collapsible)' )&lt;br /&gt;
            .addClass( 'mw-collapsible' );&lt;br /&gt;
&lt;br /&gt;
        $.each( $tables, function ( index, table ) {&lt;br /&gt;
            // mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');&lt;br /&gt;
            if ( $( table ).hasClass( 'collapsed' ) ) {&lt;br /&gt;
                $( table ).addClass( 'mw-collapsed' );&lt;br /&gt;
                // mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
        if ( $tables.length &amp;gt; 0 ) {&lt;br /&gt;
            mw.loader.using( 'jquery.makeCollapsible' ).then( function () {&lt;br /&gt;
                $tables.makeCollapsible();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    mw.hook( 'wikipage.content' ).add( makeCollapsibleMwCollapsible );&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Add support to mw-collapsible for autocollapse, innercollapse and outercollapse&lt;br /&gt;
     *&lt;br /&gt;
     * Maintainers: TheDJ&lt;br /&gt;
     */&lt;br /&gt;
    function mwCollapsibleSetup( $collapsibleContent ) {&lt;br /&gt;
        var $element,&lt;br /&gt;
            $toggle,&lt;br /&gt;
            autoCollapseThreshold = 2;&lt;br /&gt;
        $.each( $collapsibleContent, function ( index, element ) {&lt;br /&gt;
            $element = $( element );&lt;br /&gt;
            if ( $element.hasClass( 'collapsible' ) ) {&lt;br /&gt;
                $element.find( 'tr:first &amp;gt; th:first' ).prepend( $element.find( 'tr:first &amp;gt; * &amp;gt; .mw-collapsible-toggle' ) );&lt;br /&gt;
            }&lt;br /&gt;
            if ( $collapsibleContent.length &amp;gt;= autoCollapseThreshold &amp;amp;&amp;amp; $element.hasClass( 'autocollapse' ) ) {&lt;br /&gt;
                $element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
            } else if ( $element.hasClass( 'innercollapse' ) ) {&lt;br /&gt;
                if ( $element.parents( '.outercollapse' ).length &amp;gt; 0 ) {&lt;br /&gt;
                    $element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // because of colored backgrounds, style the link in the text color&lt;br /&gt;
            // to ensure accessible contrast&lt;br /&gt;
            $toggle = $element.find( '.mw-collapsible-toggle' );&lt;br /&gt;
            if ( $toggle.length ) {&lt;br /&gt;
                // Make the toggle inherit text color (Updated for T333357 2023-04-29)&lt;br /&gt;
                if ( $toggle.parent()[ 0 ].style.color ) {&lt;br /&gt;
                    $toggle.css( 'color', 'inherit' );&lt;br /&gt;
                    $toggle.find( '.mw-collapsible-text' ).css( 'color', 'inherit' );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );&lt;br /&gt;
&lt;br /&gt;
    /* End of mw.loader.using callback */&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/bigChunkedUpload.js</id>
		<title>Участник:Kolbaska/bigChunkedUpload.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/bigChunkedUpload.js"/>
				<updated>2025-11-14T04:14:41Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: Новая страница: «( function( $, mw, undefined ) {     'use strict';      var modeNewFile;     var i;     var random = Math.round(Math.random() * 0x1000000000);     var commonwWiki…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;( function( $, mw, undefined ) {&lt;br /&gt;
    'use strict';&lt;br /&gt;
&lt;br /&gt;
    var modeNewFile;&lt;br /&gt;
    var i;&lt;br /&gt;
    var random = Math.round(Math.random() * 0x1000000000);&lt;br /&gt;
    var commonwWikiKey = &amp;quot;commonswiki&amp;quot; + random;&lt;br /&gt;
    var commonsWiki = {};&lt;br /&gt;
    var modules = [&lt;br /&gt;
        [ &amp;quot;ext.gadget.editDropdown&amp;quot;, &amp;quot;ver1_svg&amp;quot;, [], null, commonwWikiKey ],&lt;br /&gt;
        [ &amp;quot;ext.gadget.libAPI&amp;quot;, &amp;quot;ver1_svg&amp;quot;, [], null, commonwWikiKey ]&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function ucFirst( s ) {&lt;br /&gt;
        return s[ 0 ].toUpperCase() + s.slice( 1 );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var _install = function() {&lt;br /&gt;
&lt;br /&gt;
        var $reuploadLink = $( '#mw-imagepage-reupload-link' )&lt;br /&gt;
            .find( 'a' ),&lt;br /&gt;
            $activationLinks;&lt;br /&gt;
&lt;br /&gt;
        if ( $reuploadLink.length ) {&lt;br /&gt;
            $activationLinks = $( '&amp;lt;a&amp;gt;', {&lt;br /&gt;
                    text: &amp;quot; (chunked upload)&amp;quot;&lt;br /&gt;
                } )&lt;br /&gt;
                .attr( {&lt;br /&gt;
                    href: '#chunked upload'&lt;br /&gt;
                } )&lt;br /&gt;
                .insertAfter( $reuploadLink );&lt;br /&gt;
&lt;br /&gt;
            $activationLinks = $activationLinks.add(&lt;br /&gt;
                mw.libs.commons.ui.addEditLink(&lt;br /&gt;
                    '#chunked upload',&lt;br /&gt;
                    &amp;quot;upload new version (chunked)&amp;quot;,&lt;br /&gt;
                    'e-chunkedupload-overwrite',&lt;br /&gt;
                    &amp;quot;Overwrite file with another one using chunked uploading&amp;quot; ) );&lt;br /&gt;
        } else if ( mw.config.get( 'wgCanonicalNamespace' ) === 'File' ) {&lt;br /&gt;
            var title, validTitle;&lt;br /&gt;
            try {&lt;br /&gt;
                title = mw.config.get( 'wgTitle' );&lt;br /&gt;
                validTitle = new mw.Title( title );&lt;br /&gt;
&lt;br /&gt;
                validTitle = validTitle.getExtension().length &amp;amp;&amp;amp; !/(?:\/|\#|\:)/.test( title );&lt;br /&gt;
            } catch ( ex ) {}&lt;br /&gt;
            if ( validTitle ) {&lt;br /&gt;
                $activationLinks = $( mw.libs.commons.ui.addEditLink(&lt;br /&gt;
                    '#chunked upload',&lt;br /&gt;
                    &amp;quot;upload (chunked)&amp;quot;,&lt;br /&gt;
                    'e-chunkedupload-overwrite',&lt;br /&gt;
                    &amp;quot;Create new file using chunked uploading&amp;quot; ) );&lt;br /&gt;
                modeNewFile = true;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if ( $activationLinks ) $activationLinks.click( window.bigChunkedUpload );&lt;br /&gt;
        if ( mw.util.getParamValue( 'chunkedupload' ) ) window.bigChunkedUpload();&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    window.bigChunkedUpload = function( e ) {&lt;br /&gt;
        if ( e ) e.preventDefault();&lt;br /&gt;
        if ( null === mw.loader.getState( 'mediawiki.commons.MwJSBot' ) ) {&lt;br /&gt;
            mw.loader.implement( 'mediawiki.commons.MwJSBot', [&lt;br /&gt;
                &amp;quot;//wiki.neverlands.ru/index.php?action=raw&amp;amp;ctype=text/javascript&amp;amp;title=User:Kolbaska/MwJSBot.js&amp;amp;_=2&amp;quot;&lt;br /&gt;
            ], { /*no styles*/ }, { /*no messages*/ } );&lt;br /&gt;
        }&lt;br /&gt;
        mw.loader.using( [&lt;br /&gt;
            'mediawiki.commons.MwJSBot',&lt;br /&gt;
            'jquery.ui',&lt;br /&gt;
            'mediawiki.util' ], _bigChunkedUpload );&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var _bigChunkedUpload = function() {&lt;br /&gt;
        var instanceId = 'i' + Math.round( Math.random() * 1073741824 ),&lt;br /&gt;
            start,&lt;br /&gt;
            makeWikiLink = function( t, text ) {&lt;br /&gt;
                return $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
                    .attr( {&lt;br /&gt;
                        href: mw.util.getUrl( t ),&lt;br /&gt;
                        target: '_blank',&lt;br /&gt;
                        title: t&lt;br /&gt;
                    } )&lt;br /&gt;
                    .text( text || t );&lt;br /&gt;
            },&lt;br /&gt;
            $dlg = $( '&amp;lt;div&amp;gt;' ),&lt;br /&gt;
            w = Math.min( $( window )&lt;br /&gt;
                .width(), 1200 ),&lt;br /&gt;
            $logInRequired = $( '&amp;lt;div class=&amp;quot;ui-state-highlight&amp;quot; style=&amp;quot;display:none; cursor:pointer&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;To continue uploading, please log in and click here after you did so. Script will try to resume. Error reported by server is: &amp;quot; )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $progDiv = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $progBar = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .css( {&lt;br /&gt;
                width: '98%',&lt;br /&gt;
                padding: '2px'&lt;br /&gt;
            } )&lt;br /&gt;
            .progressbar( {&lt;br /&gt;
                value: 0&lt;br /&gt;
            } )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $progConsole = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .css( {&lt;br /&gt;
                'background': 'black',&lt;br /&gt;
                'color': 'white',&lt;br /&gt;
                'font-family': '\'Lucida Console\',Console,monospace',&lt;br /&gt;
                'overflow': 'auto',&lt;br /&gt;
                'width': '98%',&lt;br /&gt;
                'height': '200px',&lt;br /&gt;
                'border': '1px solid grey',&lt;br /&gt;
                'padding': '2px',&lt;br /&gt;
                'white-space': 'pre-wrap',&lt;br /&gt;
                'resize': 'both'&lt;br /&gt;
            } )&lt;br /&gt;
            .text( 'Hi, ' + mw.config.get( 'wgUserName' ) + '! Thank you for testing version 0.0.1 of ' )&lt;br /&gt;
            .append( makeWikiLink( 'User:Rillke/bigChunkedUpload.js' ), '.' )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            pad = function( digit, number, input ) {&lt;br /&gt;
                input += '';&lt;br /&gt;
                return new Array( Math.max( number + 1 - input.length, 1 ) )&lt;br /&gt;
                    .join( digit ) + input;&lt;br /&gt;
            },&lt;br /&gt;
            $lastLogLineEndSpan,&lt;br /&gt;
            log = function( what, time, color ) {&lt;br /&gt;
                var $logline = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
                    .text( pad( '0', 5, time ) + ': ' + what );&lt;br /&gt;
                if ( color ) $logline.css( 'color', color );&lt;br /&gt;
                $lastLogLineEndSpan = $( '&amp;lt;span&amp;gt;' )&lt;br /&gt;
                    .appendTo( $logline );&lt;br /&gt;
                $progConsole.append( $logline );&lt;br /&gt;
                $progConsole.clearQueue()&lt;br /&gt;
                    .animate( {&lt;br /&gt;
                        scrollTop: $progConsole.scrollTop() + $logline.position()&lt;br /&gt;
                            .top&lt;br /&gt;
                    }, 800 );&lt;br /&gt;
            },&lt;br /&gt;
            logInlineProgress = function( what ) {&lt;br /&gt;
                if ( $lastLogLineEndSpan ) $lastLogLineEndSpan.text( what );&lt;br /&gt;
            },&lt;br /&gt;
            $progTextDiv = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;Ready. Selecting a file will immediately start the upload.&amp;quot; )&lt;br /&gt;
            .appendTo( $progDiv ),&lt;br /&gt;
            $options = $( '&amp;lt;fieldset&amp;gt;' )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $optionsL = $( '&amp;lt;legend&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;Upload options&amp;quot; )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $czWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $czl = $( '&amp;lt;label for=&amp;quot;chunksize' + instanceId + '&amp;quot; style=&amp;quot;display:block&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;Chunk size: &amp;quot; )&lt;br /&gt;
            .appendTo( $czWrap ),&lt;br /&gt;
            $czlz = $( '&amp;lt;span&amp;gt;' )&lt;br /&gt;
            .appendTo( $czl ),&lt;br /&gt;
            $cz = $( '&amp;lt;div id=&amp;quot;chunksize' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
            .css( {&lt;br /&gt;
                width: '98%'&lt;br /&gt;
            } )&lt;br /&gt;
            .slider( {&lt;br /&gt;
                max: 20480,&lt;br /&gt;
                min: 100,&lt;br /&gt;
                change: function( e, ui ) {&lt;br /&gt;
                    $czlz.text( ui.value + ' KiB' );&lt;br /&gt;
                },&lt;br /&gt;
                slide: function( e, ui ) {&lt;br /&gt;
                    $czlz.text( ui.value + ' KiB' );&lt;br /&gt;
                }&lt;br /&gt;
            } )&lt;br /&gt;
            .slider( 'option', 'value', 4096 )&lt;br /&gt;
            .appendTo( $czWrap ),&lt;br /&gt;
            $useStashWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $useStash = $( '&amp;lt;input type=&amp;quot;checkbox&amp;quot; checked=&amp;quot;checked&amp;quot; id=&amp;quot;usestash' + instanceId + '&amp;quot; /&amp;gt;' )&lt;br /&gt;
            .appendTo( $useStashWrap ),&lt;br /&gt;
            $useStashL = $( '&amp;lt;label for=&amp;quot;usestash' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot; use stash and async (recommended for large videos and photos)&amp;quot; )&lt;br /&gt;
            .appendTo( $useStashWrap ),&lt;br /&gt;
            $fnWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $fnl = $( '&amp;lt;label for=&amp;quot;filename' + instanceId + '&amp;quot; style=&amp;quot;display:block&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;File name: &amp;quot; )&lt;br /&gt;
            .appendTo( $fnWrap ),&lt;br /&gt;
            $fn = $( '&amp;lt;input type=&amp;quot;text&amp;quot; style=&amp;quot;width:98%&amp;quot; placeholder=&amp;quot;File:Filename.ext&amp;quot; title=&amp;quot;file name goes here&amp;quot; id=&amp;quot;filename' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
            .val( mw.config.get( 'wgPageName' ) )&lt;br /&gt;
            .appendTo( $fnWrap ),&lt;br /&gt;
            $sumWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $suml = $( '&amp;lt;label for=&amp;quot;summary' + instanceId + '&amp;quot; style=&amp;quot;display:block&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( modeNewFile ? &amp;quot;File description&amp;quot; : &amp;quot;Summary or Reason: &amp;quot; )&lt;br /&gt;
            .appendTo( $sumWrap ),&lt;br /&gt;
            $sum = ( modeNewFile ? $( '&amp;lt;textarea style=&amp;quot;width:98%; height: 7em;&amp;quot; placeholder=&amp;quot;File description&amp;quot; title=&amp;quot;file description goes here&amp;quot; id=&amp;quot;summary' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
                .appendTo( $sumWrap ) : $( '&amp;lt;input type=&amp;quot;text&amp;quot; style=&amp;quot;width:98%&amp;quot; placeholder=&amp;quot;Reason/Summary&amp;quot; title=&amp;quot;reason/summary go here&amp;quot; id=&amp;quot;summary' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
                .appendTo( $sumWrap ) ),&lt;br /&gt;
            $fsel = $( '&amp;lt;input type=&amp;quot;file&amp;quot; id=&amp;quot;files&amp;quot; name=&amp;quot;file&amp;quot; style=&amp;quot;width:98%&amp;quot;&amp;gt;' )&lt;br /&gt;
            .appendTo( $options )&lt;br /&gt;
            .change( function( e ) {&lt;br /&gt;
                start = new Date();&lt;br /&gt;
&lt;br /&gt;
                var lastdate,&lt;br /&gt;
                    oldOnBeforeUnload = window.onbeforeunload,&lt;br /&gt;
                    oldDocTitle = document.title,&lt;br /&gt;
                    filename = ucFirst( $fn.val()&lt;br /&gt;
                        .replace( /File:/, '' )&lt;br /&gt;
                        .replace( /_/g, ' ' ) ),&lt;br /&gt;
                    lastblink,&lt;br /&gt;
                    _blink = function( $node ) {&lt;br /&gt;
                        if ( lastblink ) clearTimeout( lastblink );&lt;br /&gt;
                        $node.addClass( 'ui-state-error' );&lt;br /&gt;
                        setTimeout( function() {&lt;br /&gt;
                            $node.removeClass( 'ui-state-error' );&lt;br /&gt;
                        }, 1000 );&lt;br /&gt;
                    },&lt;br /&gt;
                    _onLogInRequired = function( err, callWhenDone ) {&lt;br /&gt;
                        var _onNodeClick = function() {&lt;br /&gt;
                            $logInRequired.unbind( 'click', _onNodeClick )&lt;br /&gt;
                                .hide();&lt;br /&gt;
                            callWhenDone();&lt;br /&gt;
                        };&lt;br /&gt;
                        $logInRequired.find( 'span' )&lt;br /&gt;
                            .first()&lt;br /&gt;
                            .remove();&lt;br /&gt;
                        $logInRequired.append( $( '&amp;lt;span&amp;gt;' )&lt;br /&gt;
                                .text( err ) )&lt;br /&gt;
                            .show()&lt;br /&gt;
                            .click( _onNodeClick );&lt;br /&gt;
                    },&lt;br /&gt;
                    _onUploadProgress = function( progressCalculated, date ) {&lt;br /&gt;
                        if ( !lastdate ) lastdate = start;&lt;br /&gt;
                        if ( ( date - lastdate ) &amp;lt; 200 &amp;amp;&amp;amp; progressCalculated !== 1 ) return;&lt;br /&gt;
                        lastdate = date;&lt;br /&gt;
                        progressCalculated = Math.round( progressCalculated, 1 );&lt;br /&gt;
                        logInlineProgress( ' Upload: ' + progressCalculated + '%' );&lt;br /&gt;
                    },&lt;br /&gt;
                    _updateProgressBar = function( progressCalculated, date ) {&lt;br /&gt;
                        if ( !lastdate ) lastdate = start;&lt;br /&gt;
                        if ( ( date - lastdate ) &amp;lt; 200 &amp;amp;&amp;amp; progressCalculated !== 100 ) return;&lt;br /&gt;
                        $progBar.progressbar( 'option', 'value', progressCalculated );&lt;br /&gt;
                        document.title = Math.round( progressCalculated ) + &amp;quot;% of &amp;quot; + filename + &amp;quot; uploaded  - Chunked upload - Wikimedia Commons&amp;quot;;&lt;br /&gt;
                    };&lt;br /&gt;
&lt;br /&gt;
                if ( !filename ) return _blink( $fn );&lt;br /&gt;
&lt;br /&gt;
                var params = {&lt;br /&gt;
                    maxChunkSize: $cz.slider( 'option', 'value' ) * 1024,&lt;br /&gt;
                    retry: {&lt;br /&gt;
                        serverError: 250&lt;br /&gt;
                    },&lt;br /&gt;
                    title: $fn.val()&lt;br /&gt;
                        .replace( /File:/, '' ),&lt;br /&gt;
                    summary: '[[c:User:Rillke/bigChunkedUpload.js]]: ' + $sum.val(),&lt;br /&gt;
                    useStash: $useStash.prop( 'checked' ),&lt;br /&gt;
                    async: $useStash.prop( 'checked' ),&lt;br /&gt;
                    passToAPI: {&lt;br /&gt;
                        upload: {&lt;br /&gt;
                            ignorewarnings: 1&lt;br /&gt;
                        },&lt;br /&gt;
                        finish: {&lt;br /&gt;
                            ignorewarnings: 1&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    callbacks: {&lt;br /&gt;
                        loginRequired: _onLogInRequired&lt;br /&gt;
                    }&lt;br /&gt;
                };&lt;br /&gt;
                if ( modeNewFile ) {&lt;br /&gt;
                    params.text = $sum.val();&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                var $def = new MwJSBot()&lt;br /&gt;
                    .chunkedUpload( params, this.files[ 0 ] )&lt;br /&gt;
                    .progress( function( type, chunkinfo, txt ) {&lt;br /&gt;
                        var cc = chunkinfo.currentchunk,&lt;br /&gt;
                            idIsNumber = ( 'number' === typeof cc.id ),&lt;br /&gt;
                            curIdPlus1 = idIsNumber ? ( cc.id + 1 ) : cc.id,&lt;br /&gt;
                            curId = idIsNumber ? cc.id : 0,&lt;br /&gt;
                            l = chunkinfo.length,&lt;br /&gt;
                            progressCalculated = ( ( curId ) / l ) * 100 + ( cc.progress / l ),&lt;br /&gt;
                            d = new Date(),&lt;br /&gt;
                            ddiff = Math.round( ( d - start ) / 1000 ),&lt;br /&gt;
                            prog = '',&lt;br /&gt;
                            color = '';&lt;br /&gt;
&lt;br /&gt;
                        // second term respects progress of current chunk&lt;br /&gt;
                        if ( idIsNumber ) _updateProgressBar( progressCalculated );&lt;br /&gt;
&lt;br /&gt;
                        // handle these often frequently occuring events differently&lt;br /&gt;
                        if ( 'uploadstatus' === type ) {&lt;br /&gt;
                            return _onUploadProgress( cc.progress, d );&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        txt = txt || cc.progressText;&lt;br /&gt;
                        prog += &amp;quot;Uploaded part &amp;quot; + curIdPlus1 + &amp;quot; of &amp;quot; + l + &amp;quot;;&amp;quot;;&lt;br /&gt;
                        prog += &amp;quot; Time elapsed: &amp;quot; + ddiff + &amp;quot;s ;&amp;quot;;&lt;br /&gt;
                        prog += &amp;quot; Status: &amp;quot; + txt;&lt;br /&gt;
                        $progTextDiv.text( prog );&lt;br /&gt;
                        switch ( type ) {&lt;br /&gt;
                            case 'err':&lt;br /&gt;
                            case 'stuck':&lt;br /&gt;
                                color = '#E9D977';&lt;br /&gt;
                                break;&lt;br /&gt;
                            default:&lt;br /&gt;
                                break;&lt;br /&gt;
                        }&lt;br /&gt;
                        log( curIdPlus1 + '/' + l + '&amp;gt; ' + txt, ddiff, color );&lt;br /&gt;
&lt;br /&gt;
                    } )&lt;br /&gt;
                    .done( function() {&lt;br /&gt;
                        var txt = &amp;quot;DONE.&amp;quot;,&lt;br /&gt;
                            d = new Date(),&lt;br /&gt;
                            ddiff = Math.round( ( d - start ) / 1000 );&lt;br /&gt;
&lt;br /&gt;
                        $progDiv.text( txt );&lt;br /&gt;
                        log( txt, ddiff, '#77E9C7' );&lt;br /&gt;
                        window.onbeforeunload = oldOnBeforeUnload;&lt;br /&gt;
                        window.location.href = &amp;quot;/wiki/File:&amp;quot; + encodeURIComponent( $fn.val()&lt;br /&gt;
                            .replace( /^File:/i, &amp;quot;&amp;quot; ) );&lt;br /&gt;
                    } )&lt;br /&gt;
                    .fail( function( txt ) {&lt;br /&gt;
                        txt = &amp;quot;FAILED: &amp;quot; + txt;&lt;br /&gt;
&lt;br /&gt;
                        var d = new Date(),&lt;br /&gt;
                            ddiff = Math.round( ( d - start ) / 1000 );&lt;br /&gt;
&lt;br /&gt;
                        $progDiv.text( txt );&lt;br /&gt;
                        log( txt, ddiff, '#E977C7' );&lt;br /&gt;
                        window.onbeforeunload = oldOnBeforeUnload;&lt;br /&gt;
                        document.title = &amp;quot;FAILED! File upload failed - Chunked upload - Wikimedia Commons&amp;quot;;&lt;br /&gt;
                        setTimeout( function() {&lt;br /&gt;
                            document.title = oldDocTitle;&lt;br /&gt;
                        }, 10000 );&lt;br /&gt;
                    } );&lt;br /&gt;
&lt;br /&gt;
                $fn.add( $sum )&lt;br /&gt;
                    .add( $fsel )&lt;br /&gt;
                    .add( $useStash )&lt;br /&gt;
                    .attr( 'disabled', 'disabled' );&lt;br /&gt;
                $cz.slider( 'option', 'disabled', true );&lt;br /&gt;
&lt;br /&gt;
                // Prevent leaving the page accidentally&lt;br /&gt;
                window.onbeforeunload = function() {&lt;br /&gt;
                    return &amp;quot;Upload seems to be still in progress. Do you really wish to quit?&amp;quot;;&lt;br /&gt;
                };&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
        $dlg.dialog( {&lt;br /&gt;
            'title': &amp;quot;Overwrite existing files using Chunked Upload protocol&amp;quot;,&lt;br /&gt;
            //'height': $(window).height(),&lt;br /&gt;
            'width': w&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Set focus to summary-field&lt;br /&gt;
        $sum.focus();&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // Register globally&lt;br /&gt;
    if ( $.inArray( mw.config.get( 'wgDBname' ), [ 'commonswiki', 'commonsarchivewiki' ] ) &amp;lt; 0 ) {&lt;br /&gt;
        // mw.loader.addSource has a check for source key uniqueness&lt;br /&gt;
        // that if it fails, throws an error.&lt;br /&gt;
        // Since I am offering many scripts, I would like to be able to register&lt;br /&gt;
        // a source from multiple code positions. However the loader has no&lt;br /&gt;
        // accessors to its internally maintained list of sources. Therefore&lt;br /&gt;
        // ensure with high probabiltiy that every source key added is unique.&lt;br /&gt;
        commonsWiki[commonwWikiKey] = &amp;quot;//wiki.neverlands.ru/load.php&amp;quot;;&lt;br /&gt;
        mw.loader.addSource( commonsWiki );&lt;br /&gt;
&lt;br /&gt;
        // Register Commons RL modules&lt;br /&gt;
        for (i = 0; i &amp;lt; modules.length; i++) {&lt;br /&gt;
            if (mw.loader.getState( modules[i][0] ) === null) {&lt;br /&gt;
                mw.loader.register([modules[i]]);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mw.loader.using( [ 'ext.gadget.editDropdown', 'mediawiki.util', 'mediawiki.Title' ], _install );&lt;br /&gt;
&lt;br /&gt;
}( jQuery, mediaWiki ) );&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/MwJSBot.js</id>
		<title>Участник:Kolbaska/MwJSBot.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/MwJSBot.js"/>
				<updated>2025-11-14T04:13:51Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;// Usage:&lt;br /&gt;
// mw.loader.implement('mediawiki.commons.MwJSBot', [&amp;quot;//wiki.neverlands.ru/index.php?action=raw&amp;amp;ctype=text/javascript&amp;amp;title=User:Kolbaska/MwJSBot.js&amp;amp;_=2&amp;quot;], {/*no styles*/}, {/*no messages*/});&lt;br /&gt;
// mw.loader.load('mediawiki.commons.MwJSBot');&lt;br /&gt;
&lt;br /&gt;
/* global jQuery:false, mediaWiki:false, unescape:false, console:false, File, Blob, MwJSBot */&lt;br /&gt;
/* eslint indent:[error,tab,{outerIIFEBody:0}] */&lt;br /&gt;
/* jshint curly:false, bitwise:false, unused:false */&lt;br /&gt;
&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
var myModuleName = 'mediawiki.commons.MwJSBot',&lt;br /&gt;
	isCommonsWiki = mw.config.get( 'wgDBname' ) === 'commonswiki';&lt;br /&gt;
&lt;br /&gt;
function ContinuousAverage() {&lt;br /&gt;
	this.n = 0;&lt;br /&gt;
	this.avg = null;&lt;br /&gt;
	this.lastDateTime = Date.now();&lt;br /&gt;
}&lt;br /&gt;
ContinuousAverage.fn = ContinuousAverage.prototype;&lt;br /&gt;
$.extend( true, ContinuousAverage.fn, {&lt;br /&gt;
	push: function ( val ) {&lt;br /&gt;
		if ( this.avg === null ) {&lt;br /&gt;
			this.avg = val;&lt;br /&gt;
			this.n = 1;&lt;br /&gt;
		} else {&lt;br /&gt;
			this.avg = ( this.avg * this.n + val ) / ( ++this.n );&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	pushTimeDiff: function ( now ) {&lt;br /&gt;
		now = now || Date.now();&lt;br /&gt;
		this.push( now - this.lastDateTime );&lt;br /&gt;
		this.lastDateTime = now;&lt;br /&gt;
	},&lt;br /&gt;
	getN: function () {&lt;br /&gt;
		return this.n;&lt;br /&gt;
	},&lt;br /&gt;
	getAvg: function () {&lt;br /&gt;
		return this.avg;&lt;br /&gt;
	}&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
function firstItem( o ) {&lt;br /&gt;
	for ( var i in o ) {&lt;br /&gt;
		if ( o.hasOwnProperty( i ) ) {&lt;br /&gt;
			return o[ i ];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function encode_utf8( s ) {&lt;br /&gt;
	return unescape( encodeURIComponent( s ) );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var jsb = function () {},&lt;br /&gt;
	clnt = $.client.profile(),&lt;br /&gt;
	APIURL = mw.util.wikiScript( 'api' ),&lt;br /&gt;
	MPB = '----------' + myModuleName + Math.random();&lt;br /&gt;
&lt;br /&gt;
jsb.fn = jsb.prototype;&lt;br /&gt;
&lt;br /&gt;
$.extend( true, jsb.fn, {&lt;br /&gt;
	$downloadRawFile: function ( url ) {&lt;br /&gt;
		return $.ajax( {&lt;br /&gt;
			url: url,&lt;br /&gt;
			beforeSend: function ( xhr ) {&lt;br /&gt;
				xhr.overrideMimeType( 'text/plain; charset=x-user-defined' );&lt;br /&gt;
			},&lt;br /&gt;
			dataFilter: function ( d/* , dataType*/ ) {&lt;br /&gt;
				// Some more sophisticated stuff avoiding killing performance with memory allocations and thousands of function invocations&lt;br /&gt;
				// https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays would be perhaps also valuable&lt;br /&gt;
				var f = '',&lt;br /&gt;
					len = d.length,&lt;br /&gt;
					buff = 1018, // You can't apply huge arrays to functions!&lt;br /&gt;
					arrCC = new Array( Math.min( buff, len ) ),&lt;br /&gt;
					arrF = new Array( Math.ceil( len / buff ) );&lt;br /&gt;
&lt;br /&gt;
				// Remove junk-high-order-bytes&lt;br /&gt;
				for ( var i = 0, j = 0, z = 0; i &amp;lt; len; i++ ) {&lt;br /&gt;
					arrCC[ j ] = ( d.charCodeAt( i ) &amp;amp; 0xff );&lt;br /&gt;
					j++;&lt;br /&gt;
					if ( ( j % buff ) === 0 ) {&lt;br /&gt;
						// Convert char codes to chars&lt;br /&gt;
						arrF[ z ] = String.fromCharCode.apply( null, arrCC );&lt;br /&gt;
						// Empty the char code array&lt;br /&gt;
						arrCC = new Array( Math.min( buff, len - i - 1 ) );&lt;br /&gt;
						z++;&lt;br /&gt;
						j = 0;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				if ( j !== 0 ) { arrF[ z + 1 ] = String.fromCharCode.apply( null, arrCC ); }&lt;br /&gt;
				f = arrF.join( '' );&lt;br /&gt;
				return f;&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	},&lt;br /&gt;
	$downloadXMLFile: function ( url ) {&lt;br /&gt;
		return $.get( url, 'xml' );&lt;br /&gt;
	},&lt;br /&gt;
	// NEVER use this twice to send something. Instead, create a new message!&lt;br /&gt;
	// TODO allow/review re-sending same message again&lt;br /&gt;
	multipartMessageForBinaryFiles: function () {&lt;br /&gt;
		// Body parts that must be considered to end with line breaks, therefore, should have two CRLFs preceding the encapsulation line,&lt;br /&gt;
		// the first of which is part of the preceding body part, and the second of which is part of the encapsulation boundary&lt;br /&gt;
		var pendingParts = 0,&lt;br /&gt;
			tokenPart = '',&lt;br /&gt;
			useStuckWatcher = true,&lt;br /&gt;
			msgParts,&lt;br /&gt;
			createPart,&lt;br /&gt;
			appendPart,&lt;br /&gt;
			send,&lt;br /&gt;
			formData;&lt;br /&gt;
&lt;br /&gt;
		if ( clnt.name === 'firefox' &amp;amp;&amp;amp; clnt.versionNumber &amp;lt; 22 ) {&lt;br /&gt;
			msgParts = [];&lt;br /&gt;
			createPart = function ( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) {&lt;br /&gt;
				var p = '--' + MPB + '\r\n';&lt;br /&gt;
				if ( !ContentDisposition ) {&lt;br /&gt;
					p += 'Content-Disposition: form-data; name=\&amp;quot;' + param + '\&amp;quot;\r\n';&lt;br /&gt;
				} else {&lt;br /&gt;
					p += 'Content-Disposition: ' + ContentDisposition + '\r\n';&lt;br /&gt;
				}&lt;br /&gt;
				p += 'Content-Type: ' + ContentType + '\r\n';&lt;br /&gt;
				p += 'Content-Transfer-Encoding: ' + ContentTransferEncoding + '\r\n';&lt;br /&gt;
				return [ p, '\r\n', value, '\r\n' ].join( '' );&lt;br /&gt;
			};&lt;br /&gt;
			appendPart = function ( param, value, filename, MIME ) {&lt;br /&gt;
				var ContentType, ContentTransferEncoding, ContentDisposition, doPush = function ( value ) {&lt;br /&gt;
					msgParts.push( createPart( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) );&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				if ( filename ) {&lt;br /&gt;
					ContentType = MIME || 'application/octet-stream';&lt;br /&gt;
					ContentTransferEncoding = 'binary';&lt;br /&gt;
					ContentDisposition = 'attachment; name=\&amp;quot;' + param + '\&amp;quot;; filename=\&amp;quot;' + encode_utf8( filename.replace( /\&amp;quot;/g, '-' ) ) + '\&amp;quot;';&lt;br /&gt;
					if ( value instanceof Blob || value instanceof File ) {&lt;br /&gt;
						pendingParts++;&lt;br /&gt;
						var reader = new FileReader();&lt;br /&gt;
						reader.onload = function () {&lt;br /&gt;
							value = reader.result;&lt;br /&gt;
							doPush( value );&lt;br /&gt;
							if ( tokenPart ) { msgParts.push( tokenPart ); }&lt;br /&gt;
							pendingParts--;&lt;br /&gt;
							if ( pendingParts === 0 &amp;amp;&amp;amp; typeof send === 'function' ) { send(); }&lt;br /&gt;
						};&lt;br /&gt;
						reader.readAsBinaryString( value );&lt;br /&gt;
						return;&lt;br /&gt;
					}&lt;br /&gt;
				} else {&lt;br /&gt;
					value = encode_utf8( value );&lt;br /&gt;
					ContentType = 'text/plain; charset=UTF-8';&lt;br /&gt;
					ContentTransferEncoding = '8bit';&lt;br /&gt;
					if ( param === 'token' &amp;amp;&amp;amp; pendingParts ) {&lt;br /&gt;
						// Ensure token last (This is done to catch connection errors. This way we can circumvent calculating MD5)&lt;br /&gt;
						tokenPart = createPart( param, value, ContentType, ContentTransferEncoding, ContentDisposition );&lt;br /&gt;
						return;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				doPush( value );&lt;br /&gt;
			};&lt;br /&gt;
		} else {&lt;br /&gt;
			formData = new FormData();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var msg = {&lt;br /&gt;
			appendPart: function ( param, value, filename, MIME ) {&lt;br /&gt;
				if ( msgParts ) {&lt;br /&gt;
					appendPart.apply( window, Array.prototype.slice.call( arguments, 0 ) );&lt;br /&gt;
				} else {&lt;br /&gt;
					if ( filename ) {&lt;br /&gt;
						var bl;&lt;br /&gt;
						if ( value instanceof Blob || value instanceof File ) {&lt;br /&gt;
							bl = value;&lt;br /&gt;
						} else {&lt;br /&gt;
							bl = new Blob( [ value ], { type: MIME || 'application/octet-stream' } );&lt;br /&gt;
						}&lt;br /&gt;
						formData.append( param, bl, filename );&lt;br /&gt;
					} else {&lt;br /&gt;
						formData.append( param, value );&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				// allow something like new MwJSBot().multipartMessage().appendPart(&amp;quot;param1&amp;quot;, &amp;quot;value&amp;quot;).appendPart(&amp;quot;param2&amp;quot;, &amp;quot;value&amp;quot;).$send();&lt;br /&gt;
				return msg;&lt;br /&gt;
			},&lt;br /&gt;
			noStuckWatcher: function () {&lt;br /&gt;
				useStuckWatcher = false;&lt;br /&gt;
				return msg;&lt;br /&gt;
			},&lt;br /&gt;
			$send: function ( url, responseType ) {&lt;br /&gt;
				var $def = $.Deferred();&lt;br /&gt;
&lt;br /&gt;
				send = function () {&lt;br /&gt;
					var req = new XMLHttpRequest(),&lt;br /&gt;
						ca = new ContinuousAverage(),&lt;br /&gt;
						lastProgressEvt, intervalId, killProgressWatchers, progressWatcher;&lt;br /&gt;
&lt;br /&gt;
					// Browsers sometimes have the attitude not to continue uploading&lt;br /&gt;
					// upon network interruptions but they send new requests correctly&lt;br /&gt;
					killProgressWatchers = function () {&lt;br /&gt;
						clearInterval( intervalId );&lt;br /&gt;
					};&lt;br /&gt;
					progressWatcher = function () {&lt;br /&gt;
						var now = Date.now(),&lt;br /&gt;
							diff = now - lastProgressEvt;&lt;br /&gt;
&lt;br /&gt;
						if ( ca.getN() &amp;gt; 10 &amp;amp;&amp;amp; diff &amp;gt; ca.getAvg() * 5 &amp;amp;&amp;amp; diff &amp;gt; 7000 ) {&lt;br /&gt;
							$def.notify( 'stuck', req );&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
					req.onreadystatechange = function () {&lt;br /&gt;
						if ( req.readyState !== 4 ) { return; }&lt;br /&gt;
						if ( req.status === 200 ) {&lt;br /&gt;
							// TODO: Pass more args&lt;br /&gt;
							$def.resolve( req.statusText, req.response );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						} else {&lt;br /&gt;
							$def.reject( req.statusText, req.response, req );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
					req.onerror = function () {&lt;br /&gt;
						setTimeout( function () {&lt;br /&gt;
							$def.reject( req.statusText, req.response, req );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						}, 100 );&lt;br /&gt;
					};&lt;br /&gt;
					req.onabort = function () {&lt;br /&gt;
						setTimeout( function () {&lt;br /&gt;
							$def.reject( req.statusText, req.response, req );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						}, 100 );&lt;br /&gt;
					};&lt;br /&gt;
					// Can we monitor upload status?&lt;br /&gt;
					if ( req.upload ) {&lt;br /&gt;
						req.upload.onprogress = function ( e ) {&lt;br /&gt;
							// Ensure compatible event&lt;br /&gt;
							if ( !e.loaded || !e.total ) { return; }&lt;br /&gt;
							$def.notify( 'uploadstatus', e );&lt;br /&gt;
							lastProgressEvt = Date.now();&lt;br /&gt;
							ca.pushTimeDiff( lastProgressEvt );&lt;br /&gt;
						};&lt;br /&gt;
					}&lt;br /&gt;
					req.open( 'POST', url || APIURL );&lt;br /&gt;
					if ( responseType ) {&lt;br /&gt;
						req.responseType = responseType;&lt;br /&gt;
					}&lt;br /&gt;
					if ( useStuckWatcher ) {&lt;br /&gt;
						intervalId = setInterval( progressWatcher, 5000 );&lt;br /&gt;
					}&lt;br /&gt;
					if ( msgParts ) {&lt;br /&gt;
						req.setRequestHeader( 'Content-Type', 'multipart/form-data; charset=UTF-8; boundary=' + MPB );&lt;br /&gt;
						msgParts.push( '--', MPB, '--', '\r\n' );&lt;br /&gt;
						req.sendAsBinary( msgParts.join( '' ) );&lt;br /&gt;
					} else {&lt;br /&gt;
						req.send( formData );&lt;br /&gt;
					}&lt;br /&gt;
				};&lt;br /&gt;
				if ( pendingParts === 0 ) {&lt;br /&gt;
					send();&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				return $def;&lt;br /&gt;
			}&lt;br /&gt;
		};&lt;br /&gt;
		return msg;&lt;br /&gt;
	},&lt;br /&gt;
	multipartMessageForUTF8Files: function () {&lt;br /&gt;
		var msgParts,&lt;br /&gt;
			createPart,&lt;br /&gt;
			appendPart;&lt;br /&gt;
&lt;br /&gt;
		msgParts = [];&lt;br /&gt;
		createPart = function ( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) {&lt;br /&gt;
			var p = '--' + MPB + '\n';&lt;br /&gt;
			if ( !ContentDisposition ) {&lt;br /&gt;
				p += 'Content-Disposition: form-data; name=\&amp;quot;' + param + '\&amp;quot;\n';&lt;br /&gt;
			} else {&lt;br /&gt;
				p += 'Content-Disposition: ' + ContentDisposition + '\n';&lt;br /&gt;
			}&lt;br /&gt;
			p += 'Content-Type: ' + ContentType + '\n';&lt;br /&gt;
			p += 'Content-Transfer-Encoding: ' + ContentTransferEncoding + '\n';&lt;br /&gt;
			return [ p, '\n', value, '\n' ].join( '' );&lt;br /&gt;
		};&lt;br /&gt;
		appendPart = function ( param, value, filename ) {&lt;br /&gt;
			var ContentType, ContentTransferEncoding, ContentDisposition;&lt;br /&gt;
			if ( filename ) {&lt;br /&gt;
				ContentType = 'application/octet-stream';&lt;br /&gt;
				ContentTransferEncoding = '8bit';&lt;br /&gt;
				ContentDisposition = 'attachment; name=\&amp;quot;' + param + '\&amp;quot;; filename=\&amp;quot;' + filename.replace( /\&amp;quot;/g, '-' ) + '\&amp;quot;';&lt;br /&gt;
			} else {&lt;br /&gt;
				ContentType = 'text/plain; charset=UTF-8';&lt;br /&gt;
				ContentTransferEncoding = '8bit';&lt;br /&gt;
			}&lt;br /&gt;
			msgParts.push( createPart( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) );&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		var msg = {&lt;br /&gt;
			appendPart: function ( /* param, value, filename*/ ) {&lt;br /&gt;
				appendPart.apply( window, Array.prototype.slice.call( arguments, 0 ) );&lt;br /&gt;
				// allow something like new MwJSBot().multipartMessage().appendPart(&amp;quot;param1&amp;quot;, &amp;quot;value&amp;quot;).appendPart(&amp;quot;param2&amp;quot;, &amp;quot;value&amp;quot;).$send();&lt;br /&gt;
				return msg;&lt;br /&gt;
			},&lt;br /&gt;
			$send: function ( url, responseType ) {&lt;br /&gt;
				var $def = $.Deferred(),&lt;br /&gt;
&lt;br /&gt;
					req = new XMLHttpRequest();&lt;br /&gt;
				req.onreadystatechange = function () {&lt;br /&gt;
					if ( req.readyState !== 4 ) { return; }&lt;br /&gt;
					if ( req.status === 200 ) {&lt;br /&gt;
						// TODO: Pass more args&lt;br /&gt;
						$def.resolve( req.statusText, req.response );&lt;br /&gt;
					} else {&lt;br /&gt;
						$def.reject( req.response );&lt;br /&gt;
					}&lt;br /&gt;
				};&lt;br /&gt;
				req.open( 'POST', url || APIURL );&lt;br /&gt;
				if ( responseType ) {&lt;br /&gt;
					req.responseType = responseType;&lt;br /&gt;
				}&lt;br /&gt;
				req.setRequestHeader( 'Content-Type', 'multipart/form-data; charset=UTF-8; boundary=' + MPB );&lt;br /&gt;
				msgParts.push( '--', MPB, '--', '\n' );&lt;br /&gt;
				req.send( msgParts.join( '' ) );&lt;br /&gt;
				return $def;&lt;br /&gt;
			}&lt;br /&gt;
		};&lt;br /&gt;
		return msg;&lt;br /&gt;
	},&lt;br /&gt;
	refreshToken: function ( type, cb ) {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI', 'mediawiki.user' ], function () {&lt;br /&gt;
			/* FIXME: This is causing an error: Error: api.query is for queries only. For editing use the stable Commons edit-api. */&lt;br /&gt;
			return;&lt;br /&gt;
			mw.libs.commons.api.query( {&lt;br /&gt;
				action: 'tokens',&lt;br /&gt;
				type: type&lt;br /&gt;
			}, {&lt;br /&gt;
				method: 'POST',&lt;br /&gt;
				cache: false,&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$.each( r.tokens, function ( type, v ) {&lt;br /&gt;
						type = type.replace( 'token', 'Token' );&lt;br /&gt;
						mw.user.tokens.set( type, v );&lt;br /&gt;
					} );&lt;br /&gt;
					cb();&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( /* t, r, q */ ) {&lt;br /&gt;
					j.fail( 'Failed to refresh token.' );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	},&lt;br /&gt;
	chunkedUploadDefault: {&lt;br /&gt;
		maxChunkSize: 0.5 * 1024 * 1024, // 2MB&lt;br /&gt;
		retry: {&lt;br /&gt;
			emptyResponse: 9,&lt;br /&gt;
			serverError: 9,&lt;br /&gt;
			apiErrors: 6,&lt;br /&gt;
			offsetError: 2&lt;br /&gt;
		},&lt;br /&gt;
		file: null,&lt;br /&gt;
		title: '',&lt;br /&gt;
		summary: '',&lt;br /&gt;
		useStash: true,&lt;br /&gt;
		async: true,&lt;br /&gt;
		callbacks: {&lt;br /&gt;
			nameNeedsChange: function () {},&lt;br /&gt;
			ignorewarningsRequired: function () {},&lt;br /&gt;
			loginRequired: function () {}&lt;br /&gt;
		},&lt;br /&gt;
		passToAPI: {&lt;br /&gt;
			upload: {&lt;br /&gt;
				// e.g. ignorewarnings: 1&lt;br /&gt;
				tags: isCommonsWiki ? 'rillke-mw-js-bot' : ''&lt;br /&gt;
			},&lt;br /&gt;
			finish: {&lt;br /&gt;
				tags: isCommonsWiki ? 'rillke-mw-js-bot' : ''&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	uploadWarnings: {&lt;br /&gt;
		filename: [ 'exists', 'page-exists', 'was-deleted', 'exists-normalized', 'thumb', 'thumb-name', 'bad-prefix', 'badfilename' ],&lt;br /&gt;
		other: [ 'duplicate-archive', 'duplicate', 'large-file', 'emptyfile', 'filetype-unwanted-type' ]&lt;br /&gt;
	},&lt;br /&gt;
	chunkedUpload: function ( p, file ) {&lt;br /&gt;
		var j = this,&lt;br /&gt;
			$def = $.Deferred(),&lt;br /&gt;
			filekey = '',&lt;br /&gt;
			size = 0,&lt;br /&gt;
			remaining = 0,&lt;br /&gt;
			chunkSize = 0,&lt;br /&gt;
			offset = 0,&lt;br /&gt;
			offsetid = 0,&lt;br /&gt;
			addToNextChunk = 0,&lt;br /&gt;
			stuckCounter = 0,&lt;br /&gt;
			chunkinfo = [],&lt;br /&gt;
			waitingFinish,&lt;br /&gt;
			startTime,&lt;br /&gt;
			waitTime,&lt;br /&gt;
			$stuckXhr;&lt;br /&gt;
&lt;br /&gt;
		p = $.extend( true, {}, j.chunkedUploadDefault, p );&lt;br /&gt;
		if ( !file || !p.title ) {&lt;br /&gt;
			return j.fail( 'chunked upload&amp;gt; Either no file or no title specified.' );&lt;br /&gt;
		}&lt;br /&gt;
		if ( !( window.File &amp;amp;&amp;amp; window.File.prototype.slice &amp;amp;&amp;amp; window.FileReader &amp;amp;&amp;amp; window.Blob ) ) {&lt;br /&gt;
			return j.fail( 'chunked upload&amp;gt; Your browser does not support the full File-API, FileReader and Blob.' );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var internal = {&lt;br /&gt;
			status: 'uploading',&lt;br /&gt;
			uploadAPI: function ( params ) {&lt;br /&gt;
				params = $.extend( {&lt;br /&gt;
					format: 'json',&lt;br /&gt;
					action: 'upload',&lt;br /&gt;
					filekey: filekey,&lt;br /&gt;
					token: mw.user.tokens.get( 'csrfToken' )&lt;br /&gt;
				}, params );&lt;br /&gt;
				return $.post( APIURL, params );&lt;br /&gt;
			},&lt;br /&gt;
			nextChunk: function () {&lt;br /&gt;
				chunkSize = Math.min( remaining, p.maxChunkSize + addToNextChunk );&lt;br /&gt;
				var blob = file.slice( offset, offset + chunkSize ),&lt;br /&gt;
					mpm = j.multipartMessageForBinaryFiles();&lt;br /&gt;
&lt;br /&gt;
				addToNextChunk = 0;&lt;br /&gt;
&lt;br /&gt;
				// Notify everyone who likes to know how the situation is progressing&lt;br /&gt;
				chunkinfo.currentchunk = chunkinfo[ offsetid ];&lt;br /&gt;
				$def.notify( 'prog', chunkinfo );&lt;br /&gt;
&lt;br /&gt;
				mpm.appendPart( 'format', 'json' );&lt;br /&gt;
				mpm.appendPart( 'action', 'upload' );&lt;br /&gt;
				mpm.appendPart( 'filename', p.title );&lt;br /&gt;
				if ( filekey ) { mpm.appendPart( 'filekey', filekey ); }&lt;br /&gt;
				if ( p.useStash ) { mpm.appendPart( 'stash', 1 ); }&lt;br /&gt;
				mpm.appendPart( 'filesize', size );&lt;br /&gt;
				mpm.appendPart( 'offset', offset );&lt;br /&gt;
				if ( p.async ) { mpm.appendPart( 'async', 1 ); }&lt;br /&gt;
				mpm.appendPart( 'chunk', blob, p.title, file.type );&lt;br /&gt;
				mpm.appendPart( 'token', mw.user.tokens.get( 'csrfToken' ) );&lt;br /&gt;
				$.each( p.passToAPI.upload, function ( k, v ) {&lt;br /&gt;
					mpm.appendPart( k, v );&lt;br /&gt;
				} );&lt;br /&gt;
				if ( !p.async ) { mpm.noStuckWatcher(); }&lt;br /&gt;
				startTime = Date.now();&lt;br /&gt;
				waitTime = 4000;&lt;br /&gt;
				mpm.$send().done( internal.chunkUploaded ).fail( internal.chunkFailed ).progress( internal.chunkUploadProgess );&lt;br /&gt;
			},&lt;br /&gt;
			chunkStuck: function ( xhr ) {&lt;br /&gt;
				if ( $stuckXhr ) {&lt;br /&gt;
					$stuckXhr.abort();&lt;br /&gt;
				}&lt;br /&gt;
				$stuckXhr = $.getJSON( APIURL, {&lt;br /&gt;
					format: 'json',&lt;br /&gt;
					action: 'tokens'&lt;br /&gt;
				} ).done( function () {&lt;br /&gt;
					// Connection Ok ... we can try to fix this&lt;br /&gt;
					if ( ++stuckCounter &amp;gt; 10 ) {&lt;br /&gt;
						stuckCounter = 0;&lt;br /&gt;
						chunkinfo.currentchunk.progressText = 'Connection seems to be okay. Re-sending this request.';&lt;br /&gt;
						p.retry.serverError += 0.8;&lt;br /&gt;
						xhr.abort();&lt;br /&gt;
					} else {&lt;br /&gt;
						chunkinfo.currentchunk.progressText = 'Connection seems to be okay. Waiting one more time...';&lt;br /&gt;
					}&lt;br /&gt;
					$def.notify( 'stuckok', chunkinfo );&lt;br /&gt;
				} ).fail( function ( jqXHR, textStatus, errorThrown ) {&lt;br /&gt;
					// Connection broken ... user or server admins have to fix this&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'Please check your connection! Error: ' + textStatus + ' | ' + errorThrown;&lt;br /&gt;
					$def.notify( 'stuckbroken', chunkinfo );&lt;br /&gt;
				} );&lt;br /&gt;
			},&lt;br /&gt;
			chunkUploadProgess: function ( type, e ) {&lt;br /&gt;
				switch ( type ) {&lt;br /&gt;
				case 'uploadstatus':&lt;br /&gt;
					stuckCounter = 0;&lt;br /&gt;
					chunkinfo.currentchunk.progress = 100 * e.loaded / e.total;&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'upload in progress';&lt;br /&gt;
					$def.notify( type, chunkinfo );&lt;br /&gt;
					break;&lt;br /&gt;
				case 'stuck':&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'upload is stuck';&lt;br /&gt;
					$def.notify( type, chunkinfo );&lt;br /&gt;
					internal.chunkStuck( e );&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			chunkUploaded: function ( status, r ) {&lt;br /&gt;
				stuckCounter = 0;&lt;br /&gt;
				r = JSON.parse( r );&lt;br /&gt;
				var txt, args, defaultError;&lt;br /&gt;
&lt;br /&gt;
				defaultError = function ( args ) {&lt;br /&gt;
					args = Array.prototype.slice.call( args, 0 );&lt;br /&gt;
					args.unshift( r.error.code + ': ' + r.error.info );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				if ( r &amp;amp;&amp;amp; r.error ) {&lt;br /&gt;
					switch ( r.error.code ) {&lt;br /&gt;
					// r.error.info&lt;br /&gt;
					case 'badtoken':&lt;br /&gt;
						j.refreshToken( 'edit', $.proxy( internal.nextChunk, internal ) );&lt;br /&gt;
						break;&lt;br /&gt;
					case 'stasherror':&lt;br /&gt;
						if ( r.error.info.indexOf( 'UploadStashNotLoggedInException' ) === -1 ) {&lt;br /&gt;
							return defaultError( arguments );&lt;br /&gt;
						}&lt;br /&gt;
						/* falls through */&lt;br /&gt;
					case 'readapidenied':&lt;br /&gt;
					case 'writeapidenied':&lt;br /&gt;
					case 'invalid-file-key':&lt;br /&gt;
					case 'mustbeloggedin':&lt;br /&gt;
					case 'permissiondenied':&lt;br /&gt;
					case 'internal_api_error_UploadStashNotLoggedInException':&lt;br /&gt;
					case 'stashnotloggedin':&lt;br /&gt;
						p.callbacks.loginRequired( r.error.code + ': ' + r.error.info, function () {&lt;br /&gt;
							j.refreshToken( 'edit', $.proxy( internal.nextChunk, internal ) );&lt;br /&gt;
						} );&lt;br /&gt;
						break;&lt;br /&gt;
					case 'stashfailed':&lt;br /&gt;
					case 'offseterror':&lt;br /&gt;
					case 'offsetmismatch':&lt;br /&gt;
						if ( --p.retry.apiErrors &amp;lt; 0 ) {&lt;br /&gt;
							return defaultError( arguments );&lt;br /&gt;
						}&lt;br /&gt;
						if ( r.error.offset &amp;amp;&amp;amp; Number( r.error.offset ) !== offset ) {&lt;br /&gt;
							return internal.offsetmismatch( arguments, Number( r.error.offset ) );&lt;br /&gt;
						}&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
						break;&lt;br /&gt;
					default:&lt;br /&gt;
						return defaultError( arguments );&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				if ( !r || !r.upload ) {&lt;br /&gt;
					// Simply retry when getting an empty response&lt;br /&gt;
					txt = 'Empty response';&lt;br /&gt;
					if ( --p.retry.emptyResponse &amp;lt; 0 ) {&lt;br /&gt;
						args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
						args.unshift( txt );&lt;br /&gt;
						return internal.fail.apply( internal, args );&lt;br /&gt;
					}&lt;br /&gt;
					$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
					internal.nextChunk();&lt;br /&gt;
				}&lt;br /&gt;
				if ( r.upload.filekey ) { filekey = r.upload.filekey; }&lt;br /&gt;
&lt;br /&gt;
				var _successfullytransmitted = function () {&lt;br /&gt;
					chunkinfo.currentchunk.progress = 100;&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'Chunk uploaded';&lt;br /&gt;
					$def.notify( 'prog', chunkinfo );&lt;br /&gt;
					offset += chunkSize;&lt;br /&gt;
					remaining -= chunkSize;&lt;br /&gt;
					offsetid++;&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				if ( r.upload.result === 'Warning' ) {&lt;br /&gt;
					var fileNameRelated = true,&lt;br /&gt;
						warnings = [],&lt;br /&gt;
						__insertNewParams = function ( newparams ) {&lt;br /&gt;
							p = $.extend( p, newparams );&lt;br /&gt;
							if ( waitingFinish ) {&lt;br /&gt;
								internal.finish();&lt;br /&gt;
							}&lt;br /&gt;
						};&lt;br /&gt;
&lt;br /&gt;
					$.each( r.upload.warnings, function ( k, v ) {&lt;br /&gt;
						warnings.push( k + ': \&amp;quot;' + v + '\&amp;quot;' );&lt;br /&gt;
						fileNameRelated = fileNameRelated &amp;amp;&amp;amp; $.inArray( k, j.uploadWarnings.filename ) &amp;gt; -1;&lt;br /&gt;
						return fileNameRelated;&lt;br /&gt;
					} );&lt;br /&gt;
					warnings = warnings.join( ', ' );&lt;br /&gt;
					if ( fileNameRelated ) {&lt;br /&gt;
						p.callbacks.nameNeedsChange( warnings, __insertNewParams );&lt;br /&gt;
					} else {&lt;br /&gt;
						p.callbacks.ignorewarningsRequired( warnings, __insertNewParams );&lt;br /&gt;
					}&lt;br /&gt;
					if ( remaining === 0 ) {&lt;br /&gt;
						waitingFinish = true;&lt;br /&gt;
					} else {&lt;br /&gt;
						// Simply continue with ignorewarnings flag&lt;br /&gt;
						p.passToAPI.upload.ignorewarnings = 1;&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				if ( r.upload.result === 'Continue' &amp;amp;&amp;amp; remaining !== 0 ) {&lt;br /&gt;
					var offsetRequested = Number( r.upload.offset ),&lt;br /&gt;
						offsetCalculated = offset + chunkSize,&lt;br /&gt;
						diff = offsetCalculated - offsetRequested;&lt;br /&gt;
&lt;br /&gt;
					if ( offsetRequested === offsetCalculated ) {&lt;br /&gt;
						_successfullytransmitted();&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					} else if ( offsetRequested &amp;lt; offsetCalculated ) {&lt;br /&gt;
						$def.notify( 'warn', chunkinfo, 'Offset requested by API is lower than offset calculated. \r\n issue?' );&lt;br /&gt;
						// Correct current chunk size&lt;br /&gt;
						chunkSize -= diff;&lt;br /&gt;
						addToNextChunk = diff;&lt;br /&gt;
						_successfullytransmitted();&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					} else {&lt;br /&gt;
						// Error handling: Simply upload last chunk again&lt;br /&gt;
						txt = 'Offset error: API wants to continue at ' + r.upload.offset + ' but calculated offset is ' + ( offset + chunkSize );&lt;br /&gt;
						if ( --p.retry.offsetError &amp;lt; 0 ) {&lt;br /&gt;
							args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
							args.unshift( txt );&lt;br /&gt;
							return internal.fail.apply( internal, args );&lt;br /&gt;
						}&lt;br /&gt;
						$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				_successfullytransmitted();&lt;br /&gt;
				if ( r.upload.result === 'Success' &amp;amp;&amp;amp; remaining === 0 ) {&lt;br /&gt;
					chunkinfo.currentchunk = chunkinfo.finalize;&lt;br /&gt;
					internal.finish();&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				if ( r.upload.result === 'Poll' ) {&lt;br /&gt;
					if ( remaining === 0 ) {&lt;br /&gt;
						chunkinfo.currentchunk = chunkinfo.finalize;&lt;br /&gt;
						internal.status = 'rebuilding';&lt;br /&gt;
&lt;br /&gt;
						chunkinfo.finalize.progress = 1;&lt;br /&gt;
						chunkinfo.finalize.progressText = 'Assembling chunks';&lt;br /&gt;
						$def.notify( 'prog', chunkinfo, txt );&lt;br /&gt;
					}&lt;br /&gt;
					setTimeout( internal.poll, 2000 );&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			offsetmismatch: function ( args, offsetExpectedByServer ) {&lt;br /&gt;
				var txt,&lt;br /&gt;
					_successfullytransmitted = function ( newOffset, newRemaining, newOffsetid ) {&lt;br /&gt;
						chunkinfo.currentchunk.progress = 100;&lt;br /&gt;
						chunkinfo.currentchunk.progressText = 'Chunk uploaded';&lt;br /&gt;
						$def.notify( 'prog', chunkinfo );&lt;br /&gt;
						offset = newOffset;&lt;br /&gt;
						remaining = newRemaining;&lt;br /&gt;
						offsetid = newOffsetid;&lt;br /&gt;
					};&lt;br /&gt;
&lt;br /&gt;
				$def.notify( 'warn', chunkinfo, 'Offset issue by Server detected. Attempting to fix automatically.' );&lt;br /&gt;
				if ( offsetExpectedByServer === offset + chunkSize ) {&lt;br /&gt;
					txt = &amp;quot;Looks like this chunk was successfully transmitted but didn't receive a success message for it.&amp;quot; +&lt;br /&gt;
						'Please have a look at the file after uploading.';&lt;br /&gt;
					$def.notify( 'warn', chunkinfo, txt );&lt;br /&gt;
					_successfullytransmitted(&lt;br /&gt;
						offsetExpectedByServer,&lt;br /&gt;
						remaining - chunkSize,&lt;br /&gt;
						offsetid + 1&lt;br /&gt;
					);&lt;br /&gt;
					p.retry.offsetError += 0.5;&lt;br /&gt;
				} else if ( Math.abs( offsetExpectedByServer - offset ) &amp;lt;= chunkSize ) {&lt;br /&gt;
					txt = 'The offset requested by the server differs by one or less than one chunk size from client side calculations.\r\n' +&lt;br /&gt;
						'Going to return what is requested but please have a close look at the file after uploading.\r\n' +&lt;br /&gt;
						'Offset expected by server: ' + offsetExpectedByServer + '. Offset calculated by client: ' + offset;&lt;br /&gt;
					$def.notify( 'warn', chunkinfo, txt );&lt;br /&gt;
					_successfullytransmitted(&lt;br /&gt;
						offsetExpectedByServer,&lt;br /&gt;
						size - offsetExpectedByServer,&lt;br /&gt;
						offsetExpectedByServer &amp;gt; offset ? offsetid + 1 : offsetid&lt;br /&gt;
					);&lt;br /&gt;
				} else {&lt;br /&gt;
					txt = 'The server expects continuation at byte ' + offsetExpectedByServer + '.\r\n' +&lt;br /&gt;
						'However, to the client side calculated offset is ' + offset + '.\r\n';&lt;br /&gt;
					$def.notify( 'warn', chunkinfo, txt );&lt;br /&gt;
				}&lt;br /&gt;
				if ( --p.retry.offsetError &amp;lt; 0 ) {&lt;br /&gt;
					args = Array.prototype.slice.call( args, 0 );&lt;br /&gt;
					args.unshift( txt );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				}&lt;br /&gt;
				internal.nextChunk();&lt;br /&gt;
			},&lt;br /&gt;
			/**&lt;br /&gt;
			* status checker&lt;br /&gt;
			**/&lt;br /&gt;
			poll: function () {&lt;br /&gt;
				var txt,&lt;br /&gt;
					args,&lt;br /&gt;
					cb,&lt;br /&gt;
					word;&lt;br /&gt;
&lt;br /&gt;
				switch ( internal.status ) {&lt;br /&gt;
				case 'uploading':&lt;br /&gt;
					word = 'process chunk';&lt;br /&gt;
					cb = function ( r ) {&lt;br /&gt;
						internal.chunkUploaded( 'OK', r );&lt;br /&gt;
						return true;&lt;br /&gt;
					};&lt;br /&gt;
					break;&lt;br /&gt;
				case 'rebuilding':&lt;br /&gt;
					word = 'rebuild uploaded file';&lt;br /&gt;
					cb = function ( r ) {&lt;br /&gt;
						return ( r.upload.stage === 'queued' ) ? false : ( internal.finish() || true );&lt;br /&gt;
					};&lt;br /&gt;
					break;&lt;br /&gt;
				case 'publishing':&lt;br /&gt;
					word = 'publish uploaded file';&lt;br /&gt;
					cb = function ( r ) {&lt;br /&gt;
						internal.finished( r );&lt;br /&gt;
						return true;&lt;br /&gt;
					};&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
				internal.uploadAPI( {&lt;br /&gt;
					checkstatus: 1&lt;br /&gt;
				} ).done( function ( r ) {&lt;br /&gt;
					if ( r &amp;amp;&amp;amp; r.error ) {&lt;br /&gt;
						switch ( r.error.code ) {&lt;br /&gt;
						// r.error.info&lt;br /&gt;
						case 'badtoken':&lt;br /&gt;
							j.refreshToken( 'edit', $.proxy( internal.poll, internal ) );&lt;br /&gt;
							break;&lt;br /&gt;
						case 'readapidenied':&lt;br /&gt;
						case 'writeapidenied':&lt;br /&gt;
						case 'invalid-file-key':&lt;br /&gt;
						case 'mustbeloggedin':&lt;br /&gt;
						case 'permissiondenied':&lt;br /&gt;
						case 'internal_api_error_UploadStashNotLoggedInException':&lt;br /&gt;
							p.callbacks.loginRequired( r.error.code + ': ' + r.error.info, function () {&lt;br /&gt;
								j.refreshToken( 'edit', $.proxy( internal.poll, internal ) );&lt;br /&gt;
							} );&lt;br /&gt;
							break;&lt;br /&gt;
						default:&lt;br /&gt;
							args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
							args.unshift( r.error.code + ': ' + r.error.info );&lt;br /&gt;
							return internal.fail.apply( internal, args );&lt;br /&gt;
						}&lt;br /&gt;
						return;&lt;br /&gt;
					}&lt;br /&gt;
					if ( !r || !r.upload ) {&lt;br /&gt;
						txt = 'Empty response: Still waiting for server to ' + word;&lt;br /&gt;
						if ( --p.retry.emptyResponse &amp;lt; 0 ) {&lt;br /&gt;
							args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
							args.unshift( txt );&lt;br /&gt;
							return internal.fail.apply( internal, args );&lt;br /&gt;
						}&lt;br /&gt;
						setTimeout( internal.poll, 7000 );&lt;br /&gt;
						$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
						return j.log( txt, r );&lt;br /&gt;
					}&lt;br /&gt;
					if ( r.upload.filekey ) { filekey = r.upload.filekey; }&lt;br /&gt;
					// If the operation succeeded, the callback is called (which returns true for most cases)&lt;br /&gt;
					// otherwise the callback is not called in JavaScript because the expression would evaluate to&lt;br /&gt;
					// false anyway&lt;br /&gt;
					if ( !( ( r.upload.result === 'Success' || r.upload.result === 'Continue' ) &amp;amp;&amp;amp; cb( r ) ) ) {&lt;br /&gt;
						txt = 'Still waiting for server to ' + word;&lt;br /&gt;
						$def.notify( 'prog', chunkinfo, txt );&lt;br /&gt;
						j.log( txt, r );&lt;br /&gt;
						setTimeout( internal.poll, 4500 );&lt;br /&gt;
					}&lt;br /&gt;
				} ).fail( function ( jqXHR, textStatus, errorThrown ) {&lt;br /&gt;
					// TODO: Server status etc.&lt;br /&gt;
					// Simply re-query&lt;br /&gt;
					txt = 'Sever-Error ' + jqXHR.status + '. Reason: ' + textStatus + ' ' + errorThrown + ' ... Still waiting for server to ' + word;&lt;br /&gt;
					if ( --p.retry.serverError &amp;lt; 0 ) {&lt;br /&gt;
						args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
						args.unshift( txt );&lt;br /&gt;
						return internal.fail.apply( internal, args );&lt;br /&gt;
					}&lt;br /&gt;
					setTimeout( internal.poll, 7000 );&lt;br /&gt;
					$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
					j.log( txt );&lt;br /&gt;
				} );&lt;br /&gt;
			},&lt;br /&gt;
			finish: function () {&lt;br /&gt;
				internal.status = 'publishing';&lt;br /&gt;
				chunkinfo.finalize.progress = 10;&lt;br /&gt;
				chunkinfo.finalize.progressText = 'Finishing';&lt;br /&gt;
&lt;br /&gt;
				$def.notify( 'prog', chunkinfo );&lt;br /&gt;
				j.log( 'chunked upload&amp;gt; Finishing.' );&lt;br /&gt;
				var params = {&lt;br /&gt;
					filename: p.title,&lt;br /&gt;
					filesize: size,&lt;br /&gt;
					comment: p.summary,&lt;br /&gt;
					text: p.text&lt;br /&gt;
				};&lt;br /&gt;
				if ( p.async ) { params.async = 1; }&lt;br /&gt;
				$.each( p.passToAPI.finish, function ( k, v ) {&lt;br /&gt;
					params[ k ] = v;&lt;br /&gt;
				} );&lt;br /&gt;
				internal.uploadAPI( params ).done( internal.possiblyFinished ).fail( internal.finishFailed );&lt;br /&gt;
			},&lt;br /&gt;
			possiblyFinished: function ( r ) {&lt;br /&gt;
				if ( r &amp;amp;&amp;amp; r.error ) {&lt;br /&gt;
					switch ( r.error.code ) {&lt;br /&gt;
					// r.error.info&lt;br /&gt;
					case 'badtoken':&lt;br /&gt;
						j.refreshToken( 'edit', $.proxy( internal.finish, internal ) );&lt;br /&gt;
						break;&lt;br /&gt;
					case 'readapidenied':&lt;br /&gt;
					case 'writeapidenied':&lt;br /&gt;
					case 'invalid-file-key':&lt;br /&gt;
					case 'mustbeloggedin':&lt;br /&gt;
					case 'permissiondenied':&lt;br /&gt;
					case 'internal_api_error_UploadStashNotLoggedInException':&lt;br /&gt;
						p.callbacks.loginRequired( r.error.code + ': ' + r.error.info, function () {&lt;br /&gt;
							j.refreshToken( 'edit', $.proxy( internal.finish, internal ) );&lt;br /&gt;
						} );&lt;br /&gt;
						break;&lt;br /&gt;
					default:&lt;br /&gt;
						var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
						args.unshift( r.error.code + ': ' + r.error.info );&lt;br /&gt;
						return internal.fail.apply( internal, args );&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				if ( !r || !r.upload ) { return internal.finishFailed( 'empty response received' ); }&lt;br /&gt;
				if ( r.upload.filekey ) { filekey = r.upload.filekey; }&lt;br /&gt;
&lt;br /&gt;
				switch ( r.upload.result ) {&lt;br /&gt;
				case 'Poll':&lt;br /&gt;
					j.log( 'Waiting for upload to be published' );&lt;br /&gt;
					chunkinfo.finalize.progress = 50;&lt;br /&gt;
					chunkinfo.finalize.progressText = 'Waiting for upload to be published';&lt;br /&gt;
&lt;br /&gt;
					$def.notify( 'prog', chunkinfo );&lt;br /&gt;
					setTimeout( internal.poll, 2000 );&lt;br /&gt;
					break;&lt;br /&gt;
				case 'Success':&lt;br /&gt;
					internal.finished( r );&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			finished: function ( r ) {&lt;br /&gt;
				j.log( 'Uploaded successfully' );&lt;br /&gt;
				chunkinfo.finalize.progress = 100;&lt;br /&gt;
				chunkinfo.finalize.progressText = 'Uploaded successfully';&lt;br /&gt;
&lt;br /&gt;
				$def.notify( 'prog', chunkinfo );&lt;br /&gt;
				$def.resolve( chunkinfo, r );&lt;br /&gt;
			},&lt;br /&gt;
			chunkFailed: function ( statusText, response, xhr ) {&lt;br /&gt;
				stuckCounter = 0;&lt;br /&gt;
				var txt = 'Server error ' + xhr.status + ' after uploading chunk: ' + statusText + '\nResponse: ' + response.slice( 0, 500 ).replace( /\n\n/g, '\n' );&lt;br /&gt;
&lt;br /&gt;
				if ( --p.retry.serverError &amp;lt; 0 ) {&lt;br /&gt;
					var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
					args.shift( txt );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				}&lt;br /&gt;
				$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
				if ( startTime + 750 &amp;gt; Date.now() ) {&lt;br /&gt;
					setTimeout( function () {&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					}, waitTime *= 2 );&lt;br /&gt;
				} else {&lt;br /&gt;
					internal.nextChunk();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			finishFailed: function ( reasonOrXHR, textStatus, errorThrown ) {&lt;br /&gt;
				if ( typeof reasonOrXHR === 'object' ) { reasonOrXHR = textStatus + ' ' + errorThrown; }&lt;br /&gt;
&lt;br /&gt;
				var txt = 'Server error while publishing upload. Reason: ' + reasonOrXHR;&lt;br /&gt;
				if ( --p.retry.serverError &amp;lt; 0 ) {&lt;br /&gt;
					var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
					args.unshift( txt );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				}&lt;br /&gt;
				$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
				internal.finish();&lt;br /&gt;
			},&lt;br /&gt;
			fail: function () {&lt;br /&gt;
				var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
				j.fail.apply( j, args );&lt;br /&gt;
				$def.reject.apply( $def, args );&lt;br /&gt;
			}&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		// Get some statistics about the file&lt;br /&gt;
		size = remaining = file.size;&lt;br /&gt;
		var remains4loop = size,&lt;br /&gt;
			chunksize4loop,&lt;br /&gt;
			i = 0;&lt;br /&gt;
&lt;br /&gt;
		while ( remains4loop &amp;gt; 0 ) {&lt;br /&gt;
			chunksize4loop = Math.min( remaining, p.maxChunkSize );&lt;br /&gt;
			chunkinfo[ i ] = {&lt;br /&gt;
				chunksize: chunksize4loop,&lt;br /&gt;
				remaining: remains4loop,&lt;br /&gt;
				progress: 0,&lt;br /&gt;
				progressText: 'in progress',&lt;br /&gt;
				id: i&lt;br /&gt;
			};&lt;br /&gt;
			remains4loop -= chunksize4loop;&lt;br /&gt;
			i++;&lt;br /&gt;
		}&lt;br /&gt;
		chunkinfo.finalize = {&lt;br /&gt;
			progress: 0,&lt;br /&gt;
			progressText: '',&lt;br /&gt;
			id: 'finalize'&lt;br /&gt;
		};&lt;br /&gt;
		internal.nextChunk();&lt;br /&gt;
		$def.chunkinfo = chunkinfo;&lt;br /&gt;
&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	createSampleUploadButton: function () {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		$( '&amp;lt;input type=&amp;quot;file&amp;quot; id=&amp;quot;files&amp;quot; name=&amp;quot;file&amp;quot;&amp;gt;' ).prependTo( mw.util.$content ).on( 'change', function ( /* e */ ) {&lt;br /&gt;
			j.chunkedUpload( {&lt;br /&gt;
				title: 'A random title.png'&lt;br /&gt;
			}, this.files[ 0 ] ).progress( function () {&lt;br /&gt;
				console.log( 'prog', arguments );&lt;br /&gt;
			} ).done( function () {&lt;br /&gt;
				console.log( 'done', arguments );&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	},&lt;br /&gt;
	$loadContinue: function ( title ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			j = this;&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.query( {&lt;br /&gt;
				action: 'query',&lt;br /&gt;
				prop: 'revisions',&lt;br /&gt;
				rvprop: 'content',&lt;br /&gt;
				rvlimit: 1,&lt;br /&gt;
				titles: title&lt;br /&gt;
			}, {&lt;br /&gt;
				method: 'POST',&lt;br /&gt;
				cache: false,&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					try {&lt;br /&gt;
						$def.resolve( firstItem( r.query.pages ).revisions[ 0 ][ '*' ] );&lt;br /&gt;
					} catch ( ex ) {&lt;br /&gt;
						$def.reject( ex );&lt;br /&gt;
					}&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to retrieve continue param.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$continueQuery: function ( query, result ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			qc = result[ 'query-continue' ],&lt;br /&gt;
			j = this,&lt;br /&gt;
			oldProp = query.prop,&lt;br /&gt;
			oldList = query.list;&lt;br /&gt;
&lt;br /&gt;
		if ( qc ) {&lt;br /&gt;
			var props = [],&lt;br /&gt;
				lists = [];&lt;br /&gt;
			$.each( qc, function ( k, v ) {&lt;br /&gt;
				if ( oldProp &amp;amp;&amp;amp; oldProp.indexOf( k ) &amp;gt; -1 ) {&lt;br /&gt;
					props.push( k );&lt;br /&gt;
				}&lt;br /&gt;
				if ( oldList &amp;amp;&amp;amp; oldList.indexOf( k ) &amp;gt; -1 ) {&lt;br /&gt;
					lists.push( k );&lt;br /&gt;
				}&lt;br /&gt;
				$.extend( query, v );&lt;br /&gt;
			} );&lt;br /&gt;
			if ( props.length ) {&lt;br /&gt;
				query.prop = props.join( '|' );&lt;br /&gt;
			} else {&lt;br /&gt;
				delete query.prop;&lt;br /&gt;
			}&lt;br /&gt;
			if ( lists.length ) {&lt;br /&gt;
				query.list = lists.join( '|' );&lt;br /&gt;
			} else {&lt;br /&gt;
				delete query.list;&lt;br /&gt;
			}&lt;br /&gt;
		} else if ( result.continue ) {&lt;br /&gt;
			// new style continuation&lt;br /&gt;
			$.extend( query, result.continue );&lt;br /&gt;
		} else {&lt;br /&gt;
			throw new Error( 'MW-JS-BOT: Nothing to continue.' );&lt;br /&gt;
		}&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.query( query, {&lt;br /&gt;
				method: 'POST',&lt;br /&gt;
				cache: false,&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$def.resolve( r );&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to continue query.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$saveContinue: function ( title, value, summary ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			j = this;&lt;br /&gt;
&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.editPage( {&lt;br /&gt;
				editType: 'text',&lt;br /&gt;
				text: value,&lt;br /&gt;
				title: title,&lt;br /&gt;
				summary: 'MW-JS-BOT: ' + ( summary || ' updating continue-param' ),&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$def.resolve( r );&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to save continue param.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$addLogline: function ( title, value, summary ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			j = this;&lt;br /&gt;
&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.editPage( {&lt;br /&gt;
				editType: 'appendtext',&lt;br /&gt;
				text: '\n# ' + value,&lt;br /&gt;
				title: title,&lt;br /&gt;
				summary: 'MW-JS-BOT: ' + ( summary || ' logging' ),&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$def.resolve( r );&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to log.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$xmlFromString: function ( xmlString, title ) {&lt;br /&gt;
		var xml = $.parseXML( xmlString ),&lt;br /&gt;
			isXmlDoc = $.isXMLDoc( xml ),&lt;br /&gt;
			$xmlDoc = $( xml ),&lt;br /&gt;
			j = this;&lt;br /&gt;
&lt;br /&gt;
		if ( !isXmlDoc || !$xmlDoc || !$xmlDoc.length ) {&lt;br /&gt;
			j.warn( title + ' is not an XML Document.' );&lt;br /&gt;
		}&lt;br /&gt;
		return $xmlDoc;&lt;br /&gt;
	},&lt;br /&gt;
	stringFrom$xml: function ( $xml ) {&lt;br /&gt;
		if ( !window.XMLSerializer ) {&lt;br /&gt;
			window.XMLSerializer = function () {};&lt;br /&gt;
			window.XMLSerializer.prototype.serializeToString = function ( XMLObject ) {&lt;br /&gt;
				return XMLObject.xml || '';&lt;br /&gt;
			};&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var oSerializer = new XMLSerializer(),&lt;br /&gt;
			xmlStringOut = oSerializer.serializeToString( $xml[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
		return xmlStringOut;&lt;br /&gt;
	},&lt;br /&gt;
	$getWindowConsole: function () {&lt;br /&gt;
		if ( this.$windowConsole ) {&lt;br /&gt;
			return this.$windowConsole;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var $console = this.$windowConsole = $( '&amp;lt;div&amp;gt;' ).css( {&lt;br /&gt;
			'font-family': '&amp;quot;Lucida Console&amp;quot;, &amp;quot;Courier New&amp;quot;, Monospace'&lt;br /&gt;
		} ).appendTo( mw.util.$content );&lt;br /&gt;
		$console.$consoleTop = $( '&amp;lt;div&amp;gt;' ).text( 'Window Console by MW-JS-BOT' ).appendTo( $console );&lt;br /&gt;
		$console.$droppedEntryNote = $( '&amp;lt;span&amp;gt;' ).appendTo( $console.$consoleTop );&lt;br /&gt;
		$console.droppedEntries = 0;&lt;br /&gt;
		$console.visibleEntries = 0;&lt;br /&gt;
&lt;br /&gt;
		$console.dropFirstEntry = function () {&lt;br /&gt;
			$console.$consoleTop.next().remove();&lt;br /&gt;
			$console.droppedEntries++;&lt;br /&gt;
			$console.visibleEntries--;&lt;br /&gt;
			$console.$droppedEntryNote.text( $console.droppedEntries + ' entries were dropped from the window console.' );&lt;br /&gt;
		};&lt;br /&gt;
		$console.log = function () {&lt;br /&gt;
			if ( $console.totalEntries &amp;gt; 400 ) {&lt;br /&gt;
				$console.dropFirstEntry();&lt;br /&gt;
			}&lt;br /&gt;
			$console.visibleEntries++;&lt;br /&gt;
			var $entry = $( '&amp;lt;div&amp;gt;' ).attr( {&lt;br /&gt;
					class: 'windowconsole-entry'&lt;br /&gt;
				} ),&lt;br /&gt;
				argslen = arguments.length;&lt;br /&gt;
			for ( var i = 0; i &amp;lt; argslen; i++ ) {&lt;br /&gt;
				try {&lt;br /&gt;
					var $subentry = $( '&amp;lt;p&amp;gt;' ).text( arguments[ i ] );&lt;br /&gt;
					$subentry.appendTo( $entry );&lt;br /&gt;
				} catch ( ex ) {}&lt;br /&gt;
			}&lt;br /&gt;
			$entry.appendTo( $console );&lt;br /&gt;
		};&lt;br /&gt;
		return $console;&lt;br /&gt;
	},&lt;br /&gt;
	log: function ( /* unlimitedArgs*/ ) {&lt;br /&gt;
		if ( window.console ) {&lt;br /&gt;
			var arrArgs = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
			arrArgs.unshift( 'mwbot&amp;gt;' );&lt;br /&gt;
			if ( typeof console.log === 'function' ) {&lt;br /&gt;
				console.log.apply( console, arrArgs );&lt;br /&gt;
			} else {&lt;br /&gt;
				this.$getWindowConsole().apply( this, arrArgs );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	warn: function ( /* unlimitedArgs*/ ) {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		if ( window.console ) {&lt;br /&gt;
			var arrArgs = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
			if ( typeof console.warn === 'function' ) {&lt;br /&gt;
				arrArgs.unshift( 'mwbot&amp;gt;' );&lt;br /&gt;
				console.warn.apply( console, arrArgs );&lt;br /&gt;
			} else {&lt;br /&gt;
				arrArgs.unshift( 'WARNING&amp;gt;' );&lt;br /&gt;
				j.log.apply( j, arrArgs );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	fail: function ( /* unlimitedArgs*/ ) {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		if ( window.console ) {&lt;br /&gt;
			var arrArgs = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
			if ( typeof console.error === 'function' ) {&lt;br /&gt;
				arrArgs.unshift( 'mwbot&amp;gt;' );&lt;br /&gt;
				console.error.apply( console, arrArgs );&lt;br /&gt;
			} else {&lt;br /&gt;
				arrArgs.unshift( 'ERR&amp;gt;' );&lt;br /&gt;
				j.log.apply( j, arrArgs );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
} );&lt;br /&gt;
window.MwJSBot = jsb;&lt;br /&gt;
&lt;br /&gt;
var h = {};&lt;br /&gt;
h[ myModuleName ] = 'ready';&lt;br /&gt;
mw.loader.state( h );&lt;br /&gt;
&lt;br /&gt;
new MwJSBot().log( 'Hello. I am your MwJSBot framework.' );&lt;br /&gt;
}( jQuery, mediaWiki ) );&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/MwJSBot.js</id>
		<title>Участник:Kolbaska/MwJSBot.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/MwJSBot.js"/>
				<updated>2025-11-14T04:12:17Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: Новая страница: «( function ( $, mw ) { 'use strict';  var myModuleName = 'mediawiki.commons.MwJSBot', 	isCommonsWiki = mw.config.get( 'wgDBname' ) === 'commonswiki';  function Co…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;( function ( $, mw ) {&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
var myModuleName = 'mediawiki.commons.MwJSBot',&lt;br /&gt;
	isCommonsWiki = mw.config.get( 'wgDBname' ) === 'commonswiki';&lt;br /&gt;
&lt;br /&gt;
function ContinuousAverage() {&lt;br /&gt;
	this.n = 0;&lt;br /&gt;
	this.avg = null;&lt;br /&gt;
	this.lastDateTime = Date.now();&lt;br /&gt;
}&lt;br /&gt;
ContinuousAverage.fn = ContinuousAverage.prototype;&lt;br /&gt;
$.extend( true, ContinuousAverage.fn, {&lt;br /&gt;
	push: function ( val ) {&lt;br /&gt;
		if ( this.avg === null ) {&lt;br /&gt;
			this.avg = val;&lt;br /&gt;
			this.n = 1;&lt;br /&gt;
		} else {&lt;br /&gt;
			this.avg = ( this.avg * this.n + val ) / ( ++this.n );&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	pushTimeDiff: function ( now ) {&lt;br /&gt;
		now = now || Date.now();&lt;br /&gt;
		this.push( now - this.lastDateTime );&lt;br /&gt;
		this.lastDateTime = now;&lt;br /&gt;
	},&lt;br /&gt;
	getN: function () {&lt;br /&gt;
		return this.n;&lt;br /&gt;
	},&lt;br /&gt;
	getAvg: function () {&lt;br /&gt;
		return this.avg;&lt;br /&gt;
	}&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
function firstItem( o ) {&lt;br /&gt;
	for ( var i in o ) {&lt;br /&gt;
		if ( o.hasOwnProperty( i ) ) {&lt;br /&gt;
			return o[ i ];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function encode_utf8( s ) {&lt;br /&gt;
	return unescape( encodeURIComponent( s ) );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var jsb = function () {},&lt;br /&gt;
	clnt = $.client.profile(),&lt;br /&gt;
	APIURL = mw.util.wikiScript( 'api' ),&lt;br /&gt;
	MPB = '----------' + myModuleName + Math.random();&lt;br /&gt;
&lt;br /&gt;
jsb.fn = jsb.prototype;&lt;br /&gt;
&lt;br /&gt;
$.extend( true, jsb.fn, {&lt;br /&gt;
	$downloadRawFile: function ( url ) {&lt;br /&gt;
		return $.ajax( {&lt;br /&gt;
			url: url,&lt;br /&gt;
			beforeSend: function ( xhr ) {&lt;br /&gt;
				xhr.overrideMimeType( 'text/plain; charset=x-user-defined' );&lt;br /&gt;
			},&lt;br /&gt;
			dataFilter: function ( d/* , dataType*/ ) {&lt;br /&gt;
				// Some more sophisticated stuff avoiding killing performance with memory allocations and thousands of function invocations&lt;br /&gt;
				// https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays would be perhaps also valuable&lt;br /&gt;
				var f = '',&lt;br /&gt;
					len = d.length,&lt;br /&gt;
					buff = 1018, // You can't apply huge arrays to functions!&lt;br /&gt;
					arrCC = new Array( Math.min( buff, len ) ),&lt;br /&gt;
					arrF = new Array( Math.ceil( len / buff ) );&lt;br /&gt;
&lt;br /&gt;
				// Remove junk-high-order-bytes&lt;br /&gt;
				for ( var i = 0, j = 0, z = 0; i &amp;lt; len; i++ ) {&lt;br /&gt;
					arrCC[ j ] = ( d.charCodeAt( i ) &amp;amp; 0xff );&lt;br /&gt;
					j++;&lt;br /&gt;
					if ( ( j % buff ) === 0 ) {&lt;br /&gt;
						// Convert char codes to chars&lt;br /&gt;
						arrF[ z ] = String.fromCharCode.apply( null, arrCC );&lt;br /&gt;
						// Empty the char code array&lt;br /&gt;
						arrCC = new Array( Math.min( buff, len - i - 1 ) );&lt;br /&gt;
						z++;&lt;br /&gt;
						j = 0;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				if ( j !== 0 ) { arrF[ z + 1 ] = String.fromCharCode.apply( null, arrCC ); }&lt;br /&gt;
				f = arrF.join( '' );&lt;br /&gt;
				return f;&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	},&lt;br /&gt;
	$downloadXMLFile: function ( url ) {&lt;br /&gt;
		return $.get( url, 'xml' );&lt;br /&gt;
	},&lt;br /&gt;
	// NEVER use this twice to send something. Instead, create a new message!&lt;br /&gt;
	// TODO allow/review re-sending same message again&lt;br /&gt;
	multipartMessageForBinaryFiles: function () {&lt;br /&gt;
		// Body parts that must be considered to end with line breaks, therefore, should have two CRLFs preceding the encapsulation line,&lt;br /&gt;
		// the first of which is part of the preceding body part, and the second of which is part of the encapsulation boundary&lt;br /&gt;
		var pendingParts = 0,&lt;br /&gt;
			tokenPart = '',&lt;br /&gt;
			useStuckWatcher = true,&lt;br /&gt;
			msgParts,&lt;br /&gt;
			createPart,&lt;br /&gt;
			appendPart,&lt;br /&gt;
			send,&lt;br /&gt;
			formData;&lt;br /&gt;
&lt;br /&gt;
		if ( clnt.name === 'firefox' &amp;amp;&amp;amp; clnt.versionNumber &amp;lt; 22 ) {&lt;br /&gt;
			msgParts = [];&lt;br /&gt;
			createPart = function ( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) {&lt;br /&gt;
				var p = '--' + MPB + '\r\n';&lt;br /&gt;
				if ( !ContentDisposition ) {&lt;br /&gt;
					p += 'Content-Disposition: form-data; name=\&amp;quot;' + param + '\&amp;quot;\r\n';&lt;br /&gt;
				} else {&lt;br /&gt;
					p += 'Content-Disposition: ' + ContentDisposition + '\r\n';&lt;br /&gt;
				}&lt;br /&gt;
				p += 'Content-Type: ' + ContentType + '\r\n';&lt;br /&gt;
				p += 'Content-Transfer-Encoding: ' + ContentTransferEncoding + '\r\n';&lt;br /&gt;
				return [ p, '\r\n', value, '\r\n' ].join( '' );&lt;br /&gt;
			};&lt;br /&gt;
			appendPart = function ( param, value, filename, MIME ) {&lt;br /&gt;
				var ContentType, ContentTransferEncoding, ContentDisposition, doPush = function ( value ) {&lt;br /&gt;
					msgParts.push( createPart( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) );&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				if ( filename ) {&lt;br /&gt;
					ContentType = MIME || 'application/octet-stream';&lt;br /&gt;
					ContentTransferEncoding = 'binary';&lt;br /&gt;
					ContentDisposition = 'attachment; name=\&amp;quot;' + param + '\&amp;quot;; filename=\&amp;quot;' + encode_utf8( filename.replace( /\&amp;quot;/g, '-' ) ) + '\&amp;quot;';&lt;br /&gt;
					if ( value instanceof Blob || value instanceof File ) {&lt;br /&gt;
						pendingParts++;&lt;br /&gt;
						var reader = new FileReader();&lt;br /&gt;
						reader.onload = function () {&lt;br /&gt;
							value = reader.result;&lt;br /&gt;
							doPush( value );&lt;br /&gt;
							if ( tokenPart ) { msgParts.push( tokenPart ); }&lt;br /&gt;
							pendingParts--;&lt;br /&gt;
							if ( pendingParts === 0 &amp;amp;&amp;amp; typeof send === 'function' ) { send(); }&lt;br /&gt;
						};&lt;br /&gt;
						reader.readAsBinaryString( value );&lt;br /&gt;
						return;&lt;br /&gt;
					}&lt;br /&gt;
				} else {&lt;br /&gt;
					value = encode_utf8( value );&lt;br /&gt;
					ContentType = 'text/plain; charset=UTF-8';&lt;br /&gt;
					ContentTransferEncoding = '8bit';&lt;br /&gt;
					if ( param === 'token' &amp;amp;&amp;amp; pendingParts ) {&lt;br /&gt;
						// Ensure token last (This is done to catch connection errors. This way we can circumvent calculating MD5)&lt;br /&gt;
						tokenPart = createPart( param, value, ContentType, ContentTransferEncoding, ContentDisposition );&lt;br /&gt;
						return;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				doPush( value );&lt;br /&gt;
			};&lt;br /&gt;
		} else {&lt;br /&gt;
			formData = new FormData();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var msg = {&lt;br /&gt;
			appendPart: function ( param, value, filename, MIME ) {&lt;br /&gt;
				if ( msgParts ) {&lt;br /&gt;
					appendPart.apply( window, Array.prototype.slice.call( arguments, 0 ) );&lt;br /&gt;
				} else {&lt;br /&gt;
					if ( filename ) {&lt;br /&gt;
						var bl;&lt;br /&gt;
						if ( value instanceof Blob || value instanceof File ) {&lt;br /&gt;
							bl = value;&lt;br /&gt;
						} else {&lt;br /&gt;
							bl = new Blob( [ value ], { type: MIME || 'application/octet-stream' } );&lt;br /&gt;
						}&lt;br /&gt;
						formData.append( param, bl, filename );&lt;br /&gt;
					} else {&lt;br /&gt;
						formData.append( param, value );&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				// allow something like new MwJSBot().multipartMessage().appendPart(&amp;quot;param1&amp;quot;, &amp;quot;value&amp;quot;).appendPart(&amp;quot;param2&amp;quot;, &amp;quot;value&amp;quot;).$send();&lt;br /&gt;
				return msg;&lt;br /&gt;
			},&lt;br /&gt;
			noStuckWatcher: function () {&lt;br /&gt;
				useStuckWatcher = false;&lt;br /&gt;
				return msg;&lt;br /&gt;
			},&lt;br /&gt;
			$send: function ( url, responseType ) {&lt;br /&gt;
				var $def = $.Deferred();&lt;br /&gt;
&lt;br /&gt;
				send = function () {&lt;br /&gt;
					var req = new XMLHttpRequest(),&lt;br /&gt;
						ca = new ContinuousAverage(),&lt;br /&gt;
						lastProgressEvt, intervalId, killProgressWatchers, progressWatcher;&lt;br /&gt;
&lt;br /&gt;
					// Browsers sometimes have the attitude not to continue uploading&lt;br /&gt;
					// upon network interruptions but they send new requests correctly&lt;br /&gt;
					killProgressWatchers = function () {&lt;br /&gt;
						clearInterval( intervalId );&lt;br /&gt;
					};&lt;br /&gt;
					progressWatcher = function () {&lt;br /&gt;
						var now = Date.now(),&lt;br /&gt;
							diff = now - lastProgressEvt;&lt;br /&gt;
&lt;br /&gt;
						if ( ca.getN() &amp;gt; 10 &amp;amp;&amp;amp; diff &amp;gt; ca.getAvg() * 5 &amp;amp;&amp;amp; diff &amp;gt; 7000 ) {&lt;br /&gt;
							$def.notify( 'stuck', req );&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
					req.onreadystatechange = function () {&lt;br /&gt;
						if ( req.readyState !== 4 ) { return; }&lt;br /&gt;
						if ( req.status === 200 ) {&lt;br /&gt;
							// TODO: Pass more args&lt;br /&gt;
							$def.resolve( req.statusText, req.response );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						} else {&lt;br /&gt;
							$def.reject( req.statusText, req.response, req );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
					req.onerror = function () {&lt;br /&gt;
						setTimeout( function () {&lt;br /&gt;
							$def.reject( req.statusText, req.response, req );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						}, 100 );&lt;br /&gt;
					};&lt;br /&gt;
					req.onabort = function () {&lt;br /&gt;
						setTimeout( function () {&lt;br /&gt;
							$def.reject( req.statusText, req.response, req );&lt;br /&gt;
							killProgressWatchers();&lt;br /&gt;
						}, 100 );&lt;br /&gt;
					};&lt;br /&gt;
					// Can we monitor upload status?&lt;br /&gt;
					if ( req.upload ) {&lt;br /&gt;
						req.upload.onprogress = function ( e ) {&lt;br /&gt;
							// Ensure compatible event&lt;br /&gt;
							if ( !e.loaded || !e.total ) { return; }&lt;br /&gt;
							$def.notify( 'uploadstatus', e );&lt;br /&gt;
							lastProgressEvt = Date.now();&lt;br /&gt;
							ca.pushTimeDiff( lastProgressEvt );&lt;br /&gt;
						};&lt;br /&gt;
					}&lt;br /&gt;
					req.open( 'POST', url || APIURL );&lt;br /&gt;
					if ( responseType ) {&lt;br /&gt;
						req.responseType = responseType;&lt;br /&gt;
					}&lt;br /&gt;
					if ( useStuckWatcher ) {&lt;br /&gt;
						intervalId = setInterval( progressWatcher, 5000 );&lt;br /&gt;
					}&lt;br /&gt;
					if ( msgParts ) {&lt;br /&gt;
						req.setRequestHeader( 'Content-Type', 'multipart/form-data; charset=UTF-8; boundary=' + MPB );&lt;br /&gt;
						msgParts.push( '--', MPB, '--', '\r\n' );&lt;br /&gt;
						req.sendAsBinary( msgParts.join( '' ) );&lt;br /&gt;
					} else {&lt;br /&gt;
						req.send( formData );&lt;br /&gt;
					}&lt;br /&gt;
				};&lt;br /&gt;
				if ( pendingParts === 0 ) {&lt;br /&gt;
					send();&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				return $def;&lt;br /&gt;
			}&lt;br /&gt;
		};&lt;br /&gt;
		return msg;&lt;br /&gt;
	},&lt;br /&gt;
	multipartMessageForUTF8Files: function () {&lt;br /&gt;
		var msgParts,&lt;br /&gt;
			createPart,&lt;br /&gt;
			appendPart;&lt;br /&gt;
&lt;br /&gt;
		msgParts = [];&lt;br /&gt;
		createPart = function ( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) {&lt;br /&gt;
			var p = '--' + MPB + '\n';&lt;br /&gt;
			if ( !ContentDisposition ) {&lt;br /&gt;
				p += 'Content-Disposition: form-data; name=\&amp;quot;' + param + '\&amp;quot;\n';&lt;br /&gt;
			} else {&lt;br /&gt;
				p += 'Content-Disposition: ' + ContentDisposition + '\n';&lt;br /&gt;
			}&lt;br /&gt;
			p += 'Content-Type: ' + ContentType + '\n';&lt;br /&gt;
			p += 'Content-Transfer-Encoding: ' + ContentTransferEncoding + '\n';&lt;br /&gt;
			return [ p, '\n', value, '\n' ].join( '' );&lt;br /&gt;
		};&lt;br /&gt;
		appendPart = function ( param, value, filename ) {&lt;br /&gt;
			var ContentType, ContentTransferEncoding, ContentDisposition;&lt;br /&gt;
			if ( filename ) {&lt;br /&gt;
				ContentType = 'application/octet-stream';&lt;br /&gt;
				ContentTransferEncoding = '8bit';&lt;br /&gt;
				ContentDisposition = 'attachment; name=\&amp;quot;' + param + '\&amp;quot;; filename=\&amp;quot;' + filename.replace( /\&amp;quot;/g, '-' ) + '\&amp;quot;';&lt;br /&gt;
			} else {&lt;br /&gt;
				ContentType = 'text/plain; charset=UTF-8';&lt;br /&gt;
				ContentTransferEncoding = '8bit';&lt;br /&gt;
			}&lt;br /&gt;
			msgParts.push( createPart( param, value, ContentType, ContentTransferEncoding, ContentDisposition ) );&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		var msg = {&lt;br /&gt;
			appendPart: function ( /* param, value, filename*/ ) {&lt;br /&gt;
				appendPart.apply( window, Array.prototype.slice.call( arguments, 0 ) );&lt;br /&gt;
				// allow something like new MwJSBot().multipartMessage().appendPart(&amp;quot;param1&amp;quot;, &amp;quot;value&amp;quot;).appendPart(&amp;quot;param2&amp;quot;, &amp;quot;value&amp;quot;).$send();&lt;br /&gt;
				return msg;&lt;br /&gt;
			},&lt;br /&gt;
			$send: function ( url, responseType ) {&lt;br /&gt;
				var $def = $.Deferred(),&lt;br /&gt;
&lt;br /&gt;
					req = new XMLHttpRequest();&lt;br /&gt;
				req.onreadystatechange = function () {&lt;br /&gt;
					if ( req.readyState !== 4 ) { return; }&lt;br /&gt;
					if ( req.status === 200 ) {&lt;br /&gt;
						// TODO: Pass more args&lt;br /&gt;
						$def.resolve( req.statusText, req.response );&lt;br /&gt;
					} else {&lt;br /&gt;
						$def.reject( req.response );&lt;br /&gt;
					}&lt;br /&gt;
				};&lt;br /&gt;
				req.open( 'POST', url || APIURL );&lt;br /&gt;
				if ( responseType ) {&lt;br /&gt;
					req.responseType = responseType;&lt;br /&gt;
				}&lt;br /&gt;
				req.setRequestHeader( 'Content-Type', 'multipart/form-data; charset=UTF-8; boundary=' + MPB );&lt;br /&gt;
				msgParts.push( '--', MPB, '--', '\n' );&lt;br /&gt;
				req.send( msgParts.join( '' ) );&lt;br /&gt;
				return $def;&lt;br /&gt;
			}&lt;br /&gt;
		};&lt;br /&gt;
		return msg;&lt;br /&gt;
	},&lt;br /&gt;
	refreshToken: function ( type, cb ) {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI', 'mediawiki.user' ], function () {&lt;br /&gt;
			/* FIXME: This is causing an error: Error: api.query is for queries only. For editing use the stable Commons edit-api. */&lt;br /&gt;
			return;&lt;br /&gt;
			mw.libs.commons.api.query( {&lt;br /&gt;
				action: 'tokens',&lt;br /&gt;
				type: type&lt;br /&gt;
			}, {&lt;br /&gt;
				method: 'POST',&lt;br /&gt;
				cache: false,&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$.each( r.tokens, function ( type, v ) {&lt;br /&gt;
						type = type.replace( 'token', 'Token' );&lt;br /&gt;
						mw.user.tokens.set( type, v );&lt;br /&gt;
					} );&lt;br /&gt;
					cb();&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( /* t, r, q */ ) {&lt;br /&gt;
					j.fail( 'Failed to refresh token.' );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	},&lt;br /&gt;
	chunkedUploadDefault: {&lt;br /&gt;
		maxChunkSize: 0.5 * 1024 * 1024, // 2MB&lt;br /&gt;
		retry: {&lt;br /&gt;
			emptyResponse: 9,&lt;br /&gt;
			serverError: 9,&lt;br /&gt;
			apiErrors: 6,&lt;br /&gt;
			offsetError: 2&lt;br /&gt;
		},&lt;br /&gt;
		file: null,&lt;br /&gt;
		title: '',&lt;br /&gt;
		summary: '',&lt;br /&gt;
		useStash: true,&lt;br /&gt;
		async: true,&lt;br /&gt;
		callbacks: {&lt;br /&gt;
			nameNeedsChange: function () {},&lt;br /&gt;
			ignorewarningsRequired: function () {},&lt;br /&gt;
			loginRequired: function () {}&lt;br /&gt;
		},&lt;br /&gt;
		passToAPI: {&lt;br /&gt;
			upload: {&lt;br /&gt;
				// e.g. ignorewarnings: 1&lt;br /&gt;
				tags: isCommonsWiki ? 'rillke-mw-js-bot' : ''&lt;br /&gt;
			},&lt;br /&gt;
			finish: {&lt;br /&gt;
				tags: isCommonsWiki ? 'rillke-mw-js-bot' : ''&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	uploadWarnings: {&lt;br /&gt;
		filename: [ 'exists', 'page-exists', 'was-deleted', 'exists-normalized', 'thumb', 'thumb-name', 'bad-prefix', 'badfilename' ],&lt;br /&gt;
		other: [ 'duplicate-archive', 'duplicate', 'large-file', 'emptyfile', 'filetype-unwanted-type' ]&lt;br /&gt;
	},&lt;br /&gt;
	chunkedUpload: function ( p, file ) {&lt;br /&gt;
		var j = this,&lt;br /&gt;
			$def = $.Deferred(),&lt;br /&gt;
			filekey = '',&lt;br /&gt;
			size = 0,&lt;br /&gt;
			remaining = 0,&lt;br /&gt;
			chunkSize = 0,&lt;br /&gt;
			offset = 0,&lt;br /&gt;
			offsetid = 0,&lt;br /&gt;
			addToNextChunk = 0,&lt;br /&gt;
			stuckCounter = 0,&lt;br /&gt;
			chunkinfo = [],&lt;br /&gt;
			waitingFinish,&lt;br /&gt;
			startTime,&lt;br /&gt;
			waitTime,&lt;br /&gt;
			$stuckXhr;&lt;br /&gt;
&lt;br /&gt;
		p = $.extend( true, {}, j.chunkedUploadDefault, p );&lt;br /&gt;
		if ( !file || !p.title ) {&lt;br /&gt;
			return j.fail( 'chunked upload&amp;gt; Either no file or no title specified.' );&lt;br /&gt;
		}&lt;br /&gt;
		if ( !( window.File &amp;amp;&amp;amp; window.File.prototype.slice &amp;amp;&amp;amp; window.FileReader &amp;amp;&amp;amp; window.Blob ) ) {&lt;br /&gt;
			return j.fail( 'chunked upload&amp;gt; Your browser does not support the full File-API, FileReader and Blob.' );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var internal = {&lt;br /&gt;
			status: 'uploading',&lt;br /&gt;
			uploadAPI: function ( params ) {&lt;br /&gt;
				params = $.extend( {&lt;br /&gt;
					format: 'json',&lt;br /&gt;
					action: 'upload',&lt;br /&gt;
					filekey: filekey,&lt;br /&gt;
					token: mw.user.tokens.get( 'csrfToken' )&lt;br /&gt;
				}, params );&lt;br /&gt;
				return $.post( APIURL, params );&lt;br /&gt;
			},&lt;br /&gt;
			nextChunk: function () {&lt;br /&gt;
				chunkSize = Math.min( remaining, p.maxChunkSize + addToNextChunk );&lt;br /&gt;
				var blob = file.slice( offset, offset + chunkSize ),&lt;br /&gt;
					mpm = j.multipartMessageForBinaryFiles();&lt;br /&gt;
&lt;br /&gt;
				addToNextChunk = 0;&lt;br /&gt;
&lt;br /&gt;
				// Notify everyone who likes to know how the situation is progressing&lt;br /&gt;
				chunkinfo.currentchunk = chunkinfo[ offsetid ];&lt;br /&gt;
				$def.notify( 'prog', chunkinfo );&lt;br /&gt;
&lt;br /&gt;
				mpm.appendPart( 'format', 'json' );&lt;br /&gt;
				mpm.appendPart( 'action', 'upload' );&lt;br /&gt;
				mpm.appendPart( 'filename', p.title );&lt;br /&gt;
				if ( filekey ) { mpm.appendPart( 'filekey', filekey ); }&lt;br /&gt;
				if ( p.useStash ) { mpm.appendPart( 'stash', 1 ); }&lt;br /&gt;
				mpm.appendPart( 'filesize', size );&lt;br /&gt;
				mpm.appendPart( 'offset', offset );&lt;br /&gt;
				if ( p.async ) { mpm.appendPart( 'async', 1 ); }&lt;br /&gt;
				mpm.appendPart( 'chunk', blob, p.title, file.type );&lt;br /&gt;
				mpm.appendPart( 'token', mw.user.tokens.get( 'csrfToken' ) );&lt;br /&gt;
				$.each( p.passToAPI.upload, function ( k, v ) {&lt;br /&gt;
					mpm.appendPart( k, v );&lt;br /&gt;
				} );&lt;br /&gt;
				if ( !p.async ) { mpm.noStuckWatcher(); }&lt;br /&gt;
				startTime = Date.now();&lt;br /&gt;
				waitTime = 4000;&lt;br /&gt;
				mpm.$send().done( internal.chunkUploaded ).fail( internal.chunkFailed ).progress( internal.chunkUploadProgess );&lt;br /&gt;
			},&lt;br /&gt;
			chunkStuck: function ( xhr ) {&lt;br /&gt;
				if ( $stuckXhr ) {&lt;br /&gt;
					$stuckXhr.abort();&lt;br /&gt;
				}&lt;br /&gt;
				$stuckXhr = $.getJSON( APIURL, {&lt;br /&gt;
					format: 'json',&lt;br /&gt;
					action: 'tokens'&lt;br /&gt;
				} ).done( function () {&lt;br /&gt;
					// Connection Ok ... we can try to fix this&lt;br /&gt;
					if ( ++stuckCounter &amp;gt; 10 ) {&lt;br /&gt;
						stuckCounter = 0;&lt;br /&gt;
						chunkinfo.currentchunk.progressText = 'Connection seems to be okay. Re-sending this request.';&lt;br /&gt;
						p.retry.serverError += 0.8;&lt;br /&gt;
						xhr.abort();&lt;br /&gt;
					} else {&lt;br /&gt;
						chunkinfo.currentchunk.progressText = 'Connection seems to be okay. Waiting one more time...';&lt;br /&gt;
					}&lt;br /&gt;
					$def.notify( 'stuckok', chunkinfo );&lt;br /&gt;
				} ).fail( function ( jqXHR, textStatus, errorThrown ) {&lt;br /&gt;
					// Connection broken ... user or server admins have to fix this&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'Please check your connection! Error: ' + textStatus + ' | ' + errorThrown;&lt;br /&gt;
					$def.notify( 'stuckbroken', chunkinfo );&lt;br /&gt;
				} );&lt;br /&gt;
			},&lt;br /&gt;
			chunkUploadProgess: function ( type, e ) {&lt;br /&gt;
				switch ( type ) {&lt;br /&gt;
				case 'uploadstatus':&lt;br /&gt;
					stuckCounter = 0;&lt;br /&gt;
					chunkinfo.currentchunk.progress = 100 * e.loaded / e.total;&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'upload in progress';&lt;br /&gt;
					$def.notify( type, chunkinfo );&lt;br /&gt;
					break;&lt;br /&gt;
				case 'stuck':&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'upload is stuck';&lt;br /&gt;
					$def.notify( type, chunkinfo );&lt;br /&gt;
					internal.chunkStuck( e );&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			chunkUploaded: function ( status, r ) {&lt;br /&gt;
				stuckCounter = 0;&lt;br /&gt;
				r = JSON.parse( r );&lt;br /&gt;
				var txt, args, defaultError;&lt;br /&gt;
&lt;br /&gt;
				defaultError = function ( args ) {&lt;br /&gt;
					args = Array.prototype.slice.call( args, 0 );&lt;br /&gt;
					args.unshift( r.error.code + ': ' + r.error.info );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				if ( r &amp;amp;&amp;amp; r.error ) {&lt;br /&gt;
					switch ( r.error.code ) {&lt;br /&gt;
					// r.error.info&lt;br /&gt;
					case 'badtoken':&lt;br /&gt;
						j.refreshToken( 'edit', $.proxy( internal.nextChunk, internal ) );&lt;br /&gt;
						break;&lt;br /&gt;
					case 'stasherror':&lt;br /&gt;
						if ( r.error.info.indexOf( 'UploadStashNotLoggedInException' ) === -1 ) {&lt;br /&gt;
							return defaultError( arguments );&lt;br /&gt;
						}&lt;br /&gt;
						/* falls through */&lt;br /&gt;
					case 'readapidenied':&lt;br /&gt;
					case 'writeapidenied':&lt;br /&gt;
					case 'invalid-file-key':&lt;br /&gt;
					case 'mustbeloggedin':&lt;br /&gt;
					case 'permissiondenied':&lt;br /&gt;
					case 'internal_api_error_UploadStashNotLoggedInException':&lt;br /&gt;
					case 'stashnotloggedin':&lt;br /&gt;
						p.callbacks.loginRequired( r.error.code + ': ' + r.error.info, function () {&lt;br /&gt;
							j.refreshToken( 'edit', $.proxy( internal.nextChunk, internal ) );&lt;br /&gt;
						} );&lt;br /&gt;
						break;&lt;br /&gt;
					case 'stashfailed':&lt;br /&gt;
					case 'offseterror':&lt;br /&gt;
					case 'offsetmismatch':&lt;br /&gt;
						if ( --p.retry.apiErrors &amp;lt; 0 ) {&lt;br /&gt;
							return defaultError( arguments );&lt;br /&gt;
						}&lt;br /&gt;
						if ( r.error.offset &amp;amp;&amp;amp; Number( r.error.offset ) !== offset ) {&lt;br /&gt;
							return internal.offsetmismatch( arguments, Number( r.error.offset ) );&lt;br /&gt;
						}&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
						break;&lt;br /&gt;
					default:&lt;br /&gt;
						return defaultError( arguments );&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				if ( !r || !r.upload ) {&lt;br /&gt;
					// Simply retry when getting an empty response&lt;br /&gt;
					txt = 'Empty response';&lt;br /&gt;
					if ( --p.retry.emptyResponse &amp;lt; 0 ) {&lt;br /&gt;
						args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
						args.unshift( txt );&lt;br /&gt;
						return internal.fail.apply( internal, args );&lt;br /&gt;
					}&lt;br /&gt;
					$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
					internal.nextChunk();&lt;br /&gt;
				}&lt;br /&gt;
				if ( r.upload.filekey ) { filekey = r.upload.filekey; }&lt;br /&gt;
&lt;br /&gt;
				var _successfullytransmitted = function () {&lt;br /&gt;
					chunkinfo.currentchunk.progress = 100;&lt;br /&gt;
					chunkinfo.currentchunk.progressText = 'Chunk uploaded';&lt;br /&gt;
					$def.notify( 'prog', chunkinfo );&lt;br /&gt;
					offset += chunkSize;&lt;br /&gt;
					remaining -= chunkSize;&lt;br /&gt;
					offsetid++;&lt;br /&gt;
				};&lt;br /&gt;
&lt;br /&gt;
				if ( r.upload.result === 'Warning' ) {&lt;br /&gt;
					var fileNameRelated = true,&lt;br /&gt;
						warnings = [],&lt;br /&gt;
						__insertNewParams = function ( newparams ) {&lt;br /&gt;
							p = $.extend( p, newparams );&lt;br /&gt;
							if ( waitingFinish ) {&lt;br /&gt;
								internal.finish();&lt;br /&gt;
							}&lt;br /&gt;
						};&lt;br /&gt;
&lt;br /&gt;
					$.each( r.upload.warnings, function ( k, v ) {&lt;br /&gt;
						warnings.push( k + ': \&amp;quot;' + v + '\&amp;quot;' );&lt;br /&gt;
						fileNameRelated = fileNameRelated &amp;amp;&amp;amp; $.inArray( k, j.uploadWarnings.filename ) &amp;gt; -1;&lt;br /&gt;
						return fileNameRelated;&lt;br /&gt;
					} );&lt;br /&gt;
					warnings = warnings.join( ', ' );&lt;br /&gt;
					if ( fileNameRelated ) {&lt;br /&gt;
						p.callbacks.nameNeedsChange( warnings, __insertNewParams );&lt;br /&gt;
					} else {&lt;br /&gt;
						p.callbacks.ignorewarningsRequired( warnings, __insertNewParams );&lt;br /&gt;
					}&lt;br /&gt;
					if ( remaining === 0 ) {&lt;br /&gt;
						waitingFinish = true;&lt;br /&gt;
					} else {&lt;br /&gt;
						// Simply continue with ignorewarnings flag&lt;br /&gt;
						p.passToAPI.upload.ignorewarnings = 1;&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				if ( r.upload.result === 'Continue' &amp;amp;&amp;amp; remaining !== 0 ) {&lt;br /&gt;
					var offsetRequested = Number( r.upload.offset ),&lt;br /&gt;
						offsetCalculated = offset + chunkSize,&lt;br /&gt;
						diff = offsetCalculated - offsetRequested;&lt;br /&gt;
&lt;br /&gt;
					if ( offsetRequested === offsetCalculated ) {&lt;br /&gt;
						_successfullytransmitted();&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					} else if ( offsetRequested &amp;lt; offsetCalculated ) {&lt;br /&gt;
						$def.notify( 'warn', chunkinfo, 'Offset requested by API is lower than offset calculated. \r\n issue?' );&lt;br /&gt;
						// Correct current chunk size&lt;br /&gt;
						chunkSize -= diff;&lt;br /&gt;
						addToNextChunk = diff;&lt;br /&gt;
						_successfullytransmitted();&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					} else {&lt;br /&gt;
						// Error handling: Simply upload last chunk again&lt;br /&gt;
						txt = 'Offset error: API wants to continue at ' + r.upload.offset + ' but calculated offset is ' + ( offset + chunkSize );&lt;br /&gt;
						if ( --p.retry.offsetError &amp;lt; 0 ) {&lt;br /&gt;
							args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
							args.unshift( txt );&lt;br /&gt;
							return internal.fail.apply( internal, args );&lt;br /&gt;
						}&lt;br /&gt;
						$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				_successfullytransmitted();&lt;br /&gt;
				if ( r.upload.result === 'Success' &amp;amp;&amp;amp; remaining === 0 ) {&lt;br /&gt;
					chunkinfo.currentchunk = chunkinfo.finalize;&lt;br /&gt;
					internal.finish();&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				if ( r.upload.result === 'Poll' ) {&lt;br /&gt;
					if ( remaining === 0 ) {&lt;br /&gt;
						chunkinfo.currentchunk = chunkinfo.finalize;&lt;br /&gt;
						internal.status = 'rebuilding';&lt;br /&gt;
&lt;br /&gt;
						chunkinfo.finalize.progress = 1;&lt;br /&gt;
						chunkinfo.finalize.progressText = 'Assembling chunks';&lt;br /&gt;
						$def.notify( 'prog', chunkinfo, txt );&lt;br /&gt;
					}&lt;br /&gt;
					setTimeout( internal.poll, 2000 );&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			offsetmismatch: function ( args, offsetExpectedByServer ) {&lt;br /&gt;
				var txt,&lt;br /&gt;
					_successfullytransmitted = function ( newOffset, newRemaining, newOffsetid ) {&lt;br /&gt;
						chunkinfo.currentchunk.progress = 100;&lt;br /&gt;
						chunkinfo.currentchunk.progressText = 'Chunk uploaded';&lt;br /&gt;
						$def.notify( 'prog', chunkinfo );&lt;br /&gt;
						offset = newOffset;&lt;br /&gt;
						remaining = newRemaining;&lt;br /&gt;
						offsetid = newOffsetid;&lt;br /&gt;
					};&lt;br /&gt;
&lt;br /&gt;
				$def.notify( 'warn', chunkinfo, 'Offset issue by Server detected. Attempting to fix automatically.' );&lt;br /&gt;
				if ( offsetExpectedByServer === offset + chunkSize ) {&lt;br /&gt;
					txt = &amp;quot;Looks like this chunk was successfully transmitted but didn't receive a success message for it.&amp;quot; +&lt;br /&gt;
						'Please have a look at the file after uploading.';&lt;br /&gt;
					$def.notify( 'warn', chunkinfo, txt );&lt;br /&gt;
					_successfullytransmitted(&lt;br /&gt;
						offsetExpectedByServer,&lt;br /&gt;
						remaining - chunkSize,&lt;br /&gt;
						offsetid + 1&lt;br /&gt;
					);&lt;br /&gt;
					p.retry.offsetError += 0.5;&lt;br /&gt;
				} else if ( Math.abs( offsetExpectedByServer - offset ) &amp;lt;= chunkSize ) {&lt;br /&gt;
					txt = 'The offset requested by the server differs by one or less than one chunk size from client side calculations.\r\n' +&lt;br /&gt;
						'Going to return what is requested but please have a close look at the file after uploading.\r\n' +&lt;br /&gt;
						'Offset expected by server: ' + offsetExpectedByServer + '. Offset calculated by client: ' + offset;&lt;br /&gt;
					$def.notify( 'warn', chunkinfo, txt );&lt;br /&gt;
					_successfullytransmitted(&lt;br /&gt;
						offsetExpectedByServer,&lt;br /&gt;
						size - offsetExpectedByServer,&lt;br /&gt;
						offsetExpectedByServer &amp;gt; offset ? offsetid + 1 : offsetid&lt;br /&gt;
					);&lt;br /&gt;
				} else {&lt;br /&gt;
					txt = 'The server expects continuation at byte ' + offsetExpectedByServer + '.\r\n' +&lt;br /&gt;
						'However, to the client side calculated offset is ' + offset + '.\r\n';&lt;br /&gt;
					$def.notify( 'warn', chunkinfo, txt );&lt;br /&gt;
				}&lt;br /&gt;
				if ( --p.retry.offsetError &amp;lt; 0 ) {&lt;br /&gt;
					args = Array.prototype.slice.call( args, 0 );&lt;br /&gt;
					args.unshift( txt );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				}&lt;br /&gt;
				internal.nextChunk();&lt;br /&gt;
			},&lt;br /&gt;
			/**&lt;br /&gt;
			* status checker&lt;br /&gt;
			**/&lt;br /&gt;
			poll: function () {&lt;br /&gt;
				var txt,&lt;br /&gt;
					args,&lt;br /&gt;
					cb,&lt;br /&gt;
					word;&lt;br /&gt;
&lt;br /&gt;
				switch ( internal.status ) {&lt;br /&gt;
				case 'uploading':&lt;br /&gt;
					word = 'process chunk';&lt;br /&gt;
					cb = function ( r ) {&lt;br /&gt;
						internal.chunkUploaded( 'OK', r );&lt;br /&gt;
						return true;&lt;br /&gt;
					};&lt;br /&gt;
					break;&lt;br /&gt;
				case 'rebuilding':&lt;br /&gt;
					word = 'rebuild uploaded file';&lt;br /&gt;
					cb = function ( r ) {&lt;br /&gt;
						return ( r.upload.stage === 'queued' ) ? false : ( internal.finish() || true );&lt;br /&gt;
					};&lt;br /&gt;
					break;&lt;br /&gt;
				case 'publishing':&lt;br /&gt;
					word = 'publish uploaded file';&lt;br /&gt;
					cb = function ( r ) {&lt;br /&gt;
						internal.finished( r );&lt;br /&gt;
						return true;&lt;br /&gt;
					};&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
				internal.uploadAPI( {&lt;br /&gt;
					checkstatus: 1&lt;br /&gt;
				} ).done( function ( r ) {&lt;br /&gt;
					if ( r &amp;amp;&amp;amp; r.error ) {&lt;br /&gt;
						switch ( r.error.code ) {&lt;br /&gt;
						// r.error.info&lt;br /&gt;
						case 'badtoken':&lt;br /&gt;
							j.refreshToken( 'edit', $.proxy( internal.poll, internal ) );&lt;br /&gt;
							break;&lt;br /&gt;
						case 'readapidenied':&lt;br /&gt;
						case 'writeapidenied':&lt;br /&gt;
						case 'invalid-file-key':&lt;br /&gt;
						case 'mustbeloggedin':&lt;br /&gt;
						case 'permissiondenied':&lt;br /&gt;
						case 'internal_api_error_UploadStashNotLoggedInException':&lt;br /&gt;
							p.callbacks.loginRequired( r.error.code + ': ' + r.error.info, function () {&lt;br /&gt;
								j.refreshToken( 'edit', $.proxy( internal.poll, internal ) );&lt;br /&gt;
							} );&lt;br /&gt;
							break;&lt;br /&gt;
						default:&lt;br /&gt;
							args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
							args.unshift( r.error.code + ': ' + r.error.info );&lt;br /&gt;
							return internal.fail.apply( internal, args );&lt;br /&gt;
						}&lt;br /&gt;
						return;&lt;br /&gt;
					}&lt;br /&gt;
					if ( !r || !r.upload ) {&lt;br /&gt;
						txt = 'Empty response: Still waiting for server to ' + word;&lt;br /&gt;
						if ( --p.retry.emptyResponse &amp;lt; 0 ) {&lt;br /&gt;
							args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
							args.unshift( txt );&lt;br /&gt;
							return internal.fail.apply( internal, args );&lt;br /&gt;
						}&lt;br /&gt;
						setTimeout( internal.poll, 7000 );&lt;br /&gt;
						$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
						return j.log( txt, r );&lt;br /&gt;
					}&lt;br /&gt;
					if ( r.upload.filekey ) { filekey = r.upload.filekey; }&lt;br /&gt;
					// If the operation succeeded, the callback is called (which returns true for most cases)&lt;br /&gt;
					// otherwise the callback is not called in JavaScript because the expression would evaluate to&lt;br /&gt;
					// false anyway&lt;br /&gt;
					if ( !( ( r.upload.result === 'Success' || r.upload.result === 'Continue' ) &amp;amp;&amp;amp; cb( r ) ) ) {&lt;br /&gt;
						txt = 'Still waiting for server to ' + word;&lt;br /&gt;
						$def.notify( 'prog', chunkinfo, txt );&lt;br /&gt;
						j.log( txt, r );&lt;br /&gt;
						setTimeout( internal.poll, 4500 );&lt;br /&gt;
					}&lt;br /&gt;
				} ).fail( function ( jqXHR, textStatus, errorThrown ) {&lt;br /&gt;
					// TODO: Server status etc.&lt;br /&gt;
					// Simply re-query&lt;br /&gt;
					txt = 'Sever-Error ' + jqXHR.status + '. Reason: ' + textStatus + ' ' + errorThrown + ' ... Still waiting for server to ' + word;&lt;br /&gt;
					if ( --p.retry.serverError &amp;lt; 0 ) {&lt;br /&gt;
						args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
						args.unshift( txt );&lt;br /&gt;
						return internal.fail.apply( internal, args );&lt;br /&gt;
					}&lt;br /&gt;
					setTimeout( internal.poll, 7000 );&lt;br /&gt;
					$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
					j.log( txt );&lt;br /&gt;
				} );&lt;br /&gt;
			},&lt;br /&gt;
			finish: function () {&lt;br /&gt;
				internal.status = 'publishing';&lt;br /&gt;
				chunkinfo.finalize.progress = 10;&lt;br /&gt;
				chunkinfo.finalize.progressText = 'Finishing';&lt;br /&gt;
&lt;br /&gt;
				$def.notify( 'prog', chunkinfo );&lt;br /&gt;
				j.log( 'chunked upload&amp;gt; Finishing.' );&lt;br /&gt;
				var params = {&lt;br /&gt;
					filename: p.title,&lt;br /&gt;
					filesize: size,&lt;br /&gt;
					comment: p.summary,&lt;br /&gt;
					text: p.text&lt;br /&gt;
				};&lt;br /&gt;
				if ( p.async ) { params.async = 1; }&lt;br /&gt;
				$.each( p.passToAPI.finish, function ( k, v ) {&lt;br /&gt;
					params[ k ] = v;&lt;br /&gt;
				} );&lt;br /&gt;
				internal.uploadAPI( params ).done( internal.possiblyFinished ).fail( internal.finishFailed );&lt;br /&gt;
			},&lt;br /&gt;
			possiblyFinished: function ( r ) {&lt;br /&gt;
				if ( r &amp;amp;&amp;amp; r.error ) {&lt;br /&gt;
					switch ( r.error.code ) {&lt;br /&gt;
					// r.error.info&lt;br /&gt;
					case 'badtoken':&lt;br /&gt;
						j.refreshToken( 'edit', $.proxy( internal.finish, internal ) );&lt;br /&gt;
						break;&lt;br /&gt;
					case 'readapidenied':&lt;br /&gt;
					case 'writeapidenied':&lt;br /&gt;
					case 'invalid-file-key':&lt;br /&gt;
					case 'mustbeloggedin':&lt;br /&gt;
					case 'permissiondenied':&lt;br /&gt;
					case 'internal_api_error_UploadStashNotLoggedInException':&lt;br /&gt;
						p.callbacks.loginRequired( r.error.code + ': ' + r.error.info, function () {&lt;br /&gt;
							j.refreshToken( 'edit', $.proxy( internal.finish, internal ) );&lt;br /&gt;
						} );&lt;br /&gt;
						break;&lt;br /&gt;
					default:&lt;br /&gt;
						var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
						args.unshift( r.error.code + ': ' + r.error.info );&lt;br /&gt;
						return internal.fail.apply( internal, args );&lt;br /&gt;
					}&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				if ( !r || !r.upload ) { return internal.finishFailed( 'empty response received' ); }&lt;br /&gt;
				if ( r.upload.filekey ) { filekey = r.upload.filekey; }&lt;br /&gt;
&lt;br /&gt;
				switch ( r.upload.result ) {&lt;br /&gt;
				case 'Poll':&lt;br /&gt;
					j.log( 'Waiting for upload to be published' );&lt;br /&gt;
					chunkinfo.finalize.progress = 50;&lt;br /&gt;
					chunkinfo.finalize.progressText = 'Waiting for upload to be published';&lt;br /&gt;
&lt;br /&gt;
					$def.notify( 'prog', chunkinfo );&lt;br /&gt;
					setTimeout( internal.poll, 2000 );&lt;br /&gt;
					break;&lt;br /&gt;
				case 'Success':&lt;br /&gt;
					internal.finished( r );&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			finished: function ( r ) {&lt;br /&gt;
				j.log( 'Uploaded successfully' );&lt;br /&gt;
				chunkinfo.finalize.progress = 100;&lt;br /&gt;
				chunkinfo.finalize.progressText = 'Uploaded successfully';&lt;br /&gt;
&lt;br /&gt;
				$def.notify( 'prog', chunkinfo );&lt;br /&gt;
				$def.resolve( chunkinfo, r );&lt;br /&gt;
			},&lt;br /&gt;
			chunkFailed: function ( statusText, response, xhr ) {&lt;br /&gt;
				stuckCounter = 0;&lt;br /&gt;
				var txt = 'Server error ' + xhr.status + ' after uploading chunk: ' + statusText + '\nResponse: ' + response.slice( 0, 500 ).replace( /\n\n/g, '\n' );&lt;br /&gt;
&lt;br /&gt;
				if ( --p.retry.serverError &amp;lt; 0 ) {&lt;br /&gt;
					var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
					args.shift( txt );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				}&lt;br /&gt;
				$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
				if ( startTime + 750 &amp;gt; Date.now() ) {&lt;br /&gt;
					setTimeout( function () {&lt;br /&gt;
						internal.nextChunk();&lt;br /&gt;
					}, waitTime *= 2 );&lt;br /&gt;
				} else {&lt;br /&gt;
					internal.nextChunk();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			finishFailed: function ( reasonOrXHR, textStatus, errorThrown ) {&lt;br /&gt;
				if ( typeof reasonOrXHR === 'object' ) { reasonOrXHR = textStatus + ' ' + errorThrown; }&lt;br /&gt;
&lt;br /&gt;
				var txt = 'Server error while publishing upload. Reason: ' + reasonOrXHR;&lt;br /&gt;
				if ( --p.retry.serverError &amp;lt; 0 ) {&lt;br /&gt;
					var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
					args.unshift( txt );&lt;br /&gt;
					return internal.fail.apply( internal, args );&lt;br /&gt;
				}&lt;br /&gt;
				$def.notify( 'err', chunkinfo, txt );&lt;br /&gt;
				internal.finish();&lt;br /&gt;
			},&lt;br /&gt;
			fail: function () {&lt;br /&gt;
				var args = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
				j.fail.apply( j, args );&lt;br /&gt;
				$def.reject.apply( $def, args );&lt;br /&gt;
			}&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		// Get some statistics about the file&lt;br /&gt;
		size = remaining = file.size;&lt;br /&gt;
		var remains4loop = size,&lt;br /&gt;
			chunksize4loop,&lt;br /&gt;
			i = 0;&lt;br /&gt;
&lt;br /&gt;
		while ( remains4loop &amp;gt; 0 ) {&lt;br /&gt;
			chunksize4loop = Math.min( remaining, p.maxChunkSize );&lt;br /&gt;
			chunkinfo[ i ] = {&lt;br /&gt;
				chunksize: chunksize4loop,&lt;br /&gt;
				remaining: remains4loop,&lt;br /&gt;
				progress: 0,&lt;br /&gt;
				progressText: 'in progress',&lt;br /&gt;
				id: i&lt;br /&gt;
			};&lt;br /&gt;
			remains4loop -= chunksize4loop;&lt;br /&gt;
			i++;&lt;br /&gt;
		}&lt;br /&gt;
		chunkinfo.finalize = {&lt;br /&gt;
			progress: 0,&lt;br /&gt;
			progressText: '',&lt;br /&gt;
			id: 'finalize'&lt;br /&gt;
		};&lt;br /&gt;
		internal.nextChunk();&lt;br /&gt;
		$def.chunkinfo = chunkinfo;&lt;br /&gt;
&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	createSampleUploadButton: function () {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		$( '&amp;lt;input type=&amp;quot;file&amp;quot; id=&amp;quot;files&amp;quot; name=&amp;quot;file&amp;quot;&amp;gt;' ).prependTo( mw.util.$content ).on( 'change', function ( /* e */ ) {&lt;br /&gt;
			j.chunkedUpload( {&lt;br /&gt;
				title: 'A random title.png'&lt;br /&gt;
			}, this.files[ 0 ] ).progress( function () {&lt;br /&gt;
				console.log( 'prog', arguments );&lt;br /&gt;
			} ).done( function () {&lt;br /&gt;
				console.log( 'done', arguments );&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	},&lt;br /&gt;
	$loadContinue: function ( title ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			j = this;&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.query( {&lt;br /&gt;
				action: 'query',&lt;br /&gt;
				prop: 'revisions',&lt;br /&gt;
				rvprop: 'content',&lt;br /&gt;
				rvlimit: 1,&lt;br /&gt;
				titles: title&lt;br /&gt;
			}, {&lt;br /&gt;
				method: 'POST',&lt;br /&gt;
				cache: false,&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					try {&lt;br /&gt;
						$def.resolve( firstItem( r.query.pages ).revisions[ 0 ][ '*' ] );&lt;br /&gt;
					} catch ( ex ) {&lt;br /&gt;
						$def.reject( ex );&lt;br /&gt;
					}&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to retrieve continue param.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$continueQuery: function ( query, result ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			qc = result[ 'query-continue' ],&lt;br /&gt;
			j = this,&lt;br /&gt;
			oldProp = query.prop,&lt;br /&gt;
			oldList = query.list;&lt;br /&gt;
&lt;br /&gt;
		if ( qc ) {&lt;br /&gt;
			var props = [],&lt;br /&gt;
				lists = [];&lt;br /&gt;
			$.each( qc, function ( k, v ) {&lt;br /&gt;
				if ( oldProp &amp;amp;&amp;amp; oldProp.indexOf( k ) &amp;gt; -1 ) {&lt;br /&gt;
					props.push( k );&lt;br /&gt;
				}&lt;br /&gt;
				if ( oldList &amp;amp;&amp;amp; oldList.indexOf( k ) &amp;gt; -1 ) {&lt;br /&gt;
					lists.push( k );&lt;br /&gt;
				}&lt;br /&gt;
				$.extend( query, v );&lt;br /&gt;
			} );&lt;br /&gt;
			if ( props.length ) {&lt;br /&gt;
				query.prop = props.join( '|' );&lt;br /&gt;
			} else {&lt;br /&gt;
				delete query.prop;&lt;br /&gt;
			}&lt;br /&gt;
			if ( lists.length ) {&lt;br /&gt;
				query.list = lists.join( '|' );&lt;br /&gt;
			} else {&lt;br /&gt;
				delete query.list;&lt;br /&gt;
			}&lt;br /&gt;
		} else if ( result.continue ) {&lt;br /&gt;
			// new style continuation&lt;br /&gt;
			$.extend( query, result.continue );&lt;br /&gt;
		} else {&lt;br /&gt;
			throw new Error( 'MW-JS-BOT: Nothing to continue.' );&lt;br /&gt;
		}&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.query( query, {&lt;br /&gt;
				method: 'POST',&lt;br /&gt;
				cache: false,&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$def.resolve( r );&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to continue query.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$saveContinue: function ( title, value, summary ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			j = this;&lt;br /&gt;
&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.editPage( {&lt;br /&gt;
				editType: 'text',&lt;br /&gt;
				text: value,&lt;br /&gt;
				title: title,&lt;br /&gt;
				summary: 'MW-JS-BOT: ' + ( summary || ' updating continue-param' ),&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$def.resolve( r );&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to save continue param.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$addLogline: function ( title, value, summary ) {&lt;br /&gt;
		var $def = $.Deferred(),&lt;br /&gt;
			j = this;&lt;br /&gt;
&lt;br /&gt;
		mw.loader.using( [ 'ext.gadget.libAPI' ], function () {&lt;br /&gt;
			mw.libs.commons.api.editPage( {&lt;br /&gt;
				editType: 'appendtext',&lt;br /&gt;
				text: '\n# ' + value,&lt;br /&gt;
				title: title,&lt;br /&gt;
				summary: 'MW-JS-BOT: ' + ( summary || ' logging' ),&lt;br /&gt;
				cb: function ( r ) {&lt;br /&gt;
					$def.resolve( r );&lt;br /&gt;
				},&lt;br /&gt;
				// r-result, query, text&lt;br /&gt;
				errCb: function ( t, r/* , q*/ ) {&lt;br /&gt;
					j.fail( 'Failed to log.' );&lt;br /&gt;
					$def.reject( r );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
		return $def;&lt;br /&gt;
	},&lt;br /&gt;
	$xmlFromString: function ( xmlString, title ) {&lt;br /&gt;
		var xml = $.parseXML( xmlString ),&lt;br /&gt;
			isXmlDoc = $.isXMLDoc( xml ),&lt;br /&gt;
			$xmlDoc = $( xml ),&lt;br /&gt;
			j = this;&lt;br /&gt;
&lt;br /&gt;
		if ( !isXmlDoc || !$xmlDoc || !$xmlDoc.length ) {&lt;br /&gt;
			j.warn( title + ' is not an XML Document.' );&lt;br /&gt;
		}&lt;br /&gt;
		return $xmlDoc;&lt;br /&gt;
	},&lt;br /&gt;
	stringFrom$xml: function ( $xml ) {&lt;br /&gt;
		if ( !window.XMLSerializer ) {&lt;br /&gt;
			window.XMLSerializer = function () {};&lt;br /&gt;
			window.XMLSerializer.prototype.serializeToString = function ( XMLObject ) {&lt;br /&gt;
				return XMLObject.xml || '';&lt;br /&gt;
			};&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var oSerializer = new XMLSerializer(),&lt;br /&gt;
			xmlStringOut = oSerializer.serializeToString( $xml[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
		return xmlStringOut;&lt;br /&gt;
	},&lt;br /&gt;
	$getWindowConsole: function () {&lt;br /&gt;
		if ( this.$windowConsole ) {&lt;br /&gt;
			return this.$windowConsole;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var $console = this.$windowConsole = $( '&amp;lt;div&amp;gt;' ).css( {&lt;br /&gt;
			'font-family': '&amp;quot;Lucida Console&amp;quot;, &amp;quot;Courier New&amp;quot;, Monospace'&lt;br /&gt;
		} ).appendTo( mw.util.$content );&lt;br /&gt;
		$console.$consoleTop = $( '&amp;lt;div&amp;gt;' ).text( 'Window Console by MW-JS-BOT' ).appendTo( $console );&lt;br /&gt;
		$console.$droppedEntryNote = $( '&amp;lt;span&amp;gt;' ).appendTo( $console.$consoleTop );&lt;br /&gt;
		$console.droppedEntries = 0;&lt;br /&gt;
		$console.visibleEntries = 0;&lt;br /&gt;
&lt;br /&gt;
		$console.dropFirstEntry = function () {&lt;br /&gt;
			$console.$consoleTop.next().remove();&lt;br /&gt;
			$console.droppedEntries++;&lt;br /&gt;
			$console.visibleEntries--;&lt;br /&gt;
			$console.$droppedEntryNote.text( $console.droppedEntries + ' entries were dropped from the window console.' );&lt;br /&gt;
		};&lt;br /&gt;
		$console.log = function () {&lt;br /&gt;
			if ( $console.totalEntries &amp;gt; 400 ) {&lt;br /&gt;
				$console.dropFirstEntry();&lt;br /&gt;
			}&lt;br /&gt;
			$console.visibleEntries++;&lt;br /&gt;
			var $entry = $( '&amp;lt;div&amp;gt;' ).attr( {&lt;br /&gt;
					class: 'windowconsole-entry'&lt;br /&gt;
				} ),&lt;br /&gt;
				argslen = arguments.length;&lt;br /&gt;
			for ( var i = 0; i &amp;lt; argslen; i++ ) {&lt;br /&gt;
				try {&lt;br /&gt;
					var $subentry = $( '&amp;lt;p&amp;gt;' ).text( arguments[ i ] );&lt;br /&gt;
					$subentry.appendTo( $entry );&lt;br /&gt;
				} catch ( ex ) {}&lt;br /&gt;
			}&lt;br /&gt;
			$entry.appendTo( $console );&lt;br /&gt;
		};&lt;br /&gt;
		return $console;&lt;br /&gt;
	},&lt;br /&gt;
	log: function ( /* unlimitedArgs*/ ) {&lt;br /&gt;
		if ( window.console ) {&lt;br /&gt;
			var arrArgs = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
			arrArgs.unshift( 'mwbot&amp;gt;' );&lt;br /&gt;
			if ( typeof console.log === 'function' ) {&lt;br /&gt;
				console.log.apply( console, arrArgs );&lt;br /&gt;
			} else {&lt;br /&gt;
				this.$getWindowConsole().apply( this, arrArgs );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	warn: function ( /* unlimitedArgs*/ ) {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		if ( window.console ) {&lt;br /&gt;
			var arrArgs = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
			if ( typeof console.warn === 'function' ) {&lt;br /&gt;
				arrArgs.unshift( 'mwbot&amp;gt;' );&lt;br /&gt;
				console.warn.apply( console, arrArgs );&lt;br /&gt;
			} else {&lt;br /&gt;
				arrArgs.unshift( 'WARNING&amp;gt;' );&lt;br /&gt;
				j.log.apply( j, arrArgs );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	fail: function ( /* unlimitedArgs*/ ) {&lt;br /&gt;
		var j = this;&lt;br /&gt;
		if ( window.console ) {&lt;br /&gt;
			var arrArgs = Array.prototype.slice.call( arguments, 0 );&lt;br /&gt;
			if ( typeof console.error === 'function' ) {&lt;br /&gt;
				arrArgs.unshift( 'mwbot&amp;gt;' );&lt;br /&gt;
				console.error.apply( console, arrArgs );&lt;br /&gt;
			} else {&lt;br /&gt;
				arrArgs.unshift( 'ERR&amp;gt;' );&lt;br /&gt;
				j.log.apply( j, arrArgs );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
} );&lt;br /&gt;
window.MwJSBot = jsb;&lt;br /&gt;
&lt;br /&gt;
var h = {};&lt;br /&gt;
h[ myModuleName ] = 'ready';&lt;br /&gt;
mw.loader.state( h );&lt;br /&gt;
&lt;br /&gt;
new MwJSBot().log( 'Hello. I am your MwJSBot framework.' );&lt;br /&gt;
}( jQuery, mediaWiki ) );&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js</id>
		<title>Участник:Kolbaska/common.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js"/>
				<updated>2025-11-14T04:01:11Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Keep code in MediaWiki:Common.js to a minimum as it is unconditionally&lt;br /&gt;
 * loaded for all users on every wiki page. If possible create a gadget that is&lt;br /&gt;
 * enabled by default instead of adding it here (since gadgets are fully&lt;br /&gt;
 * optimized ResourceLoader modules with possibility to add dependencies etc.)&lt;br /&gt;
 *&lt;br /&gt;
 * Since Common.js isn't a gadget, there is no place to declare its&lt;br /&gt;
 * dependencies, so we have to lazy load them with mw.loader.using on demand and&lt;br /&gt;
 * then execute the rest in the callback. In most cases these dependencies will&lt;br /&gt;
 * be loaded (or loading) already and the callback will not be delayed. In case a&lt;br /&gt;
 * dependency hasn't arrived yet it'll make sure those are loaded before this.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/* global mw, $ */&lt;br /&gt;
/* jshint strict:false, browser:true */&lt;br /&gt;
&lt;br /&gt;
mw.loader.using( [ 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
    /* Begin of mw.loader.using callback */&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Map addPortletLink to mw.util&lt;br /&gt;
     * @deprecated: Use mw.util.addPortletLink instead.&lt;br /&gt;
     */&lt;br /&gt;
    mw.log.deprecate( window, 'addPortletLink', mw.util.addPortletLink, 'Use mw.util.addPortletLink instead' );&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
     * @rev 6&lt;br /&gt;
     */&lt;br /&gt;
    var extraCSS = mw.util.getParamValue( 'withCSS' ),&lt;br /&gt;
        extraJS = mw.util.getParamValue( 'withJS' );&lt;br /&gt;
&lt;br /&gt;
    if ( extraCSS ) {&lt;br /&gt;
        if ( extraCSS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.css$/ ) ) {&lt;br /&gt;
            mw.loader.load( '/index.php?title=' + extraCSS + '&amp;amp;action=raw&amp;amp;ctype=text/css', 'text/css' );&lt;br /&gt;
        } else {&lt;br /&gt;
            mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( extraJS ) {&lt;br /&gt;
        if ( extraJS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.js$/ ) ) {&lt;br /&gt;
            mw.loader.load( '/index.php?title=' + extraJS + '&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
        } else {&lt;br /&gt;
            mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Collapsible tables; reimplemented with mw-collapsible&lt;br /&gt;
     * Styling is also in place to avoid FOUC&lt;br /&gt;
     *&lt;br /&gt;
     * Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].&lt;br /&gt;
     * @version 3.0.0 (2018-05-20)&lt;br /&gt;
     * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js&lt;br /&gt;
     * @author [[User:R. Koot]]&lt;br /&gt;
     * @author [[User:Krinkle]]&lt;br /&gt;
     * @author [[User:TheDJ]]&lt;br /&gt;
     * @deprecated Since MediaWiki 1.20: Use class=&amp;quot;mw-collapsible&amp;quot; instead which&lt;br /&gt;
     * is supported in MediaWiki core. Shimmable since MediaWiki 1.32&lt;br /&gt;
     *&lt;br /&gt;
     * @param {jQuery} $content&lt;br /&gt;
     */&lt;br /&gt;
    function makeCollapsibleMwCollapsible( $content ) {&lt;br /&gt;
        var $tables = $content&lt;br /&gt;
            .find( 'table.collapsible:not(.mw-collapsible)' )&lt;br /&gt;
            .addClass( 'mw-collapsible' );&lt;br /&gt;
&lt;br /&gt;
        $.each( $tables, function ( index, table ) {&lt;br /&gt;
            // mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');&lt;br /&gt;
            if ( $( table ).hasClass( 'collapsed' ) ) {&lt;br /&gt;
                $( table ).addClass( 'mw-collapsed' );&lt;br /&gt;
                // mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
        if ( $tables.length &amp;gt; 0 ) {&lt;br /&gt;
            mw.loader.using( 'jquery.makeCollapsible' ).then( function () {&lt;br /&gt;
                $tables.makeCollapsible();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    mw.hook( 'wikipage.content' ).add( makeCollapsibleMwCollapsible );&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Add support to mw-collapsible for autocollapse, innercollapse and outercollapse&lt;br /&gt;
     *&lt;br /&gt;
     * Maintainers: TheDJ&lt;br /&gt;
     */&lt;br /&gt;
    function mwCollapsibleSetup( $collapsibleContent ) {&lt;br /&gt;
        var $element,&lt;br /&gt;
            $toggle,&lt;br /&gt;
            autoCollapseThreshold = 2;&lt;br /&gt;
        $.each( $collapsibleContent, function ( index, element ) {&lt;br /&gt;
            $element = $( element );&lt;br /&gt;
            if ( $element.hasClass( 'collapsible' ) ) {&lt;br /&gt;
                $element.find( 'tr:first &amp;gt; th:first' ).prepend( $element.find( 'tr:first &amp;gt; * &amp;gt; .mw-collapsible-toggle' ) );&lt;br /&gt;
            }&lt;br /&gt;
            if ( $collapsibleContent.length &amp;gt;= autoCollapseThreshold &amp;amp;&amp;amp; $element.hasClass( 'autocollapse' ) ) {&lt;br /&gt;
                $element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
            } else if ( $element.hasClass( 'innercollapse' ) ) {&lt;br /&gt;
                if ( $element.parents( '.outercollapse' ).length &amp;gt; 0 ) {&lt;br /&gt;
                    $element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // because of colored backgrounds, style the link in the text color&lt;br /&gt;
            // to ensure accessible contrast&lt;br /&gt;
            $toggle = $element.find( '.mw-collapsible-toggle' );&lt;br /&gt;
            if ( $toggle.length ) {&lt;br /&gt;
                // Make the toggle inherit text color (Updated for T333357 2023-04-29)&lt;br /&gt;
                if ( $toggle.parent()[ 0 ].style.color ) {&lt;br /&gt;
                    $toggle.css( 'color', 'inherit' );&lt;br /&gt;
                    $toggle.find( '.mw-collapsible-text' ).css( 'color', 'inherit' );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );&lt;br /&gt;
&lt;br /&gt;
    /* End of mw.loader.using callback */&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
/*jshint curly:false*/&lt;br /&gt;
/*global jQuery:false, mediaWiki:false, MwJSBot:false*/&lt;br /&gt;
&lt;br /&gt;
( function( $, mw, undefined ) {&lt;br /&gt;
    'use strict';&lt;br /&gt;
&lt;br /&gt;
    var modeNewFile;&lt;br /&gt;
    var i;&lt;br /&gt;
    var random = Math.round(Math.random() * 0x1000000000);&lt;br /&gt;
    var commonwWikiKey = &amp;quot;commonswiki&amp;quot; + random;&lt;br /&gt;
    var commonsWiki = {};&lt;br /&gt;
    var modules = [&lt;br /&gt;
        [ &amp;quot;ext.gadget.editDropdown&amp;quot;, &amp;quot;ver1_svg&amp;quot;, [], null, commonwWikiKey ],&lt;br /&gt;
        [ &amp;quot;ext.gadget.libAPI&amp;quot;, &amp;quot;ver1_svg&amp;quot;, [], null, commonwWikiKey ]&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function ucFirst( s ) {&lt;br /&gt;
        return s[ 0 ].toUpperCase() + s.slice( 1 );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var _install = function() {&lt;br /&gt;
&lt;br /&gt;
        var $reuploadLink = $( '#mw-imagepage-reupload-link' )&lt;br /&gt;
            .find( 'a' ),&lt;br /&gt;
            $activationLinks;&lt;br /&gt;
&lt;br /&gt;
        if ( $reuploadLink.length ) {&lt;br /&gt;
            $activationLinks = $( '&amp;lt;a&amp;gt;', {&lt;br /&gt;
                    text: &amp;quot; (chunked upload)&amp;quot;&lt;br /&gt;
                } )&lt;br /&gt;
                .attr( {&lt;br /&gt;
                    href: '#chunked upload'&lt;br /&gt;
                } )&lt;br /&gt;
                .insertAfter( $reuploadLink );&lt;br /&gt;
&lt;br /&gt;
            $activationLinks = $activationLinks.add(&lt;br /&gt;
                mw.libs.commons.ui.addEditLink(&lt;br /&gt;
                    '#chunked upload',&lt;br /&gt;
                    &amp;quot;upload new version (chunked)&amp;quot;,&lt;br /&gt;
                    'e-chunkedupload-overwrite',&lt;br /&gt;
                    &amp;quot;Overwrite file with another one using chunked uploading&amp;quot; ) );&lt;br /&gt;
        } else if ( mw.config.get( 'wgCanonicalNamespace' ) === 'File' ) {&lt;br /&gt;
            var title, validTitle;&lt;br /&gt;
            try {&lt;br /&gt;
                title = mw.config.get( 'wgTitle' );&lt;br /&gt;
                validTitle = new mw.Title( title );&lt;br /&gt;
&lt;br /&gt;
                validTitle = validTitle.getExtension().length &amp;amp;&amp;amp; !/(?:\/|\#|\:)/.test( title );&lt;br /&gt;
            } catch ( ex ) {}&lt;br /&gt;
            if ( validTitle ) {&lt;br /&gt;
                $activationLinks = $( mw.libs.commons.ui.addEditLink(&lt;br /&gt;
                    '#chunked upload',&lt;br /&gt;
                    &amp;quot;upload (chunked)&amp;quot;,&lt;br /&gt;
                    'e-chunkedupload-overwrite',&lt;br /&gt;
                    &amp;quot;Create new file using chunked uploading&amp;quot; ) );&lt;br /&gt;
                modeNewFile = true;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if ( $activationLinks ) $activationLinks.click( window.bigChunkedUpload );&lt;br /&gt;
        if ( mw.util.getParamValue( 'chunkedupload' ) ) window.bigChunkedUpload();&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    window.bigChunkedUpload = function( e ) {&lt;br /&gt;
        if ( e ) e.preventDefault();&lt;br /&gt;
        if ( null === mw.loader.getState( 'mediawiki.commons.MwJSBot' ) ) {&lt;br /&gt;
            mw.loader.implement( 'mediawiki.commons.MwJSBot', [&lt;br /&gt;
                &amp;quot;//wiki.neverlands.ru/index.php?action=raw&amp;amp;ctype=text/javascript&amp;amp;title=User:Rillke/MwJSBot.js&amp;amp;_=2&amp;quot;&lt;br /&gt;
            ], { /*no styles*/ }, { /*no messages*/ } );&lt;br /&gt;
        }&lt;br /&gt;
        mw.loader.using( [&lt;br /&gt;
            'mediawiki.commons.MwJSBot',&lt;br /&gt;
            'jquery.ui',&lt;br /&gt;
            'mediawiki.util' ], _bigChunkedUpload );&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var _bigChunkedUpload = function() {&lt;br /&gt;
        var instanceId = 'i' + Math.round( Math.random() * 1073741824 ),&lt;br /&gt;
            start,&lt;br /&gt;
            makeWikiLink = function( t, text ) {&lt;br /&gt;
                return $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
                    .attr( {&lt;br /&gt;
                        href: mw.util.getUrl( t ),&lt;br /&gt;
                        target: '_blank',&lt;br /&gt;
                        title: t&lt;br /&gt;
                    } )&lt;br /&gt;
                    .text( text || t );&lt;br /&gt;
            },&lt;br /&gt;
            $dlg = $( '&amp;lt;div&amp;gt;' ),&lt;br /&gt;
            w = Math.min( $( window )&lt;br /&gt;
                .width(), 1200 ),&lt;br /&gt;
            $logInRequired = $( '&amp;lt;div class=&amp;quot;ui-state-highlight&amp;quot; style=&amp;quot;display:none; cursor:pointer&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;To continue uploading, please log in and click here after you did so. Script will try to resume. Error reported by server is: &amp;quot; )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $progDiv = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $progBar = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .css( {&lt;br /&gt;
                width: '98%',&lt;br /&gt;
                padding: '2px'&lt;br /&gt;
            } )&lt;br /&gt;
            .progressbar( {&lt;br /&gt;
                value: 0&lt;br /&gt;
            } )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $progConsole = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .css( {&lt;br /&gt;
                'background': 'black',&lt;br /&gt;
                'color': 'white',&lt;br /&gt;
                'font-family': '\'Lucida Console\',Console,monospace',&lt;br /&gt;
                'overflow': 'auto',&lt;br /&gt;
                'width': '98%',&lt;br /&gt;
                'height': '200px',&lt;br /&gt;
                'border': '1px solid grey',&lt;br /&gt;
                'padding': '2px',&lt;br /&gt;
                'white-space': 'pre-wrap',&lt;br /&gt;
                'resize': 'both'&lt;br /&gt;
            } )&lt;br /&gt;
            .text( 'Hi, ' + mw.config.get( 'wgUserName' ) + '! Thank you for testing version 0.0.1 of ' )&lt;br /&gt;
            .append( makeWikiLink( 'User:Rillke/bigChunkedUpload.js' ), '.' )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            pad = function( digit, number, input ) {&lt;br /&gt;
                input += '';&lt;br /&gt;
                return new Array( Math.max( number + 1 - input.length, 1 ) )&lt;br /&gt;
                    .join( digit ) + input;&lt;br /&gt;
            },&lt;br /&gt;
            $lastLogLineEndSpan,&lt;br /&gt;
            log = function( what, time, color ) {&lt;br /&gt;
                var $logline = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
                    .text( pad( '0', 5, time ) + ': ' + what );&lt;br /&gt;
                if ( color ) $logline.css( 'color', color );&lt;br /&gt;
                $lastLogLineEndSpan = $( '&amp;lt;span&amp;gt;' )&lt;br /&gt;
                    .appendTo( $logline );&lt;br /&gt;
                $progConsole.append( $logline );&lt;br /&gt;
                $progConsole.clearQueue()&lt;br /&gt;
                    .animate( {&lt;br /&gt;
                        scrollTop: $progConsole.scrollTop() + $logline.position()&lt;br /&gt;
                            .top&lt;br /&gt;
                    }, 800 );&lt;br /&gt;
            },&lt;br /&gt;
            logInlineProgress = function( what ) {&lt;br /&gt;
                if ( $lastLogLineEndSpan ) $lastLogLineEndSpan.text( what );&lt;br /&gt;
            },&lt;br /&gt;
            $progTextDiv = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;Ready. Selecting a file will immediately start the upload.&amp;quot; )&lt;br /&gt;
            .appendTo( $progDiv ),&lt;br /&gt;
            $options = $( '&amp;lt;fieldset&amp;gt;' )&lt;br /&gt;
            .appendTo( $dlg ),&lt;br /&gt;
            $optionsL = $( '&amp;lt;legend&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;Upload options&amp;quot; )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $czWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $czl = $( '&amp;lt;label for=&amp;quot;chunksize' + instanceId + '&amp;quot; style=&amp;quot;display:block&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;Chunk size: &amp;quot; )&lt;br /&gt;
            .appendTo( $czWrap ),&lt;br /&gt;
            $czlz = $( '&amp;lt;span&amp;gt;' )&lt;br /&gt;
            .appendTo( $czl ),&lt;br /&gt;
            $cz = $( '&amp;lt;div id=&amp;quot;chunksize' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
            .css( {&lt;br /&gt;
                width: '98%'&lt;br /&gt;
            } )&lt;br /&gt;
            .slider( {&lt;br /&gt;
                max: 20480,&lt;br /&gt;
                min: 100,&lt;br /&gt;
                change: function( e, ui ) {&lt;br /&gt;
                    $czlz.text( ui.value + ' KiB' );&lt;br /&gt;
                },&lt;br /&gt;
                slide: function( e, ui ) {&lt;br /&gt;
                    $czlz.text( ui.value + ' KiB' );&lt;br /&gt;
                }&lt;br /&gt;
            } )&lt;br /&gt;
            .slider( 'option', 'value', 4096 )&lt;br /&gt;
            .appendTo( $czWrap ),&lt;br /&gt;
            $useStashWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $useStash = $( '&amp;lt;input type=&amp;quot;checkbox&amp;quot; checked=&amp;quot;checked&amp;quot; id=&amp;quot;usestash' + instanceId + '&amp;quot; /&amp;gt;' )&lt;br /&gt;
            .appendTo( $useStashWrap ),&lt;br /&gt;
            $useStashL = $( '&amp;lt;label for=&amp;quot;usestash' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot; use stash and async (recommended for large videos and photos)&amp;quot; )&lt;br /&gt;
            .appendTo( $useStashWrap ),&lt;br /&gt;
            $fnWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $fnl = $( '&amp;lt;label for=&amp;quot;filename' + instanceId + '&amp;quot; style=&amp;quot;display:block&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( &amp;quot;File name: &amp;quot; )&lt;br /&gt;
            .appendTo( $fnWrap ),&lt;br /&gt;
            $fn = $( '&amp;lt;input type=&amp;quot;text&amp;quot; style=&amp;quot;width:98%&amp;quot; placeholder=&amp;quot;File:Filename.ext&amp;quot; title=&amp;quot;file name goes here&amp;quot; id=&amp;quot;filename' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
            .val( mw.config.get( 'wgPageName' ) )&lt;br /&gt;
            .appendTo( $fnWrap ),&lt;br /&gt;
            $sumWrap = $( '&amp;lt;div&amp;gt;' )&lt;br /&gt;
            .appendTo( $options ),&lt;br /&gt;
            $suml = $( '&amp;lt;label for=&amp;quot;summary' + instanceId + '&amp;quot; style=&amp;quot;display:block&amp;quot;&amp;gt;' )&lt;br /&gt;
            .text( modeNewFile ? &amp;quot;File description&amp;quot; : &amp;quot;Summary or Reason: &amp;quot; )&lt;br /&gt;
            .appendTo( $sumWrap ),&lt;br /&gt;
            $sum = ( modeNewFile ? $( '&amp;lt;textarea style=&amp;quot;width:98%; height: 7em;&amp;quot; placeholder=&amp;quot;File description&amp;quot; title=&amp;quot;file description goes here&amp;quot; id=&amp;quot;summary' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
                .appendTo( $sumWrap ) : $( '&amp;lt;input type=&amp;quot;text&amp;quot; style=&amp;quot;width:98%&amp;quot; placeholder=&amp;quot;Reason/Summary&amp;quot; title=&amp;quot;reason/summary go here&amp;quot; id=&amp;quot;summary' + instanceId + '&amp;quot;&amp;gt;' )&lt;br /&gt;
                .appendTo( $sumWrap ) ),&lt;br /&gt;
            $fsel = $( '&amp;lt;input type=&amp;quot;file&amp;quot; id=&amp;quot;files&amp;quot; name=&amp;quot;file&amp;quot; style=&amp;quot;width:98%&amp;quot;&amp;gt;' )&lt;br /&gt;
            .appendTo( $options )&lt;br /&gt;
            .change( function( e ) {&lt;br /&gt;
                start = new Date();&lt;br /&gt;
&lt;br /&gt;
                var lastdate,&lt;br /&gt;
                    oldOnBeforeUnload = window.onbeforeunload,&lt;br /&gt;
                    oldDocTitle = document.title,&lt;br /&gt;
                    filename = ucFirst( $fn.val()&lt;br /&gt;
                        .replace( /File:/, '' )&lt;br /&gt;
                        .replace( /_/g, ' ' ) ),&lt;br /&gt;
                    lastblink,&lt;br /&gt;
                    _blink = function( $node ) {&lt;br /&gt;
                        if ( lastblink ) clearTimeout( lastblink );&lt;br /&gt;
                        $node.addClass( 'ui-state-error' );&lt;br /&gt;
                        setTimeout( function() {&lt;br /&gt;
                            $node.removeClass( 'ui-state-error' );&lt;br /&gt;
                        }, 1000 );&lt;br /&gt;
                    },&lt;br /&gt;
                    _onLogInRequired = function( err, callWhenDone ) {&lt;br /&gt;
                        var _onNodeClick = function() {&lt;br /&gt;
                            $logInRequired.unbind( 'click', _onNodeClick )&lt;br /&gt;
                                .hide();&lt;br /&gt;
                            callWhenDone();&lt;br /&gt;
                        };&lt;br /&gt;
                        $logInRequired.find( 'span' )&lt;br /&gt;
                            .first()&lt;br /&gt;
                            .remove();&lt;br /&gt;
                        $logInRequired.append( $( '&amp;lt;span&amp;gt;' )&lt;br /&gt;
                                .text( err ) )&lt;br /&gt;
                            .show()&lt;br /&gt;
                            .click( _onNodeClick );&lt;br /&gt;
                    },&lt;br /&gt;
                    _onUploadProgress = function( progressCalculated, date ) {&lt;br /&gt;
                        if ( !lastdate ) lastdate = start;&lt;br /&gt;
                        if ( ( date - lastdate ) &amp;lt; 200 &amp;amp;&amp;amp; progressCalculated !== 1 ) return;&lt;br /&gt;
                        lastdate = date;&lt;br /&gt;
                        progressCalculated = Math.round( progressCalculated, 1 );&lt;br /&gt;
                        logInlineProgress( ' Upload: ' + progressCalculated + '%' );&lt;br /&gt;
                    },&lt;br /&gt;
                    _updateProgressBar = function( progressCalculated, date ) {&lt;br /&gt;
                        if ( !lastdate ) lastdate = start;&lt;br /&gt;
                        if ( ( date - lastdate ) &amp;lt; 200 &amp;amp;&amp;amp; progressCalculated !== 100 ) return;&lt;br /&gt;
                        $progBar.progressbar( 'option', 'value', progressCalculated );&lt;br /&gt;
                        document.title = Math.round( progressCalculated ) + &amp;quot;% of &amp;quot; + filename + &amp;quot; uploaded  - Chunked upload - Wikimedia Commons&amp;quot;;&lt;br /&gt;
                    };&lt;br /&gt;
&lt;br /&gt;
                if ( !filename ) return _blink( $fn );&lt;br /&gt;
&lt;br /&gt;
                var params = {&lt;br /&gt;
                    maxChunkSize: $cz.slider( 'option', 'value' ) * 1024,&lt;br /&gt;
                    retry: {&lt;br /&gt;
                        serverError: 250&lt;br /&gt;
                    },&lt;br /&gt;
                    title: $fn.val()&lt;br /&gt;
                        .replace( /File:/, '' ),&lt;br /&gt;
                    summary: '[[c:User:Rillke/bigChunkedUpload.js]]: ' + $sum.val(),&lt;br /&gt;
                    useStash: $useStash.prop( 'checked' ),&lt;br /&gt;
                    async: $useStash.prop( 'checked' ),&lt;br /&gt;
                    passToAPI: {&lt;br /&gt;
                        upload: {&lt;br /&gt;
                            ignorewarnings: 1&lt;br /&gt;
                        },&lt;br /&gt;
                        finish: {&lt;br /&gt;
                            ignorewarnings: 1&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
                    callbacks: {&lt;br /&gt;
                        loginRequired: _onLogInRequired&lt;br /&gt;
                    }&lt;br /&gt;
                };&lt;br /&gt;
                if ( modeNewFile ) {&lt;br /&gt;
                    params.text = $sum.val();&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                var $def = new MwJSBot()&lt;br /&gt;
                    .chunkedUpload( params, this.files[ 0 ] )&lt;br /&gt;
                    .progress( function( type, chunkinfo, txt ) {&lt;br /&gt;
                        var cc = chunkinfo.currentchunk,&lt;br /&gt;
                            idIsNumber = ( 'number' === typeof cc.id ),&lt;br /&gt;
                            curIdPlus1 = idIsNumber ? ( cc.id + 1 ) : cc.id,&lt;br /&gt;
                            curId = idIsNumber ? cc.id : 0,&lt;br /&gt;
                            l = chunkinfo.length,&lt;br /&gt;
                            progressCalculated = ( ( curId ) / l ) * 100 + ( cc.progress / l ),&lt;br /&gt;
                            d = new Date(),&lt;br /&gt;
                            ddiff = Math.round( ( d - start ) / 1000 ),&lt;br /&gt;
                            prog = '',&lt;br /&gt;
                            color = '';&lt;br /&gt;
&lt;br /&gt;
                        // second term respects progress of current chunk&lt;br /&gt;
                        if ( idIsNumber ) _updateProgressBar( progressCalculated );&lt;br /&gt;
&lt;br /&gt;
                        // handle these often frequently occuring events differently&lt;br /&gt;
                        if ( 'uploadstatus' === type ) {&lt;br /&gt;
                            return _onUploadProgress( cc.progress, d );&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        txt = txt || cc.progressText;&lt;br /&gt;
                        prog += &amp;quot;Uploaded part &amp;quot; + curIdPlus1 + &amp;quot; of &amp;quot; + l + &amp;quot;;&amp;quot;;&lt;br /&gt;
                        prog += &amp;quot; Time elapsed: &amp;quot; + ddiff + &amp;quot;s ;&amp;quot;;&lt;br /&gt;
                        prog += &amp;quot; Status: &amp;quot; + txt;&lt;br /&gt;
                        $progTextDiv.text( prog );&lt;br /&gt;
                        switch ( type ) {&lt;br /&gt;
                            case 'err':&lt;br /&gt;
                            case 'stuck':&lt;br /&gt;
                                color = '#E9D977';&lt;br /&gt;
                                break;&lt;br /&gt;
                            default:&lt;br /&gt;
                                break;&lt;br /&gt;
                        }&lt;br /&gt;
                        log( curIdPlus1 + '/' + l + '&amp;gt; ' + txt, ddiff, color );&lt;br /&gt;
&lt;br /&gt;
                    } )&lt;br /&gt;
                    .done( function() {&lt;br /&gt;
                        var txt = &amp;quot;DONE.&amp;quot;,&lt;br /&gt;
                            d = new Date(),&lt;br /&gt;
                            ddiff = Math.round( ( d - start ) / 1000 );&lt;br /&gt;
&lt;br /&gt;
                        $progDiv.text( txt );&lt;br /&gt;
                        log( txt, ddiff, '#77E9C7' );&lt;br /&gt;
                        window.onbeforeunload = oldOnBeforeUnload;&lt;br /&gt;
                        window.location.href = &amp;quot;/wiki/File:&amp;quot; + encodeURIComponent( $fn.val()&lt;br /&gt;
                            .replace( /^File:/i, &amp;quot;&amp;quot; ) );&lt;br /&gt;
                    } )&lt;br /&gt;
                    .fail( function( txt ) {&lt;br /&gt;
                        txt = &amp;quot;FAILED: &amp;quot; + txt;&lt;br /&gt;
&lt;br /&gt;
                        var d = new Date(),&lt;br /&gt;
                            ddiff = Math.round( ( d - start ) / 1000 );&lt;br /&gt;
&lt;br /&gt;
                        $progDiv.text( txt );&lt;br /&gt;
                        log( txt, ddiff, '#E977C7' );&lt;br /&gt;
                        window.onbeforeunload = oldOnBeforeUnload;&lt;br /&gt;
                        document.title = &amp;quot;FAILED! File upload failed - Chunked upload - Wikimedia Commons&amp;quot;;&lt;br /&gt;
                        setTimeout( function() {&lt;br /&gt;
                            document.title = oldDocTitle;&lt;br /&gt;
                        }, 10000 );&lt;br /&gt;
                    } );&lt;br /&gt;
&lt;br /&gt;
                $fn.add( $sum )&lt;br /&gt;
                    .add( $fsel )&lt;br /&gt;
                    .add( $useStash )&lt;br /&gt;
                    .attr( 'disabled', 'disabled' );&lt;br /&gt;
                $cz.slider( 'option', 'disabled', true );&lt;br /&gt;
&lt;br /&gt;
                // Prevent leaving the page accidentally&lt;br /&gt;
                window.onbeforeunload = function() {&lt;br /&gt;
                    return &amp;quot;Upload seems to be still in progress. Do you really wish to quit?&amp;quot;;&lt;br /&gt;
                };&lt;br /&gt;
            } );&lt;br /&gt;
&lt;br /&gt;
        $dlg.dialog( {&lt;br /&gt;
            'title': &amp;quot;Overwrite existing files using Chunked Upload protocol&amp;quot;,&lt;br /&gt;
            //'height': $(window).height(),&lt;br /&gt;
            'width': w&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Set focus to summary-field&lt;br /&gt;
        $sum.focus();&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // Register globally&lt;br /&gt;
    if ( $.inArray( mw.config.get( 'wgDBname' ), [ 'commonswiki', 'commonsarchivewiki' ] ) &amp;lt; 0 ) {&lt;br /&gt;
        // mw.loader.addSource has a check for source key uniqueness&lt;br /&gt;
        // that if it fails, throws an error.&lt;br /&gt;
        // Since I am offering many scripts, I would like to be able to register&lt;br /&gt;
        // a source from multiple code positions. However the loader has no&lt;br /&gt;
        // accessors to its internally maintained list of sources. Therefore&lt;br /&gt;
        // ensure with high probabiltiy that every source key added is unique.&lt;br /&gt;
        commonsWiki[commonwWikiKey] = &amp;quot;//wiki.neverlands.ru/load.php&amp;quot;;&lt;br /&gt;
        mw.loader.addSource( commonsWiki );&lt;br /&gt;
&lt;br /&gt;
        // Register Commons RL modules&lt;br /&gt;
        for (i = 0; i &amp;lt; modules.length; i++) {&lt;br /&gt;
            if (mw.loader.getState( modules[i][0] ) === null) {&lt;br /&gt;
                mw.loader.register([modules[i]]);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mw.loader.using( [ 'ext.gadget.editDropdown', 'mediawiki.util', 'mediawiki.Title' ], _install );&lt;br /&gt;
&lt;br /&gt;
}( jQuery, mediaWiki ) );&lt;br /&gt;
&lt;br /&gt;
/* DO NOT ADD CODE BELOW THIS LINE */&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	<entry>
		<id>http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js</id>
		<title>Участник:Kolbaska/common.js</title>
		<link rel="alternate" type="text/html" href="http://wiki.neverlands.ru/wiki/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Kolbaska/common.js"/>
				<updated>2025-11-14T03:53:50Z</updated>
		
		<summary type="html">&lt;p&gt;Kolbaska: Новая страница: «/**  * Keep code in MediaWiki:Common.js to a minimum as it is unconditionally  * loaded for all users on every wiki page. If possible create a gadget that is  * e…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Keep code in MediaWiki:Common.js to a minimum as it is unconditionally&lt;br /&gt;
 * loaded for all users on every wiki page. If possible create a gadget that is&lt;br /&gt;
 * enabled by default instead of adding it here (since gadgets are fully&lt;br /&gt;
 * optimized ResourceLoader modules with possibility to add dependencies etc.)&lt;br /&gt;
 *&lt;br /&gt;
 * Since Common.js isn't a gadget, there is no place to declare its&lt;br /&gt;
 * dependencies, so we have to lazy load them with mw.loader.using on demand and&lt;br /&gt;
 * then execute the rest in the callback. In most cases these dependencies will&lt;br /&gt;
 * be loaded (or loading) already and the callback will not be delayed. In case a&lt;br /&gt;
 * dependency hasn't arrived yet it'll make sure those are loaded before this.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/* global mw, $ */&lt;br /&gt;
/* jshint strict:false, browser:true */&lt;br /&gt;
&lt;br /&gt;
mw.loader.using( [ 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
	/* Begin of mw.loader.using callback */&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Map addPortletLink to mw.util&lt;br /&gt;
	 * @deprecated: Use mw.util.addPortletLink instead.&lt;br /&gt;
	 */&lt;br /&gt;
	mw.log.deprecate( window, 'addPortletLink', mw.util.addPortletLink, 'Use mw.util.addPortletLink instead' );&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
	 * @rev 6&lt;br /&gt;
	 */&lt;br /&gt;
	var extraCSS = mw.util.getParamValue( 'withCSS' ),&lt;br /&gt;
		extraJS = mw.util.getParamValue( 'withJS' );&lt;br /&gt;
&lt;br /&gt;
	if ( extraCSS ) {&lt;br /&gt;
		if ( extraCSS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.css$/ ) ) {&lt;br /&gt;
			mw.loader.load( '/w/index.php?title=' + extraCSS + '&amp;amp;action=raw&amp;amp;ctype=text/css', 'text/css' );&lt;br /&gt;
		} else {&lt;br /&gt;
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if ( extraJS ) {&lt;br /&gt;
		if ( extraJS.match( /^MediaWiki:[^&amp;amp;&amp;lt;&amp;gt;=%#]*\.js$/ ) ) {&lt;br /&gt;
			mw.loader.load( '/w/index.php?title=' + extraJS + '&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
		} else {&lt;br /&gt;
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Collapsible tables; reimplemented with mw-collapsible&lt;br /&gt;
	 * Styling is also in place to avoid FOUC&lt;br /&gt;
	 *&lt;br /&gt;
	 * Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].&lt;br /&gt;
	 * @version 3.0.0 (2018-05-20)&lt;br /&gt;
	 * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js&lt;br /&gt;
	 * @author [[User:R. Koot]]&lt;br /&gt;
	 * @author [[User:Krinkle]]&lt;br /&gt;
	 * @author [[User:TheDJ]]&lt;br /&gt;
	 * @deprecated Since MediaWiki 1.20: Use class=&amp;quot;mw-collapsible&amp;quot; instead which&lt;br /&gt;
	 * is supported in MediaWiki core. Shimmable since MediaWiki 1.32&lt;br /&gt;
	 *&lt;br /&gt;
	 * @param {jQuery} $content&lt;br /&gt;
	 */&lt;br /&gt;
	function makeCollapsibleMwCollapsible( $content ) {&lt;br /&gt;
		var $tables = $content&lt;br /&gt;
			.find( 'table.collapsible:not(.mw-collapsible)' )&lt;br /&gt;
			.addClass( 'mw-collapsible' );&lt;br /&gt;
&lt;br /&gt;
		$.each( $tables, function ( index, table ) {&lt;br /&gt;
			// mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');&lt;br /&gt;
			if ( $( table ).hasClass( 'collapsed' ) ) {&lt;br /&gt;
				$( table ).addClass( 'mw-collapsed' );&lt;br /&gt;
				// mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
		if ( $tables.length &amp;gt; 0 ) {&lt;br /&gt;
			mw.loader.using( 'jquery.makeCollapsible' ).then( function () {&lt;br /&gt;
				$tables.makeCollapsible();&lt;br /&gt;
			} );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	mw.hook( 'wikipage.content' ).add( makeCollapsibleMwCollapsible );&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Add support to mw-collapsible for autocollapse, innercollapse and outercollapse&lt;br /&gt;
	 *&lt;br /&gt;
	 * Maintainers: TheDJ&lt;br /&gt;
	 */&lt;br /&gt;
	function mwCollapsibleSetup( $collapsibleContent ) {&lt;br /&gt;
		var $element,&lt;br /&gt;
			$toggle,&lt;br /&gt;
			autoCollapseThreshold = 2;&lt;br /&gt;
		$.each( $collapsibleContent, function ( index, element ) {&lt;br /&gt;
			$element = $( element );&lt;br /&gt;
			if ( $element.hasClass( 'collapsible' ) ) {&lt;br /&gt;
				$element.find( 'tr:first &amp;gt; th:first' ).prepend( $element.find( 'tr:first &amp;gt; * &amp;gt; .mw-collapsible-toggle' ) );&lt;br /&gt;
			}&lt;br /&gt;
			if ( $collapsibleContent.length &amp;gt;= autoCollapseThreshold &amp;amp;&amp;amp; $element.hasClass( 'autocollapse' ) ) {&lt;br /&gt;
				$element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
			} else if ( $element.hasClass( 'innercollapse' ) ) {&lt;br /&gt;
				if ( $element.parents( '.outercollapse' ).length &amp;gt; 0 ) {&lt;br /&gt;
					$element.data( 'mw-collapsible' ).collapse();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// because of colored backgrounds, style the link in the text color&lt;br /&gt;
			// to ensure accessible contrast&lt;br /&gt;
			$toggle = $element.find( '.mw-collapsible-toggle' );&lt;br /&gt;
			if ( $toggle.length ) {&lt;br /&gt;
				// Make the toggle inherit text color (Updated for T333357 2023-04-29)&lt;br /&gt;
				if ( $toggle.parent()[ 0 ].style.color ) {&lt;br /&gt;
					$toggle.css( 'color', 'inherit' );&lt;br /&gt;
					$toggle.find( '.mw-collapsible-text' ).css( 'color', 'inherit' );&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	mw.hook( 'wikipage.collapsibleContent' ).add( mwCollapsibleSetup );&lt;br /&gt;
&lt;br /&gt;
	/* End of mw.loader.using callback */&lt;br /&gt;
} );&lt;br /&gt;
/* DO NOT ADD CODE BELOW THIS LINE */&lt;/div&gt;</summary>
		<author><name>Kolbaska</name></author>	</entry>

	</feed>