Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
  • Opera: Strg+F5
/// <nowiki>
// ==UserScript==
// @name        global
// @version     2017-09-17
// @namespace   file
// @include     https://de.wikipedia.org/*
// @include     https://de.m.wikipedia.org/*
// @include     https://de.wikisource.org/*
// @include     https://de.wikipedia.beta.wmflabs.org/*
// @grant       none
// @run-at      document-start
// ==/UserScript==


/* global window:false, navigator:false                                */
/* jshint forin:false,
          bitwise:true, curly:true, eqeqeq:true,
          futurehostile:true, latedef:true,
          laxbreak:true,
          nocomma:true, strict:true, undef:true, unused:true           */



if ( typeof(window.PerfektesChaos) !== "object" ) {
   window.PerfektesChaos  =  { };
}
if ( typeof(window.PerfektesChaos.bb) !== "object" ) {
   window.PerfektesChaos.bb  =  { };
}



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.mw  =  function (userObj, mw, jQuery, win) {
   // 2014-03-24
   "use strict";
   var MWlog        =  mw.log;
   userObj.mw_libs  =  mw.libs;



   mw.log  =  function (assign, apply, action, add) {
      // Popup message, if under development
      //    assign  -- debugging object
      //               >  .max     number of message boxes
      //               >  .say     identification of app
      //               >< .loud    false: silent
      //               >< .man     current message box count
      //    apply   -- message string
      //    action  -- level: 0=log 1=debug 2=info 3=warn 4=error
      //    add     -- additional object;  true: trace
      // Uses:
      //    Firebug support
      // 2014-08-26
      var opt   =  assign,
          show  =  apply,
          s, wc;
      if ( typeof(opt)  === "string"
           &&  typeof(show) !== "string") {
         show  =  opt;
         opt   =  true;
      }
      if (opt === true) {
         opt  =  { loud: true,
                   say:  ".log" };
      }
      if ( typeof(opt) === "object"  &&
           opt  &&
           typeof(opt.loud) !== "undefined"  &&
           opt.loud ) {
         if (typeof(opt.max) !== "number") {
            opt.max  =  20;
         }
         if (typeof(opt.man) !== "number") {
            opt.man  =  0;
         }
         if (typeof(opt.say) === "string") {
            s  =  opt.say + " ";
         } else {
            s  =  "";
         }
         wc  =  win.console;
         if (typeof(wc) === "object") {
            s  =  s + show;
            switch (action) {
            case 1 :
               if (typeof(wc.debug) !== "undefined") {
                  wc.debug(s);
                  break;
               }   // might fall through
            case 2 :
               if (typeof(wc.info) !== "undefined") {
                  wc.info(s);
                  break;
               }   // might fall through
            case 3 : //
               if (typeof(wc.warn) !== "undefined") {
                  wc.warn(s);
                  break;
               }   // might fall through
            case 4 : //
               if (typeof(wc.error) !== "undefined") {
                  wc.error(s);
                  break;
               }   // might fall through
            default : //
               if (typeof(wc.log) !== "undefined") {
                  wc.log(s);
               }   // might fall through
            }   // switch action
            if (add) {
               switch (typeof(add)) {
                  case "function" :
                  case "object" :
                     if (typeof(wc.dir) !== "undefined") {
                        wc.dir(add);
                        break;
                     }   // might fall through
                  case  "string": //
                     if (typeof(wc.debug) !== "undefined") {
                        wc.debug(add);
                        break;
                     }   // might fall through
                  default : //
                     if (typeof(wc.trace) !== "undefined") {
                        wc.trace();
                        break;
                     } else {
                        wc.log(add);
                     }
               }   // switch typeof(add)
            }
            if (action
                &&  ! opt.man
                &&  typeof(action) === "number"
                &&  action > 2
                &&  win.PerfektesChaos.g.client
                &&  win.PerfektesChaos.g.client.name === "firefox") {
               s = "Firebug console " + action + "\n" + s;
               win.alert(s);
               opt.man  =  -1;
            }
         } else {   // Fallback
            if (typeof(opt.man) !== "number") {
               opt.man  =  -1;
            }
            if (opt.man > opt.max) {
               opt.loud  =  false;
            } else {
               opt.man++;
               s  =  s + "   #" + opt.man;
               if (typeof(action) === "number") {
                  s  =  s + "     " + action;
               }
               if (typeof(show) !== "number") {
                  s  =  s + "\n" + show;
               }
               if ( ! win.confirm(s) ) {
                  opt.loud  =  false;
               }
            }
         }
      }   // opt.loud
   };   // mw.log()



   mw.log.deprecate  =  MWlog.deprecate;
   mw.log.warn       =  MWlog.warn;
};   // .bb.mw()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.fileFF  =  function (userObj, mw) {
   // 2015-03-05
   "use strict";
   var VSN = 0.2,
       w   = window,
       CORE;



   CORE  =  function ( apparent, mw ) {
      // Build basic file content load functions
      // Precondition:
      //    apparent  -- application object parent
      //    mw        -- MediaWiki software, or nil
      // 2015-03-05
      var LFC,
          fallback, fade, feedback, fetch, furnish;
      if ( typeof apparent.localFileContent  !==  "object" ) {
         apparent.localFileContent  =  { };
      }
      LFC            =  apparent.localFileContent;
      LFC.config     =  { msec:    5000,
                          missing: 50 };
      LFC.head       =  false;
      LFC.listened   =  false;
      LFC.listening  =  true;
      LFC.live       =  false;
      LFC.missing    =  LFC.config.missing;
      LFC.queries    =  false;
      LFC.requests   =  false;
      LFC.timer      =  false;
      LFC.vsn        =  VSN;



      fade  =  function ( access ) {
         // Add-on did not answer any more?
         // Precondition:
         //    access  -- resource specification
         //               >  .lack
         // Uses:
         //     < .live
         //     < .missing
         //    furnish()
         // 2015-03-05
         if ( access.lack ) {
            LFC.live     =  false;
            LFC.missing  =  0;
         }
         furnish();
      };   // fade()



      fallback  =  function ( access ) {
         // Local resource not available, use backup if defined
         // Precondition:
         //    access  -- resource specification
         //               >  .backup  string/Array: fallback capabiity
         //                           [0]        --  0: function
         //                                          1: mw.load URL
         //                                          2: mw.load module
         //                                          3: mw.implement
         //                           [1]        -- URL/module/function
         //                           [2]        -- mw.load URL: async
         //                           [2]...[4]  -- mw.implement
         //                           string means URL
         //               >  .scope   MIME
         //                < .lack    done
         // Uses:
         //    >  mw
         //    mw.loader.load()
         //    mw.loader.implement()
         // 2015-02-12
         var bak  =  access.backup,
             head, lead, scope;
         switch ( typeof bak ) {
            case "string" :
               bak  =  [ 1, bak ];
               break;
            case "object" :
               break;
            default:
               bak  =  false;
         }   // switch
         if ( bak ) {
            head  =  bak[ 0 ];
            if ( head ) {
               if ( typeof mw  ===  "object" ) {
                  switch ( head ) {
                     case 1:   // mw.load URL
                        switch ( access.scope  ) {
                           case "application/javascript" :
                              scope  =  "text/javascript";
                              break;
                           default:
                             scope  =  access.scope;
                        }   // switch access.scope
                        if ( typeof bak[ 2 ]  ===  "boolean" ) {
                           lead  =  bak[ 2 ];
                        } else {
                           lead  =  true;
                        }
                        mw.loader.load( bak[ 1 ], scope, lead );
                        break;
                     case 2:   // mw.load module
                        mw.loader.load( bak[ 1 ] );
                        break;
                     case 3:   // mw.implement
                        mw.loader.implement( bak[ 1 ],
                                             bak[ 2 ],
                                             bak[ 3 ],
                                             bak[ 4 ] );
                        break;
                  }   // switch access
               } else if ( head === 1 ) {
                  // Non-MW URL loading
               }
            } else {
               bak[ 1 ]( access );
            }
         }
         access.lack  =  false;
      };   // fallback()



      feedback  =  function ( /* event */ ) {
         // Add-on has sent an answer
         // Precondition:
         //    event  -- DOM event specification
         // Uses:
         //    this  -- DOM element attached to event
         //    >  .requests
         //    DOM.getAttribute()
         // 2015-03-05
         var dom = this,
             rq, scope, sign, stuff, success;
         if ( dom.getAttribute( "class" ) === "localfilecontent-get" ) {
            scope  =  dom.getAttribute( "type" );
            stuff  =  dom.getAttribute( "title" );
            sign   =  scope + " " + stuff;
            if ( typeof LFC.requests[ sign ]  ===  "object" ) {
               success  =  dom.getAttribute( "data-lucky" );
               if ( success ) {
                  rq        =  LFC.requests[ sign ];
                  rq.lack   =  false;
                  rq.load   =  false;
                  rq.lucky  =  ( success === "1" );
                  if ( rq.lucky ) {
                     rq.story  =  dom.getAttribute( "data-content" );
                  }
               }
            }
         }
      };   // feedback()



      fetch  =  function ( access ) {
         // Try to retrieve local string
         // Precondition:
         //    access  -- resource specification
         //               >  .scope    MIME
         //               >  .sign     key
         //               >  .backup   some fallback available
         //               >< .link     DOM <link />
         //                < .load     Add-on loading in process
         // Uses:
         //    >  w
         //    >  .config.msec
         //    >< .head
         //    >< .timer
         //     < .requests
         //    DOM.createElement()
         //    DOM.setAttribute()
         //    DOM.getElementsByTagName()
         //    DOM.appendChild()
         //    DOM.addEventListener()
         //    DOM.createEvent()
         //    DOM.initEvent()
         //    DOM.dispatchEvent()
         //    window.setTimeout()
         //    window.clearTimeout()
         //    (feedback)
         //    (fade)
         // 2015-03-05
         var elt, event;
         if ( typeof access.link  !==  "object"   &&   ! access.load ) {
            access.load  =  true;
            elt          =  w.document.createElement( "link" );
            elt.setAttribute( "class", "localfilecontent-get" );
            elt.setAttribute( "type",  access.scope );
            elt.setAttribute( "title", access.sign );
            if ( ! LFC.head ) {
               LFC.head  =  w.document.getElementsByTagName( "head" );
               LFC.head  =  LFC.head[ 0 ];
            }
            LFC.head.appendChild( elt );
            elt.addEventListener( "localfileContents", feedback, true );
            event  =  w.document.createEvent( "Events" );
            event.initEvent( "localfilecontent", true, false );
            //                                   bubbles, cancelable
            elt.dispatchEvent( event );
            if ( access.backup ) {
               if ( LFC.timer ) {
                  w.clearTimeout( LFC.timer );
               }
               LFC.timer  =  w.setTimeout( function () {
                                                          fade( access );
                                                       },
                                           LFC.config.msec );
            }
            access.link  =  elt;
         }
      };   // fetch()



      furnish  =  function () {
         // Add-on detection completed, load requests
         // Uses:
         //    >  .live
         //    >  .missing
         //    >< .queries
         //    >< .requests
         //     < .listened
         //    fetch()
         //    fallback()
         // 2015-03-05
         var i, n, request, sign;
         LFC.listened  =  true;
         if ( LFC.queries ) {
            n  =  LFC.queries.length;
            if ( n ) {
               for ( i = n - 1;  i >= 0;  i-- ) {
                  sign  =  LFC.queries[ i ];
                  if ( typeof LFC.requests[ sign ]  ===  "object" ) {
                     request  =  LFC.requests[ sign ];
                     if ( request.lack ) {
                        if ( LFC.live ) {
                           fetch( request );
                        } else if ( LFC.missing ) {
                           fallback( request );
                        }
                     } else {
                        LFC.queries.splice( i, 1 );
                     }
                  }
               }   // for i--
            } else {
               LFC.queries  =  false;
            }
         }
      };   // furnish()



      LFC.file  =  function ( accept, ask, assume ) {
         // Try to load resource from local environment, at least enqueue
         // Precondition:
         //    accept  -- MIME type, or MIME nick
         //    ask     -- package nick string
         //    assume  -- string or Array with fallback capabiity
         //               [0]        --  0: mw.load URL
         //                              1: mw.load module
         //                              2: mw.implement
         //               [1]        -- URL / moduleiD
         //               [2]        -- mw.load URL: async
         //               [2]...[4]  -- mw.implement
         //               string means URL
         // Uses:
         //    >  .listened
         //    >< .queries
         //    >< .requests
         //    furnish()
         // 2015-03-05
         var guess  =  { "css":  "text/css",
                         "js":   "application/javascript",
                         "json": "application/json",
                         "txt":  "text/plain" },
             longing, scope, sign;
         if ( typeof guess[ accept ]  ===  "string" ) {
            scope  =  guess[ accept ];
         } else {
            scope  =  accept;
         }
         sign  =  scope + " " + ask;
         if ( LFC.requests ) {
            longing  =  ( typeof LFC.requests[ sign ]  !==  "object" );
         } else {
            LFC.requests  =  { };
            longing       =  true;
         }
         if ( longing ) {
            LFC.requests[ sign ]  =  { scope:  scope,
                                       sign:   ask,
                                       backup: assume,
                                       lack:   true,
                                       load:   false };
            if ( typeof LFC.queries  !==  "object" ) {
               LFC.queries  =  [ ];
            }
            LFC.queries.push( sign );
         }
         if ( LFC.listened ) {
            furnish();
         }
      };   // LFC.file()



      LFC.first  =  function () {
         // Find add-on presence
         // Uses:
         //    >  w
         //    >  .config.missing
         //    >  .config.msec
         //    >< .jump
         //    >< .missing
         //     < .live
         //    furnish()
         //    window.setTimeout()
         //    (.first)
         // 2014-04-21
         var elts  =  w.document.getElementsByTagName( "meta" ),
             seek  =  "localfilecontentReady",
             elt, i, n;
         if ( elts ) {
            n  =  elts.length;
            if ( n ) {
               for ( i = 0;  i < n;  i++ ) {
                  elt  =  elts[ i ];
                  if ( elt.getAttribute( "name" ) === seek ) {
                     LFC.live  =  true;
                     break;
                  }
               }   // for i
            }
         }
         if ( ! LFC.live  &&  LFC.missing ) {
            if ( typeof LFC.jump  !==  "number" ) {
               LFC.jump  =  LFC.config.msec / LFC.config.missing;
            }
            w.setTimeout( LFC.first, LFC.jump );
            LFC.missing--;
         } else {
            furnish();
         }
      };   // .first()



      if ( typeof LFC.loaded  !==  "boolean" ) {
         LFC.loaded  =  true;
         LFC.first();
      }
   };   // CORE()




   if ( navigator.userAgent.indexOf( "Gecko/" ) >= 0   &&
        ( navigator.userAgent.indexOf( "OpenBSD amd64" ) >= 0  ||
          navigator.userAgent.indexOf( "WOW64" ) > 0 ) ) {
      CORE( userObj, mw );
   }
};   // .bb.fileFF()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.cnf  =  function (userObj, mw, jQuery, win) {
   // 2015-01-07
   "use strict";
   userObj.cnf        =  { script: "javascript" };
   userObj.debugging  =  { wg:     mw.config.get( "debug" ),
                           loud:   true,
                           max:    10,
                           man:    0,
                           say:    "~PC~" };
   if (typeof(userObj.g) !== "object") {
      userObj.g  =  { };
   }
   win.debugging      =  { loud: true,
                           say:  "##??? (PC) ???##" };



   userObj.g.first  =  function () {
      // Define available script locations (autorun)
      // Uses:
      //     < .g.*
      //     < .cnf.lightSpoof
      // 2014-07-05
      var env       =  mw.config.get( [ "skin",
                                        "wgAction",
                                        "wgDBname",
                                        "wgIsArticle",
                                        "wgNamespaceNumber",
                                        "wgPageName",
                                        "wgServer",
                                        "wgTitle" ] ),
          suffixes  =  ".css.js.lua.uue.";
      this.name         =  "User:PerfektesChaos";
      this.deWPwmf      =  "//de.wikipedia.org";
      this.deWPbeta     =  "//de.wikipedia.beta.wmflabs.org";
      this.action       =  env.wgAction;
      this.dbName       =  env.wgDBname;
      this.isArticle    =  env.wgIsArticle;
      this.nsN          =  env.wgNamespaceNumber;
      this.pageName     =  env.wgPageName;
      this.server       =  env.wgServer;
      this.skin         =  env.skin;
      this.title        =  env.wgTitle;
      this.isEditing    =  ! this.isArticle;
      this.isResource   =  false;
      if (this.isEditing) {
         this.isEditing  =  (this.action === "edit"  ||
                             this.action === "submit");
      }
      userObj.cnf.lightSpoof  =  true;
      if (this.isArticle || this.isEditing) {
         this.isResource  =  (this.nsN
                              &&   this.nsN % 2  ===  0
                              &&   this.nsN > 0);
         if (this.isResource) {
            this.isResource  =  this.title.lastIndexOf(".");
            if (this.isResource > 0) {
               this.isResource  =  this.title.substr(this.isResource)
                                             .toLowerCase();
               if (suffixes.indexOf(this.isResource + ".")  <  0) {
                  this.isResource  =  false;
               } else if (this.isResource === ".js") {
                  this.isResource  =  "javascript";
               } else {
                  this.isResource  =  this.isResource.substr(1);
               }
            } else {
               this.isResource  =  false;
            }
         }
      }
   };   // .g.first()
   userObj.g.first();



   userObj.flop  =  function (arg) {
      // Interprete arg
      // Postcondition:
      //    Return false if arg indicates 'undesirable'
      // 2012-02-14
      var r  =  arg;
      if (arg === null) {
         r  =  false;
      } else if (typeof(arg) === "string") {
         if (arg.substr(0, 1)  ===  "n"  ||
             arg === "0" ||
             arg === "-" ||
             arg === "null" ||
             arg === "false") {
            r  =  false;
         }
      }
      return r;
   };   // .flop()



   userObj.isEditPermitted  =  function () {
      // Is the current user permitted to edit the current page?
      // Postcondition:
      //    Return true iff no restriction detected
      // 2015-10-24
      var r     =  true,
          dont  =  mw.config.get("wgRestrictionEdit"),
          groups, i, j, m, n, ng, p, trsl;
      if (dont) {
         if (typeof(dont) === "object") {
            n  =  dont.length;
            if (n) {
               groups  =  mw.config.get("wgUserGroups");
               r  =  false;
               if (groups) {
                  ng  =  groups.length;
                  if (ng) {
                     trsl  =  { autoconfirmed:       "autoconfirmed",
                                editeditorprotected: "editor",
                                sysop:               "sysop" };
                     m     =  n;
                     for (i = 0;  i < n;  i++) {
                        p  =  trsl[ dont[i] ];
                        if (p) {
                           for (j = 0;  j < ng;  j++) {
                              if (p === groups[j]) {
                                 m--;
                                 break;   // for j
                              }
                           }   // for j
                        } else {   // may contain "" or null
                           m--;
                        }
                     }   // for i
                     r  =  (! m);
                  }
               }
            }
         }
      }
      return r;
   };   // .isEditPermitted()



   userObj.isNamespace  =  function (applicable) {
      // Is the current page in certain namespace?
      // Precondition:
      //    applicable  -- Array of namespace numbers
      // Postcondition:
      //    Return true iff current namespace in applicable list
      // Uses:
      //    this
      //    >  .g.nsN
      // 2013-01-11
      var r  =  false,
          i,
          n  =  applicable.length;
      for (i = 0;  i < n;  i++) {
         if (applicable[i] === this.g.nsN) {
            r  =  true;
            break;   // for i
         }
      }   // for i
      return r;
   };   // .isNamespace()



   userObj.isWiki  =  function ( allow ) {
      // Is this the current project?
      // Precondition:
      //    allow  -- "deWPwmf", "deWPbeta"
      // Postcondition:
      //    Return true iff current project
      // Uses:
      //    this
      //    >  .g.server
      // 2013-01-11
      return  ( this.g.server === this.g[ allow ] );
   };   // .isWiki()



   userObj.cnf.flat  =  function () {
      // Remove minordefault tic if not appropriate
      // Postcondition:
      //    Form tic removed/set for some conditions
      // Uses:
      //    this
      //    >  .g.nsN
      //    >  .g.isResource
      //    >< .cnf.form_Edit
      // 2012-11-11
      var low  =  true,
          s;
      if (typeof(this.form_Edit) !== "object") {
         this.form_Edit  =  win.document.getElementById("editform");
      }
      if (typeof(this.form_Edit) === "object"  &&
          this.form_Edit  &&
          typeof(this.form_Edit.wpMinoredit) === "object"  &&
          this.form_Edit.wpMinoredit) {   // section != new
         if (userObj.g.isResource  ||
             userObj.g.nsN % 2) {
            low  =  false;
         } else if (typeof(this.form_Edit.wpTextbox1) === "object"  &&
                    this.form_Edit.wpTextbox1) {
            s  =  this.form_Edit.wpTextbox1.value;
            if (s.indexOf(" (CE") > 0) {
               if (s.indexOf(" (CET)") > 0  ||
                   s.indexOf(" (CEST)") > 0) {
                  low  =  false;
               }
            }
         }
         this.form_Edit.wpMinoredit.checked  =  low;
      }   // form_Edit
   };   // .cnf.flat()



   userObj.cnf.filthy  =  function () {
      // Disable central notices
      // Uses:
      //    jQuery.cookie()
      // 2013-01-01
      if (! jQuery.cookie("centralnotice_default")) {
         jQuery.cookie("centralnotice_default",
                       "hide",
                       { expires: 365,
                         path:    "/" });
      }
      if (jQuery.cookie("clicktracking-session")) {
         jQuery.cookie("clicktracking-session", null);
      }
   };   // .cnf.filthy()



   userObj.fetch  =  function () {
      // Define current configuration depending on cookies
      // Uses:
      //    >  .local.storage
      //    >  .load.js
      //    >  .load.js.suffix
      //    >< .local.lock
      //    >< .load.base
      //     < .debugging.debug
      //     < .load.js.DISK
      //    jQuery.cookie()
      //    .flop()
      //    .load.server.fetch()
      // 2015-02-11
      var local    =  false,
          setting  =  "",
          got, p, re, script, sub;
      if ( this.g.client.name === "firefox"
           &&  typeof this.localFileContent  ===  "object" ) {
         mw.libs.localFileContent  =  this.localFileContent;
         local                     =  true;
      } else if (this.local.storage) {
         setting  =  win.localStorage.getItem("load.base");
         if ( ! setting) {
            setting  =  "";
         }
         this.local.lock  =  true;
      } else if ("|chrome|firefox".indexOf(this.g.client.name) > 0) {
         if (win.location.host.indexOf("de.wikipedia.org") > 0) {
            win.alert("DISK: local.path");
         } else {
            this.local.lock  =  true;
         }
      }
      if (this.debugging.debug) {
         this.debugging.debug  =  true;
      }
      this.load.server.fetch("en");
      this.load.server.fetch("de");
      this.load.server.fetch("test");
      this.load.server.fetch("mw");
      for (script in this.load.base) {
         p  =  this.load.base[script];
         if (typeof(p.js) === "object") {
            re   =  new RegExp("~" + script + "_([-a-z:0]+/?)~",  "");
            got  =  re.exec(setting);
            if (got) {
               sub       =  this.flop(got[1]);
               p.js.SET  =  sub;
            } else {
               sub  =  p.js.STD;
               if (sub  &&  p.js["file:/"]  &&  ! this.local.lock) {
                  sub  =  "file:/";
               }
            }
            if (sub) {
               if (p.js[sub]) {
                  sub  =  p.js[ sub ];
               } else {
                  sub  =  false;
               }
               if (sub === "file:/") {
                  sub  =  script;
               }
               switch (typeof(sub)) {
                  case "object" :
                     p.js.WEB  =  sub;
                     break;
                  case "boolean" :
                     if (! sub) {
                        break;
                     }
                     sub  =  script;   // fall through
                  case "string" : //
                     if (sub !== "*") {
                        if (sub === "0") {
                           sub  =  false;
                        } else if ( local  ||
                              typeof(this.local.storage) === "string" ) {
                           p.js.DISK  =  sub + ".js";
                           sub  =  "file:/";
                           if ( typeof p.js[ p.js.STD ] === "object" ) {
                              p.js.WEB  =  p.js[ p.js.STD ];
                           }
                        } else if (! this.local.lock) {
                           sub  =  "no local.path";
                           mw.log(this.debugging,
                                  ".fetch()  no local.path",
                                  3);
                        }
                     }
                     break;
                  default :
                     mw.log(this.debugging,
                            ".fetch()  Unknown: " + script
                                       + " " + sub,
                            3);
                     sub  =  "*Unknown*";
               }   // switch typeof(sub)
               if ( typeof p.js.WEB  ===  "object" ) {
                  got       =  p.js.WEB;
                  p.js.WEB  =  this.load.js[ got[0] ] + script;
                  if (got[1] !== "*") {
                     p.js.WEB  +=  "/" + got[1];
                  }
                  p.js.WEB  +=  this.load.js.suffix;
               } else {
                  p.js.WEB  =  false;
               }
            }
            p.js.USE  =  sub;
         }
      }   // script in base[]
   };   // .fetch()



};   // .bb.cnf()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.local  =  function (userObj, mw, jQuery, win) {
   // 2013-12-07
   "use strict";
   if (typeof(userObj.local) !== "object") {
      userObj.local  =  { };
   }



   function bbLoadFile( app, doc, $ ) {
      // Build basic file load functions
      // Precondition:
      //    app  -- application object
      //    doc  -- window.document, or nil
      //    $    -- jQuery, or nil
      // 2013-12-05
      var later  =  false;   // document ready



      function file( absolute, accept, asyncInhibit ) {
         // Load script if doc ready, or prepare statement
         // Precondition:
         //    absolute      -- (local) path
         //    accept        -- charset string, if any
         //    asyncInhibit  -- force synchronous loading
         // Postcondition:
         //    Return string, with HTML statement to be written
         //                   or SPC if already appended
         //                   or "" if nothing done
         // Uses:
         //    >  later
         //    >  doc
         //    $()
         // 2013-12-05
         var o,
             s  =  absolute.toLowerCase();
         if ( $ ) {
            if ( s.slice( -3 )  ===  ".js" ) {
               o  =  { "src":  "file:/" + absolute,
                       "type": "text/javascript"
                     };
               if ( accept ) {
                  o.charset  =  accept;
               }
               if ( !  ( later || asyncInhibit ) ) {
                  o.async  =  "async";
               }
               s  =  ( later ? "body" : "head" );
               $( s ).append(  $( "<script />",  o )  );
            } else if ( s.slice( -4 )  ===  ".css" ) {
               o  =  { "href": "file:/" + absolute,
                       "rel":  "stylesheet",
                       "type": "text/css"
                     };
               if ( accept ) {
                  o.charset  =  accept;
               }
               $( "head" ).append(  $( "<link />",  o )  );
            }
         } else if ( doc ) {   // jQuery not yet available; use DOM
            /*
            if ( s.slice( -3 )  ===  ".js" ) {
               e  =  doc.createElement( "script" );
               e.setAttribute( "type", "text/javascript" );
               e.setAttribute( "src",  "file:/" + absolute );
               if ( later ) {
                  doc.body.appendChild( e );
               } else {
                  doc.head.appendChild( e );
               }
            } else if ( s.slice( -4 )  ===  ".css" ) {
               e  =  doc.createElement( "link" );
               e.setAttribute( "rel",  "stylesheet" );
               e.setAttribute( "type", "text/css" );
               e.setAttribute( "href", "file:/" + absolute );
               doc.head.appendChild( e );
            }
            */
         }
      }   // file()



      app.files  =  function ( apply, access, accept ) {
         // Try to load resources from local environment
         // Precondition:
         //    apply   -- identifier string, or Array with identifiers
         //    access  -- string (optional), absolute file system base
         //    accept  -- charset string, if any
         // Uses:
         //    >  .storage
         //    >  .set
         //    file()
         //    $.isArray()
         // 2013-12-05
         var i,
             s      =  typeof apply,
             set,
             start;
         if ( typeof access  ===  "string" ) {
            start  =  access;
         } else if ( this.storage ) {
            start  =  this.storage;
         } else {
            start  =  "/";
         }
         if ( start.search( /\/$/ )  <  0 ) {
            start  =  start + "/";
         }
         if ( typeof accept  ===  "string" ) {
            set  =  accept;
         } else if ( this.set ) {
            set  =  this.set;
         } else {
            set  =  false;
         }
         if ( s === "string" ) {
            file( start + apply,  set );
         } else if ( s === "object" ) {
            if ( $.isArray( apply ) ) {
               for ( i = 0;  i < apply.length;  i++ ) {
                  s  =  apply[ i ];
                  if ( typeof s  ===  "string" ) {
                     file( start + s,  set );
                  }
               }   // for i
            }
         }
      };   // app.files()



      function finished() {
         // Completed document loading
         // Precondition:
         //    document ready
         // Uses:
         //     < later
         // 2013-12-05
         later  =  true;
      }   // finished()



      app.folder  =  function ( access ) {
         // Set base folder for ressources
         // Precondition:
         //    access  -- string with absolute file system path
         // Uses:
         //     < .storage
         // 2013-12-05
         if ( typeof access  ===  "string" ) {
            this.storage  =  access;
         }
      };   // app.folder()



      app.font  =  function ( accept ) {
         // Set default charset for ressources
         // Precondition:
         //    accept  -- string with charset
         // Uses:
         //     < .set
         // 2013-12-05
         if ( typeof accept  ===  "string" ) {
            this.set  =  accept;
         }
      };   // app.font()



      $( finished );   // document ready
      app.low  =  true;
   }   // bbLoadFile()



   if ( ! userObj.local.low ) {
      bbLoadFile( userObj.local, null, jQuery );
   }
   userObj.local.font( "iso-8859-1" );
   if ( ! userObj.local.storage) {
      if ( win.localStorage ) {
         userObj.local.folder( win.localStorage.getItem( "load.path" ) );
      }
   }
};   // .bb.local()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.load  =  function (userObj, mw, jQuery, win) {
   // 2013-12-07
   "use strict";
   if ( ! userObj.load ) {
      userObj.load  =  { };
   }
   userObj.load.ready   =  false;
   userObj.load.path    =  "/w/index.php?title=";
   userObj.load.scheme  =  win.location.protocol + "//";
   userObj.load.server  =  { };
   userObj.load.css     =  { path:   userObj.g.name + "/css/",
                             suffix: ".css&action=raw&ctype=text/css" };
   userObj.load.js      =  { path:   userObj.g.name + "/js/",
                             suffix: ".js&action=raw"
                                     + "&ctype=text/javascript" };



   userObj.load.css.fundamentals  =  function () {
      // Uses:
      //    .load.resources()
      // 2015-11-25
      var shared  =  "[[Benutzer:PerfektesChaos/css/shared.css]]";
      userObj.load.resources(shared);
   };   // .load.css.fundamentals()



   userObj.load.server.fetch  =  function (attempt) {
      // Precondition:
      //    attempt  -- "en", "de", "test", "mw"
      // Uses:
      //    >  .load.scheme
      //    >  .load.path
      //    >  .load.js.path
      //     < .load.server[]
      //     < .load.js
      // 2012-02-10
      var r;
      r  =  userObj.load.scheme;
      switch (attempt) {
         case "en" :
         case "de" :
         case "test" :
            r  =  r + attempt + ".wikipedia.org";
            break;
         case "mw" :
            r  =  r + "www.mediawiki.org";
            break;
      }   // switch s
      userObj.load.server[attempt]  =  r;
      userObj.load.js[attempt]      =  r + userObj.load.path
                                         + userObj.load.js.path;
      return r;
   };   // .load.server.fetch()



   userObj.load.furnish  =  function () {
      // Define available script locations (autorun)
      // Uses:
      //    this
      //     < .load.base
      // 2017-08-11
      var D;
      this.base  =  { "preferencesGadgetOptions":   {},
                      "autoBackup":                 {},
                      "booksourcesDirect":          {},
                      "browserStorageManager":      {},
                      "citoidWikitext":             {},
                      "clickDivertimento":          {},
                      "deleteShortpages":           {},
                      "editorContent":              {},
                      "editToolStrIns":             {},
                      "externalLinkProblem":        {},
                      "fileAdm":                    {},
                      "fragmentAnchors":            {},
                      "idResolver":                 {},
                      "importUtility":              {},
                      "isbnLib":                    {},
                      "jsonXMLutils":               {},
                      "jsVersionGrab":              {},
                      "keyboardMapper":             {},
                      "keyboardMapperConfig":       {},
                      "lightSpoof":                 {},
                      "lintHint":                   {},
                      "listPageOptions":            {},
                      "loadResourceFile":           {},
                      "localEdit":                  {},
                      "pageLinkHelper":             {},
                      "paneMarker":                 {},
                      "prettyPageHeading":          {},
                      "recentAuthors":              {},
                      "remindErrorMessages":        {},
                      "resultListSort":             {},
                      "signatureMissing":           {},
                      "superscriptMagnifier":       {},
                      "ToolboxAddItems":            {},
                      "userspaceLinks":             {},
                      "versionControl":             {},
                      "watchCategories":            {},
                      "wikiExport":                 {},
                      "WikiSyntaxTextMod":          {},
                      "wikEd":                      {},
                      "wikEdDiff":                  {} };
      D  =  this.base;
      D.autoBackup.js                  =  { "STD":    "en:r",
                                            "file:/": true,
                                            "en:r":   ["en",   "r"],
                                            "mw":     ["mw",   "r"] };
      D.browserStorageManager.js       =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.citoidWikitext.js              =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "d"] };
      D.clickDivertimento.js           =  { "STD":    "en:r",
                                            "file:/": true,
                                            "en:r":   ["en",   "r"],
                                            "en:d":   ["en",   "d"] };
      D.deleteShortpages.js            =  { "STD":    false,
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.editorContent.js               =  { "STD":    false,
                                            "file:/": true,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.editToolStrIns.js              =  { "STD":    "mw",
                                            "file:/": true,
                                            "mw":     ["mw",   "debug"],
                                            "test":   ["test", "d"] };
      D.externalLinkProblem.js         =  { "STD":    "en:d",
                                            "file:/": true,
                                            "en:d":   ["en", "d"],
                                            "en:r":   ["en", "r"] };
      D.fileAdm.js                     =  { "STD":    false,
                                            "file:/": true,
                                            "test":   ["test", "d"] };
      D.fragmentAnchors.js             =  { "STD":    "en:r",
                                            "file:/": true,
                                            "en:r":   ["en",   "r"] };
      D.idResolver.js                  =  { "STD":    "en:d",
                                            "file:/": true,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.importUtility.js               =  { "STD":    false,
                                            "file:/": true,
                                            "test":   ["test", "d"] };
      D.isbnLib.js                     =  { "STD":    "en:r",
                                            "file:/": true,
                                            "en:r":   ["en",   "r"] };
      D.jsonXMLutils.js                =  { "STD":    "en:r",
                                            "file:/": true,
                                            "en:r":   ["en",   "r"] };
      D.jsVersionGrab.js               =  { "STD":    "file:/",
                                            "file:/": true };
      D.keyboardMapper.js              =  { "STD":    "en:d",
                                            "file:/": true,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.keyboardMapperConfig.js        =  { "STD":    "en:d",
                                            "file:/": true,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.lightSpoof.js                  =  { "STD":    "de",
                                            "de":     ["de",   "*"] };
      D.lintHint.js                    =  { "STD":    "en:d",
                                            "file:/": true,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.listPageOptions.js             =  { "STD":    "en:d",
                                            "file:/": true,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.loadResourceFile.js            =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.localEdit.js                   =  { "STD":    false,
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.pageLinkHelper.js              =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.paneMarker.js                  =  { "STD":    "mw",
                                            "file:/":
                                                 "paneMarker/paneMarker",
                                            "mw":     ["mw",   "r"] };
      D.preferencesGadgetOptions.js    =  { "STD":    "en:d",
                                            "file:/": true,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.prettyPageHeading.js           =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.recentAuthors.js               =  { "STD":    "file:/",
                                            "file:/": true };
      D.remindErrorMessages.js         =  { "STD":    "en:r",
                                            "file:/": true,
                                            "en:r":   ["en",   "r"] };
      D.resultListSort.js              =  { "STD":    "mw",
                                            "file:/": true,
                                            "mw":     ["mw",   "r"] };
      D.superscriptMagnifier.js        =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.ToolboxAddItems.js             =  { "STD":    "en:x",
                                            "file:/": false,
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"],
                                            "en:x":   ["en",   "x"] };
      D.userspaceLinks.js              =  { "STD":    "file:/",
                                            "file:/": true,
                                            "mw":     ["mw",   "r"] };
      D.versionControl.js              =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "r"] };
      D.watchCategories.js             =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.wikiExport.js                  =  { "STD":    "en",
                                            "file:/": true,
                                            "en":     ["en",   "d"],
                                            "en:r":   ["en",   "r"] };
      D.WikiSyntaxTextMod.js           =  { "STD":    "en:d",
                                            "file:/": "WSTM",
                                            "en:d":   ["en",   "d"],
                                            "en:r":   ["en",   "r"],
                                            "de:r":   ["de",   "r"] };
      D.wikEd.js                       =  { "STD":    false,
                                            "en":     "*" };
      D.wikEdDiff.js                   =  { "STD":    false,
                                            "en":     "*" };
   };   // .load.furnish()
   userObj.load.furnish();



};   // .bb.load()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.js  =  function (userObj, mw, jQuery, win) {
   // 2014-03-11
   "use strict";



   userObj.load.js.feed  =  function ( add, acquire ) {
      // Load local file with dependencies
      // Precondition:
      //    add       -- identifier of main module
      //    acquire   -- Array of sub modules, each element
      //                 [ RL signature, local file name ]
      // Uses:
      //    >  .load.base
      //    >  .local.storage
      //    .load.js.feeder()
      //    .load.js.fun()
      //    mw.loader.using()
      //    mw.log()
      // 2014-02-01
      var deps, i, n, part, signature,
          reg  =  userObj.load.base[ add ];
      if ( reg && reg.js ) {
         if ( reg.js.DISK
              &&  userObj.local
              &&  typeof userObj.local.storage  === "string"
              &&  userObj.local.files
              &&  ! userObj.local.lock ) {
            n     =  acquire.length;
            deps  =  new Array( n );
            for ( i = 0;  i < n;  i++ ) {
               part       =  acquire[ i ];
               signature  =  part[ 0 ];
               deps[ i ]  =  signature;
               this.feeder( signature, part[ 1 ] );
            }   // for i
            mw.loader.using( deps,
                             function () {
                                userObj.load.js.fun( add );
                             } );
         } else {
            this.fun( add );
         }
      } else {
         mw.log( userObj.debugging,
                 ".load.js.feed()  unknown " + add,
                 3 );
      }
   };   // .load.js.feed()



   userObj.load.js.feeder  =  function ( assign, address ) {
      // Implement local file
      // Precondition:
      //    assign   -- RL signature
      //    address  -- local file name within local path
      // Uses:
      //    mw.loader.implement()
      //    .local.files()
      // 2015-11-12
      mw.loader.implement( assign,
                           function () {
                              userObj.local.files( address );
                           } );
   };   // .load.js.feeder()



   userObj.load.js.fun  =  function (add, append, access) {
      // Load current (cookie controlled) version of add
      // Precondition:
      //    add     -- identifier
      //    append  -- subpage
      //    access  -- distinction
      // Uses:
      //    >  .load.base
      //    >  .load.server
      //    >  .load.path
      //    >  .load.js
      //    >  .local.lock
      //    .load.js.lightSpoof()
      //    .local.files()
      //    mw.loader.using()
      //    mw.loader.load()
      // 2015-02-15
      var local    =  false,
          p        =  userObj.load.base[add],
          script   =  false,
          schnark  =  userObj.load.server.de + userObj.load.path
                      + "User:Schnark/js/",
          use      =  false;
      if (typeof(access) !== "string") {
         access  =  append;
      }
      switch (add) {
         case "Schnark:diff" :
            //[[Benutzer:Schnark/js/diff]]
            script  =  schnark + "diff";
            break;
         case "lightSpoof" :
            if (p.js.USE[0] === "de") {
               this.lightSpoof(schnark);
            }
            break;
         case "wikEd" :
            p  =  userObj.load.base[ add ];
            if (p.js.USE) {
               script  =  userObj.load.server.en + userObj.load.path
                          + "User:Cacycle/" + add;
            }
            break;
      }   // switch add
      if (script) {
         script  =  script + this.suffix;
      } else {
         if (p) {
            if (p.js) {
               if ( p.js.DISK ) {
                  if ( typeof mw.libs.localFileContent  ===  "object" ) {
                     mw.libs.localFileContent.file( "js",
                                                    add,
                                                    p.js.WEB );
                     script  =  false;
                     local   =  true;
                  } else if ( userObj.local
                              &&  userObj.local.files
                              &&  ! userObj.local.lock ) {
                     userObj.local.files( p.js.DISK );
                     local   =  true;
                  }
               }
               if ( ! local  &&  p.js.WEB ) {
                  script  =  p.js.WEB;
               }
            }
         } else {
            mw.log(userObj.debugging,
                   ".load.js.fun()  unknown " + add,
                   3);
         }
      }
      if (script) {
         if (use) {
            mw.loader.using( use,
                             function () {
                                       mw.loader.load(script,
                                                      "text/javascript");
                                         } );
         } else {
            mw.loader.load(script, "text/javascript");
         }
      }
   };   // .load.js.fun()



   userObj.load.js.autoBackup  =  function () {
      // Uses:
      //    .load.js.fun()
      // 2012-11-11
      if ( typeof mw.libs.autoBackup  !==  "object"   ||
           ! mw.libs.autoBackup ) {
         mw.libs.autoBackup  =  { };
      }
      mw.libs.autoBackup.debugging  =  { loud: true,
                                         say:  "autoBAK" };
      this.fun("autoBackup");
   };   // .load.js.autoBackup()



   userObj.load.js.editToolStrIns  =  function () {
      // Uses:
      //    .local.files()
      //    .load.js.fun()
      // 2013-12-07
      var storage  =  win.localStorage.getItem( "etsi.user" );
      if (typeof(mw.libs.editToolStrIns) !== "object") {
         mw.libs.editToolStrIns  =  { };
      }
      if ( storage ) {
         if ( ! mw.libs.editToolStrIns.user ) {
            userObj.local.files( storage, false, "utf-8" );
         }
      }
      mw.libs.editToolStrIns.debugging  =  { loud: true,
                                             man:  0,
                                             max:  20,
                                             say:  "etSI" };
      this.fun("editToolStrIns");
   };   // .load.js.editToolStrIns()



   userObj.load.js.fileAdm  =  function () {
      // Uses:
      //    .isNamespace()
      //    jQuery.cookie()
      //    .load.fun()
      // 2013-01-29
      var FA;
      if ( userObj.isNamespace( [ -1, 4, 6, 14, 100 ] ) ) {
         mw.libs.fileAdm  =  {  debugging: { loud: true }  };
         FA  =  mw.libs.fileAdm;
         FA.debugging.skin  =  jQuery.cookie("fileAdm_Skin");
         if (typeof(FA.debugging.skin) === "string") {
            if (FA.debugging.skin === userObj.g.skin) {
               FA.options  =  { "lessMini": false,
                                "multiWin": false };
               userObj.load.js.fun("fileAdm");
            } else {
               FA.debugging  =  false;
            }
         } else {
            FA.debugging  =  false;
         }
         if ( ! mw.libs.fileAdm.debugging ) {
            delete mw.libs.fileAdm;
         }
      }
   };   // .load.js.fileAdm()



   userObj.load.js.lightSpoof  =  function (access) {
      // 2012-10-05
      mw.loader.load("jquery.async");
      mw.loader.load(access + "highlight" + this.suffix,
                     "text/javascript");
      /// </nowiki>
      //[[Benutzer:Schnark/js/highlight]]
      jQuery(win.document).on( "loadWikiScript",
                         function (event, name) {
                            var s  =  "Benutzer:Schnark/js/highlight.js";
                            if (name === s) {
                               mw.loader.load(access + "antispoof"
                                              + userObj.load.js.suffix,
                                              "text/javascript");
                               //[[Benutzer:Schnark/js/antispoof]]
                            }
                         } );
      /// <nowiki>
   };   // .load.js.lightSpoof()



   userObj.load.js.listPageOptions  =  function () {
      // Uses:
      //    this
      //    .load.js.fun()
      // 2014-03-01
      var LPO, sub,
          s    = "listPageOptions";
      if ( typeof mw.libs[ s ]  !==  "object"   ||   ! mw.libs[ s ] ) {
         mw.libs[ s ]  =  { };
      }
      LPO         =  mw.libs[ s ];
      LPO.learnt  =  true;
      LPO.leyo    =  false;
      LPO.lower   =  false;
      LPO.hide    =  [ [ false, false, 0, "(Addbot|MorbZ-Bot)$"],
                       [ false, "([A-Z][a-z]+_)?Diskussion:", 2 ],
                       [ false, "Wikipedia:Import", 0 ],
                       [ false, "Wikipedia:(L%C3%B6schk|Spielwiese)", 2 ]
                     ];
      if ( typeof userObj.local  ===  "object"   &&
           typeof userObj.local.v  ===  "object" ) {
         sub  =  s + "_hide";
         if ( typeof userObj.local.v[ sub ]  ===  "object" ) {
            LPO.hide  =  LPO.hide.concat( userObj.local.v[ sub ] );
         }
         sub  =  s + "_show";
         if ( typeof userObj.local.v[ sub ]  ===  "object" ) {
            LPO.show  =  userObj.local.v[ sub ];
         }
      }
      this.fun( s );
   };   // .load.js.listPageOptions()



   userObj.load.js.watchCategories  =  function () {
      // Uses:
      //    this
      //    .isWiki()
      //    .load.js.fun()
      // 2014-03-11
      var WATCAT;
      if ( typeof mw.libs.watchCategories  !==  "object"  ||
           ! mw.libs.watchCategories ) {
         mw.libs.watchCategories  =  {  cats: [ ]  };
      }
      WATCAT  =  mw.libs.watchCategories;
      if ( typeof userObj.watchCategories_cats  ===  "object" ) {
         WATCAT.cats  =  userObj.watchCategories_cats;
      }
      if ( typeof WATCAT.cats  !==  "object" ) {
         WATCAT.cats  =  [ ];
      }
      WATCAT.cats.concat( [ { cat:  "Wikipedia:Modul_mit_Syntaxfehler",
                              text: "Modul mit Syntaxfehler" },
                            { cat:  "Wikipedia:Seite_mit_Skriptfehlern",
                              text: "Skriptfehler" }
                          ] );
/*
      if ( userObj.isWiki( "deWPwmf" ) ) {
      }
*/
      if ( userObj.isWiki( "deWPbeta" ) ) {
         WATCAT.cats.push( { before: "#mw-content-text",
                             cat:    "Wikipedia:Schnelllöschen",
                             text:   "Schnelllöschen",
                             title:  "Recentchanges" } );
      }
      this.fun( "watchCategories" );
   };   // .load.js.watchCategories()



   userObj.load.js.wstm  =  function () {
      // Uses:
      //    this
      //    >  .g.nsN
      //    >  .g.title
      //    .flop()
      //    .local.files()
      //    .load.js.fun()
      // 2017-06-20
      var val, WSTM;
      if ( ! mw.libs.WikiSyntaxTextMod) {
         mw.libs.WikiSyntaxTextMod  =  { };
      }
      WSTM  =  mw.libs.WikiSyntaxTextMod;
      if ( ! WSTM.config) {
         WSTM.config  =  { data:     { },
                           format:   { },
                           lang:     { },
                           load:     { },
                           page:     { },
                           warn:     { } };
      }
      WSTM.debugging  =  { loud:   true,
                           man:    0,
                           max:    20,
                           say:    "WSTM",
                           timer:  false };
      val  =  userObj.load.base.WikiSyntaxTextMod.js.USE;
      if (val === "file:/") {
         WSTM.debugging.site    =  "file:/";
         WSTM.debugging.prefix  =  "d";
      } else if (typeof(val) === "object") {
         WSTM.debugging.prefix  =  val[1];
         val  =  val[0];
         if (val.length <= 2) {
            val  =  "";
         }
         WSTM.debugging.site  =  val;
         val  =  true;
      } else {
         val  =  false;
      }
      if ( val  &&  userObj.g.nsN === 10   /*  &&
                    userObj.g.title.indexOf("/Doku") < 0 */ ) {
         val  =  false;
      }
      if (val) {
         WSTM.config.lang.accept  =  "de";
         WSTM.config.page     =
                { include: [ ":dewiki:Benutzer:PerfektesChaos/js/",
                             ":dewiki:Benutzer:PerfektesChaos/LocalEdit",
                             ":dewiki:Wikipedia:Spielwiese",
                             ":dewiki:Portal:",
                             "Vorlage:.+/(Doku|Wartung)",
                             ":commonswiki:Commons:",
                             ":.+:User:PerfektesChaos(/.+)?$",
                             ":.+:File:.*" ],
                  support: [ ":dewiki:Datei:",
                             ":dewiki:Hilfe:",
                             ":dewiki:Kategorie:",
                             ":dewiki:Wikipedia:",
                             ":commonswiki:Help:" ],
                  exclude: [ ":dewiki:Wikipedia:Administratoren/",
                             ":dewiki:Wikipedia:.+/Archiv/",
                             ":dewiki:Wikipedia:Fragen zur ",
                             ":dewiki:Wikipedia:Löschkandidaten/",
                             ":dewiki:Wikipedia:Meinungsbild",
                             ":dewiki:Wikipedia:Projekt",
                             ":dewiki:Wikipedia:Redaktion ",
                             ":dewiki:Wikipedia:.*Redundanz/",
                             ":dewiki:Wikipedia:WikiProjekt" ]
               };
         if (userObj.g.pageName === "Wikipedia:Spielwiese") {
            this.fun("ToolboxAddItems");
         }
         if ( typeof mw.libs.localFileContent  ===  "object"
              &&  jQuery.client.profile().name === "firefox" ) {
            mw.libs.localFileContent.file( "js", "WSTM_user" );
            val  =  false;
         } else {
            val  =  win.localStorage.getItem("wstm.udfPath");
            if (val) {
               userObj.local.files(val + ".user.js");
            }
         }
      } else {
         val  =  true;
      }
      if (val) {
         this.fun("WikiSyntaxTextMod");
      }
   };   // .load.js.wstm()



   userObj.load.markGroupMembers  =  function ( assign ) {
      // Establish group member marks
      // Precondition:
      //    assign  -- true: initialize
      // Uses:
      //    .isWiki()
      //    mw.loader.getState()
      //    mw.loader.implement()
      //    mw.loader.using()
      // 2014-03-15
      var lock, s, urls,
          stop       =  "tools.markGroupMembers",
          store      =  "markGroupMembers.css",
          signature  =  "user:PerfektesChaos.markGroupMembers";
      if ( userObj.isWiki( "deWPwmf" ) ) {
         if ( assign ) {
            lock  =  win.localStorage.getItem( stop );
            if ( lock ) {
               if ( ! /^\s*0\s*$/.test(lock) ) {
                  lock  =  false;
               }
            }
            if ( ! lock ) {
               store  =  win.sessionStorage.getItem( store );
               if ( store ) {
                  mw.util.addCSS( store );
                  lock  =  true;
               }
            }
            if ( ! lock ) {
               s     =  "//tools.wmflabs.org/ggu/?"
                        + "format=cssmarker&localuser=#user#&query="
                        + "sysop@dewiki@A|"
                        + "bureaucrat@dewiki@B|"
                        + "checkuser@dewiki@C|"
                        + "oversight@dewiki@O|"
                        + "steward@metawiki@S";
               urls  =  [ s.replace( /#user#/, "Benutzer" ),
                          s.replace( /#user#/, "Benutzerin" ) ];
               if ( ! mw.loader.getState( signature ) ) {
                  mw.loader.implement( signature,
                                       [ ],
                                       { url: { screen: urls } },
                                       { } );
               }
/*
               mw.loader.using( [ signature ],
                                userObj.load.markGroupMembers );
*/
            }
/*
         } else {
*/
         }
      }   // deWPwmf
   };   // .load.markGroupMembers()



};   // .bb.js()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.res  =  function (userObj, mw) {
   // Library/utility for resource loading
   // Uses:
   //    mw.util.wikiUrlencode()
   // 2015-10-24
   "use strict";
   var Env, Projects;



   function wikilink2URL(adjust, address, access) {
      // Retrieve the "title=" URL from a wikilink (MW 1.18)
      // Precondition:
      //    adjust   -- string with wikilink target (within brackets)
      //                leading ':' indicates foreign project
      //    address  -- string with wgServer server URL
      //    access   -- string with wgScript, or false
      // Postcondition:
      //    Returns string with URL
      //    RegExp was used.
      // Uses:
      //    >< Projects
      //     < Env
      //    mw.util.wikiUrlencode()
      // 2015-10-24 PerfektesChaos@de.wikipedia
      var local  =  true,
          start  =  false,
          s      =  adjust.replace( /^\s-+/,  "")
                          .replace( /\s-+$/,  "" ),
          i, script, sister, site, slang;
      if ( s.charCodeAt( 0 )  ===  58 ) {   // ':'
         i      =  s.indexOf( ":", 1 );
         s      =  s.substr( 1 );
         local  =  ( i < 1 );
      }
      if ( ! local ) {
         sister  =  s.substr( 0,  i - 1 ).toLowerCase();
         if ( ! Projects ) {
            Projects  =  { b:       "wikibooks",
                           n:       "wikinews",
                           q:       "wikiquote",
                           s:       "wikisource",
                           v:       "wikiversity",
                           voy:     "wikivoyage",
                           w:       "wikipedia",
                           wikt:    "wiktionary",
                           commons: "commons.mediawiki.org",
                           c:       "commons.mediawiki.org",
                           meta:    "meta.wikimedia.org",
                           m:       "meta.wikimedia.org",
                           mw:      "www.mediawiki.org" };
         }
         site  =  Projects[ sister ];
         if ( site ) {
            if ( site.indexOf( "." )  >  0 ) {
               start  =  site;
            } else {
               sister  =  site;
            }
            s  =  s.substr( i );
            if ( ! start ) {
               i  =  s.indexOf( ":", 2 );
               if ( i < 1 ) {   // forgotten; hopefully intended
                  slang  =  "en";
               } else {
                  slang  =  s.substr( 0, i ).toLowerCase();
                  s      =  s.substr( i + 1 );
               }   //
               start  =  slang + "." + sister + ".org";
            }   // start
            start  =  "//" + start + Env.wgScript;
         } else {
            local  =  true;
         }
      }   // ! local
      if ( local ) {
         if ( access ) {
            script  =  access;
         } else {
            script  =  Env.wgScript;
         }
         start  =  address + script;
      }
      return  start + "?title=" + mw.util.wikiUrlencode( s );
   }   // wikilink2URL



   function resourceLink2URL( attach, address, access, age /*,apply*/ ) {
      // Retrieve the URL of a resource from any kind of link
      // Precondition:
      //    attach   -- string with link to the resource
      //                * Wikilink enclosed in brackets [[...]]
      //                  foreign project possible when :abbreviated
      //                * Relative path URL (starting with /)
      //                  within the same domain
      //                * http/https URL
      //                Expected to be JS, but works also with CSS
      //    address  -- string with wgServer server URL
      //    access   -- string with wgScript, or false
      //    age      -- number: seconds of maxage in cache
      //                optional, to be used in links to wiki project
      //    apply    -- true/false: use load.php and debug
      //                Not supported yet by load.php
      // Postcondition:
      //    Returns array with two elements
      //                  [0] URL
      //                  [1] mode: 0=CSS, 1=JS, -1=unknown
      //    RegExp was used.
      // Uses:
      //     < Env
      //    wikilink2URL()
      // 2011-02-23 PerfektesChaos@de.wikipedia
      var r       =  [ attach, 1 ],
          s       =  attach.replace( /^\s-+/, "" )
                           .replace( /\s-+$/, "" ),
          splash  =  false,
          shift;
      if ( typeof age  ===  "number" ) {
         if ( age >= 0 ) {
            splash  =  "&bcache=1&maxage=" + Math.floor( age );
         }
      }
      if ( s.substr( 0, 2 )  ===  "[["   &&
           s.substr( -2, 2 )  ===  "]]" ) {   // Wikilink
         s  =  wikilink2URL( s.substr( 2,  s.length - 4 ),
                             address,
                             access);
         if ( s.substr( -4, 4 ).toLowerCase()  ===  ".css" ) {
            r[ 1 ]  =  0;
         }
         r[ 0 ]  =  s + "&action=raw&ctype=text/"
                      +     ( r[ 1 ]  ===  1   ?   "javascript"
                                               :   "css" )
                      +     ( splash ? splash : "" );
      } else if ( s.charCodeAt( 0 )  ===  47   ||   // '/'
                  s.indexOf( address )  ===  0 ) {
         if ( s.indexOf( Env.wgScript )  >=  0 ) {
            if ( s.indexOf( "ctype=text/" )  <  0 ) {   //not yet present
               shift  =  s.toLowerCase() + "&";
               if ( shift.indexOf( ".css&" )  >  0 ) {
                  r[ 1 ]  =  0;
               }
               s  =  s + "&ctype=text/"
                       +     ( r[ 1 ]  ===  1   ?   "javascript"
                                                :   "css" );
            }   // no ctype= yet
            if ( s.indexOf( "action=raw" )  <  0 ) {   // not yet present
               s  =  s + "&action=raw";
            }
            if ( splash ) {
               if ( s.indexOf("maxage=" )  <  0 ) {   // not yet present
                  s  =  s + splash;
               }
            }
         } else {   // load.php ??
            shift  =  s.toLowerCase() + "&";
            if ( shift.indexOf( ".css&" )  >  0 ) {
               r[ 1 ]  =  0;
            }
         }
         if ( s.charCodeAt( 0 )  ===  47 ) {   // '/'
            s  =  s + address;
         }   // relative path URL
         r[ 0 ]  =  s;
      } else {   // pass thru -- good luck
         r[ 1 ]  =  -1;
      }   // address type
      return r;
   }   // resourceLink2URL



   userObj.load.resources  =  function ( attach, age /* , apply */ ) {
      // Load some resources (JS or CSS) of a local project or domain
      // Precondition:
      //    attach  -- string with link to the resource
      //               * Wikilink (within local project only)
      //                          enclosed in brackets [[...]]
      //               * Relative path URL (starting with /)
      //                 within the same domain
      //               * http/https URL
      //    age     -- number: seconds of maxage in cache
      //               optional
      //    apply   -- true/false: use load.php and debug
      //               Not supported yet by load.php
      // Postcondition:
      //    Loading requested.
      //    Returns false if no failure detected
      //            else (last) erroneous data
      //    RegExp was used.
      // Uses:
      //     < Env
      //    resourceLink2URL()
      //    mw.config.get()
      //    mw.loader.load()
      // 2015-10-24 PerfektesChaos@de.wikipedia
      var r  =  attach,
          http, i, m, n, obtain, outcome, s, script;
      if ( ! Env ) {
         Env  =  mw.config.get( [ "wgScript",
                                  "wgServer" ] );
      }
      n        =  -1;
      obtain   =  typeof attach;
      outcome  =  [  [ ],  [ ]  ];
      s        =  false;
      if ( obtain === "string" ) {
         n       =  1;
         obtain  =  [ attach ];
      } else if ( obtain === "object" ) {
         obtain  =  attach;
         n       =  attach.length;
         s       =  Env.wgScript;
      }
      for ( i = 0;  i < n;  i++ ) {
         if ( typeof obtain[ i ]  ===  "string" ) {
            http  =  resourceLink2URL( obtain[ i ],
                                       Env.wgServer,
                                       s,
                                       age /*,
                                       apply */ );
            m     =  http[ 1 ];
            if ( m < 0 ) {   // out of space
               if ( !  mw.loader.load( http[ 0 ] ) ) {   // success?
                  r  =  http[ 0 ];
               }
            } else {
               outcome[ m ]  =  outcome[ m ].concat( http[ 0 ] );
            }
         }
      }   // for i
      // sort as two piles for possible packaging and minifying
      for ( m = 0;  m < 2;  m++ ) {
         script  =  "text/"
                    +   ( m === 1  ?  "javascript"  :  "css" );
         obtain  =  outcome[ m ];
         n       =  obtain.length;
         for ( i = 0;  i < n;  i++ ) {
            if ( !  mw.loader.load( obtain[ i ],  script ) ) {
               r  =  obtain[ i ];   // failure
            }
         }   // for i
      }   // for m
      return  r;
   };   // .load.resources()



};   // .bb.res()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.run  =  function (userObj, mw, jQuery, win) {
   // 2014-01-30
   "use strict";



   userObj.fire  =  function () {
      // Remark: Used as event handler -- 'this' is not userObj
      // 2012-06-08
      userObj.first();
   };   // .fire()



   userObj.first  =  function () {
      // Initialization (autorun)
      // Precondition:
      //    jQuery.client available
      // Uses:
      //    this
      //    >  .g.dbName
      //    >  .g.nsN
      //    >  .g.isArticle
      //    >  .g.title
      //    >  .g.dbName
      //    >< .g.isEditing
      //    >< .cnf.lightSpoof
      //     < mw.loader.store.enabled
      //     < .g.client
      //     < .local.lock
      //     < .g.isResource
      //     < .g.isDiffPossible
      //    mw.loader.store.clear()
      //    jQuery.client.profile()
      //    mw.libs.localFileContent()
      //    .load.css.fundamentals()
      //    mw.util.getParamValue()
      //    .fetch()
      //    .load.js.fun()
      //    .load.js.listPageOptions()
      //    .load.js.watchCategories()
      //    .load.js.externalLinkProblem()
      //    .isWiki()
      //    .load.js.autoBackup()
      //    .isNamespace()
      //    .isEditPermitted()
      //    .load.js.editToolStrIns()
      //    .load.js.wstm()
      //    .load.js.fileAdm()
      //    .load.markGroupMembers()
      //    .cnf.filthy()
      //    jQuery, mw, document
      // 2017-07-20
      var re, s, special;
      if ( jQuery.inArray( this.g.dbName,  [ "dewiki", "enwiki" ] )
           <  0 ) {
         mw.loader.store.clear();
         mw.loader.store.enabled = false;
      }
      this.g.client  =  jQuery.client.profile();
      if  (! this.g.client) {
         this.g.client  =  { };
      }
      this.local.lock  =  (this.g.client.layout !== "gecko"  &&
                           this.g.client !== "webkit");
      this.fetch();
      if ( typeof mw.libs.localFileContent  ===  "object" ) {
         mw.libs.localFileContent.file( "css", "usercommon" );
         s  =  "preferencesGadgetOptions";
         mw.loader.state( "ext.gadget." + s,  "loading" );
         mw.libs.localFileContent.file( "js",
                                        s,
                                        this.load.base[ s ].js.WEB );
      }
      userObj.load.css.fundamentals();
      mw.libs.autoBackup  =  { opt:  { portlet: true }
                             };
      switch (this.g.nsN) {
         case -1:
            special  =  mw.config.get("wgCanonicalSpecialPageName");
            switch (special) {
               case "Blankpage" :
               case "Gadgets" :
                  s  =  "preferencesGadgetOptions";
                  if ( ! mw.loader.getState("ext.gadget." + s) ) {
                     this.load.js.fun(s);
                  }
                  //                autoBackup
                  this.load.js.fun("browserStorageManager");
                  this.load.js.fun("citoidWikitext");
                  this.load.js.fun("clickDivertimento");
                  this.load.js.fun("externalLinkProblem");
                  this.load.js.fun("idResolver");
                  this.load.js.fun("keyboardMapper");
                  this.load.js.fun("keyboardMapperConfig");
                  this.load.js.fun("listPageOptions");
                  //        --      loadResourceFile
                  //                pageLinkHelper
                  this.load.js.fun("paneMarker");
                  this.load.js.fun("resultListSort");
                  //                userspaceLinks
                  //                watchCategories
                  //   .load.js.wstm();   // see below
                  break;
               case "Watchlist" :
               case "Recentchanges" :
                  this.load.js.fun("externalLinkProblem");
                  this.load.js.watchCategories();
               case "EditWatchlist" :
                  this.load.js.listPageOptions();
                  break;
            }
            this.load.js.fun("resultListSort");
            this.load.js.fun("userspaceLinks");
            break;
         case  0:
            if ( userObj.isWiki( "deWPwmf" ) ) {
               this.load.js.fun("ToolboxAddItems");
               if (this.g.dbName === "dewiki") {
                  this.load.js.fun("externalLinkProblem");
                  this.load.js.fun("idResolver");
               }
            }
            if (this.g.action === "edit") {
               this.load.js.fun("recentAuthors");
            }
            // fall through
         case  1:
            if (this.g.dbName === "dewiki") {
               this.load.js.fun("externalLinkProblem");
            }
            break;
         case  2:
            this.load.js.fun("localEdit");
            this.load.js.fun("userspaceLinks");
            break;
         case  3:
            this.load.js.fun("userspaceLinks");
            break;
         case  14:
            if (this.g.dbName === "dewiki") {
               this.load.js.fun("externalLinkProblem");
            }
            break;
      }
      if (this.g.nsN >= 0) {
         this.load.js.autoBackup();
         this.load.js.fun("remindErrorMessages");
      }
      this.load.js.fun("paneMarker");
      if ( userObj.isNamespace( [ -1, 4 ] ) ) {
         this.load.js.fun("importUtility");
      }
      if (this.g.nsN > 0) {
         this.load.js.fun("prettyPageHeading");
      }
      if (this.g.isArticle || this.g.isEditing) {
         if (this.g.isResource) {
            mw.config.set("wgCodeEditorCurrentLanguage",
                          this.g.isResource);
            this.load.js.fun("editorContent");
         } else if (this.g.nsN === 2) {
            if (this.g.title.indexOf("/Modul:") > 0) {
               this.g.isResource  =  "lua";
               mw.config.set("wgCodeEditorCurrentLanguage", "lua");
            }
         } else if (this.g.nsN === 10) {
            if (this.g.title.search(/\/XML$/) > 0) {
               this.g.isResource  =  "xml";
               mw.config.set("wgCodeEditorCurrentLanguage", "xml");
            }
         } else if (this.g.nsN === 828) {
            if (this.g.title.indexOf("/") < 0) {
               this.g.isResource  =  "lua";
            } else {
               switch (this.g.dbName) {
                  case "dewiki" :
                     re  =  /\/Doku$/;
                     break;
                  case "enwiki" :
                     re  =  /\/doc$/;
                     break;
               }
               if (re) {
                  if (! re.test(this.g.title)) {
                     this.g.isResource  =  "lua";
                  }
               } else {
                  this.g.isResource  =  "lua";
               }
            }
         }   // suppress JavaScript, CSS and Lua
         if (this.g.isEditing) {
            this.g.isEditing  =  this.isEditPermitted();
         }
      }   // view edit submit
      this.load.js.fun("clickDivertimento");
      if (this.cnf.lightSpoof) {
         if (this.g.isArticle || this.g.isEditing) {
            if (this.g.client.layout === "gecko") {
               if (this.g.isResource) {
                  this.cnf.lightSpoof  =  false;
               }   // suppress JavaScript and CSS
               if (this.cnf.lightSpoof) {
                  this.load.js.fun("lightSpoof");
               }
            }
         }
      }
      if (this.g.isEditing) {
         if ( ! this.g.isResource
              &&  "|chrome|firefox".indexOf(this.g.client.name) > 0 ) {
            win.wikEd                     =  {  config: { }  };
            win.wikEd.config.filePreview  =  false;
            this.load.base.wikEd.js       =  { STD: "en", USE: "*" };
            if (this.g.dbName !== "dewiki") {
//             this.load.js.fun("wikEd");
            }
         }
         this.load.js.editToolStrIns();
         this.load.js.fun("citoidWikitext");
         this.load.js.fun("keyboardMapper");
      } else {
         this.load.js.fun("fragmentAnchors");
      }
      this.g.isDiffPossible  =  this.g.isEditing;
      if ( ! this.g.isDiffPossible) {
         if (mw.util.getParamValue("diff")) {
            this.g.isDiffPossible  =  true;
         }
      }
      if (this.g.isDiffPossible
          &&  this.local  &&  ! this.local.lock) {
         mw.libs.wikEdDiff  =  false;
         this.load.js.fun("Schnark:diff");
      }
      if (this.g.nsN % 2  ===  0   ||   this.g.nsN === -1) {
         switch (this.g.nsN) {
            case -1:
               if (special !== "Blankpage") {
                  this.load.js.wstm  =  false;
               }
               break;
            case 2:
               if (this.g.title.substr(0,15) === "PerfektesChaos/") {
                  if (this.g.isResource === "javascript") {
                     this.load.js.fun("jsVersionGrab");
                     this.load.js.wstm  =  false;
                  }
               } else {
                  this.load.js.wstm  =  false;
               }
               break;
            case 4:
               this.load.js.fun("citoidWikitext");
               break;
            case 8:   // BETA
               if (this.g.isResource === "javascript") {
                  this.load.js.fun("jsVersionGrab");
               }
               break;
            case 10:
               this.load.js.fun("jsonXMLutils");
               this.load.js.fun("citoidWikitext");
               break;
            case 828:
               if (this.g.title.indexOf("/Doku") < 0) {
                  this.load.js.wstm  =  false;
               }
               break;
            default:
         }   // switch .g.nsN
         if (this.load.js.wstm   &&
             (this.g.isEditing  ||  this.g.nsN === -1)) {
            this.load.js.wstm();
         }
         if ( this.isNamespace( [ -1, 2, 4, 6, 14, 100 ] ) ) {
            this.load.js.fileAdm();
         }
      }
      if ( this.g.nsN % 2  ||  this.g.nsN === 4 ) {
         this.load.markGroupMembers( true );
      }
      mw.libs.pageLinkHelper  =  { forcerecursivelinkupdate: true,
                                   slangQQX:                 true };
      this.load.js.fun("pageLinkHelper");
      this.load.js.fun("superscriptMagnifier");
      this.load.js.fun("browserStorageManager");
      jQuery(win.document).ready(this.further);
      this.cnf.filthy();
   };   // .first()



   userObj.further  =  function () {
      // Do something after loading
      // Precondition:
      //    document load ready
      // Uses:
      //     < .load.ready
      //    .g.isEditing()
      //    .isWiki()
      //    .cnf.flat()
      // Remark: Used as event handler -- 'this' is not userObj
      // 2015-10-22
      userObj.load.ready  =  true;
      if ( userObj.g.isEditing ) {
         if ( userObj.g.nsN ) {   // talk, project etc.
            if ( userObj.g.action === "edit" ) {
               userObj.cnf.flat();
            }   // edit
         }   // wgNamespaceNumber
      }
   };   // .further()



   mw.loader.using( [ "mediawiki.util",
                      "jquery.async",
                      "jquery.client",
                      "jquery.cookie" ],
                    userObj.fire );
};   // .bb.run()



//-----------------------------------------------------------------------



window.PerfektesChaos.bb.common  =  function (userObj) {
   // 2015-10-24
   "use strict";
   var bbs, i, n, s;
   if ( ! window.PerfektesChaos.bb.loaded ) {
      window.PerfektesChaos.bb.loaded  =  true;
      bbs  =  [ "mw", "cnf", "fileFF", "local", "load", "js", "res",
                "run" ];
      n    =  bbs.length;
      for ( i = 0;  i < n;  i++ ) {
         s  =  bbs[ i ];
         if (userObj.bb[ s ]) {
            userObj.bb[ s ]( userObj,
                             window.mediaWiki,
                             window.jQuery,
                             window );
            delete userObj.bb[ s ];
         }
      }   // for i
   }
};   // .bb.common()
window.PerfektesChaos.bb.common(window.PerfektesChaos);



//-----------------------------------------------------------------------



// Emacs
// Local Variables:
// coding: utf-8-dos
// fill-column: 80
// End: