User:PerfektesChaos/js/WikiSyntaxTextMod/dH.js

/// PerfektesChaos/js/WikiSyntaxTextMod/dH.js /// 2020-02-05 PerfektesChaos@de.wikipedia // WikiSyntaxTextMod:  Wiki syntax: Analysis of link -- web and wiki /// Fingerprint: #0#0# /// @license: CC-by-sa/4.0 GPLv3 /// /* global mw:true, mediaWiki:false                                    */ /* jshint forin:false, bitwise:true, curly:true, eqeqeq:true, latedef:true, laxbreak:true, nocomma:true, strict:true, undef:true, unused:true          */

if ( typeof mediaWiki !==  "object" ) {   // disconnected mw =  { libs:   { WikiSyntaxTextMod:  { } },           log:    function  {"use strict";} }; } ( function ( mw ) {  "use strict";   var version  =  -7.23,       sign     =  "WikiSyntaxTextMod",       sub      =  "H",       rls, self, WSTM;   if ( typeof mw.loader  ===  "object" ) {      rls   =  { };      self  =  "user:PerfektesChaos/" + sign + "/" + sub;      rls[ self ] = "loading";      mw.loader.state( rls );   }   if ( typeof mw.libs[ sign ]  !==  "object" ) {   // isolated      mw.libs[ sign ]  =  { };   }   WSTM  =  mw.libs[ sign ];   if ( typeof WSTM.w  !==  "object" ) {      WSTM.w  =  { link: { }  };   }   if ( typeof WSTM.w.link  !==  "object" ) {      WSTM.w.link  =  { };   }   WSTM.w.link.vsn   =  version;   WSTM.w.link.self  =  self;   if ( typeof WSTM.bb  !==  "object" ) {      WSTM.bb  =  { };   }   if ( typeof WSTM.debugging  !==  "object" ) {      WSTM.debugging  =  { };   } } ( mw ) );

/* Requires: JavaScript 1.3 (String.charCodeAt String.fromCharCode String.replace) JavaScript 1.5 RegExp non-capturing parenthese */

//---

mw.libs.WikiSyntaxTextMod.bb.bbH =  function ( WSTM ) { // Building block and run environment support // 2012-05-18 PerfektesChaos@de.wikipedia "use strict"; if ( typeof WSTM.util !==  "object" ) { WSTM.util =  { }; }

if ( typeof WSTM.util.fiatObjects !==  "function" ) { WSTM.util.fiatObjects =  function ( adult, activate, assign ) { // Ensure existence of at least empty object // Precondition: //   adult     -- parent object //   activate  -- String with name of child object //   assign    -- optional object with initial definition //                if containing object components, //                they will be asserted as well // Postcondition: //   adult has been extended // Uses: //   .util.fiatObjects  -- recursive // 2012-05-18 PerfektesChaos@de.wikipedia var elt, obj, s;        if ( typeof adult[ activate ]  !==  "object" ) { adult[ activate ] =  ( assign  ?  assign  :  { } ); }        if ( assign ) { obj =  adult[ activate ]; for ( s in assign ) { elt =  assign[ s ]; if ( typeof elt ===  "object" ) { WSTM.util.fiatObjects( obj, s, elt ); }           }  //  for s in assign }     };   // .util.fiatObjects }

WSTM.util.fiatObjects( WSTM, "debugging",  { loud: false } );

};  // .bb.bbH mw.libs.WikiSyntaxTextMod.bb.bbH( mw.libs.WikiSyntaxTextMod ); delete mw.libs.WikiSyntaxTextMod.bb.bbH;

//---

mw.libs.WikiSyntaxTextMod.bb.link =  function (WSTM) { // Analysis of link -- web and wiki // Uses: //   .util.fiatObjects // 2012-11-11 PerfektesChaos@de.wikipedia "use strict"; WSTM.util.fiatObjects( WSTM, "w",                          { link:  { namespace: {  detect: {},                                                   write:  {}  },                                     projects:  { },                                     protocol:  { },                                     re:        { },                                     replace:   { },                                     web:       { },                                     wiki:      { }                                   }                         } ); var WLINK     =  WSTM.w.link, NAMESPACE =  WLINK.namespace; WLINK.maxTitle    =  200; WLINK.maxURL      =  150; WLINK.maxWikilink =  200; WLINK.nesting     =   50;

WLINK.fence =  function ( address, access, alone ) { // Detect termination of any link (URL or wiki) // Precondition: //   address  -- string with link and aftermath //   access   -- link type   0: unknown   1: URL   2: wikilink //   alone    -- true: detect target only   false: keep title // Postcondition: //   Returns false       entire string appears to be link target //           number > 0  index of termination before string end // Requires: JavaScript 1.3  charCodeAt // 2011-03-02 PerfektesChaos@de.wikipedia var r =  false, c,         i,          m,          s,          scheme; if ( address.length > 0 ) { m =  access; s =  address; if ( alone ) { if ( m === 0 ) { m =  2; i =  address.indexOf( "://" ); if ( i > 0 ) {  // URL if ( i < 6 ) { scheme =  address.substr( 0, i ); if ( scheme === "ftp" ||                          scheme === "http"  ||                          scheme === "https" ) { m =  1; }                 }               }            }   // determine link type i =  address.indexOf( ( m === 1  ? " " :  "|" ) );            if ( i > 0 ) { r =  i;               s  =  address.substr( 0, r ); }        }   // target only i =  s.indexOf( "\n" ); if ( i > 0 ) { r =  i;            s  =  s.substr(0, r); }        i  =  s.indexOf( "]" ); if ( i > 0 ) { r =  i;            s  =  s.substr( 0, r ); }        i  =  s.indexOf( "<" ); if ( i > 0 ) { c = s.charCodeAt( i + 1 ); if ( c === 47 ) {  // '/' c =  s.charCodeAt( i + 2 ); }           if ( c > 96  &&  c < 123 ) {   // 'a' ... 'z'              r  =  i;            } }     }   // content return r;   };   // .w.link.fence

WLINK.fenced =  function ( adjust, access, above, adhere ) { // Find '[' in WikiTom, analyze and process links // Precondition: //   adjust  -- WikiTom top element //   access  -- location object //              .i  position to start searching for "[" //              .k  sibling number //   above   -- top level //   adhere  -- true: freeze link targets // Uses: //   >< .w.link.nesting //   .o.WikiTom.find //   .w.link.fenced   -- recursive //   .adjust.focus //   mw.log //   .w.link.format // 2012-05-24 PerfektesChaos@de.wikipedia var lock =  adhere, open =  access, deep; do { open =  adjust.find( "[",                               open.i,                               open.k,                               true,                               false,                               false ); if ( open ) { deep =  open.child; if ( deep ) { if ( this.nesting > 0 ) { this.nesting--; this.fenced( deep.o, deep, false, lock ); open.i =  0; open.k++; this.nesting++; } else if ( ! this.nesting ) { mw.log( WSTM.debugging,                         ".w.link.fenced  nesting level exhausted  c="                          + open.i,                          2,                          adjust.focus( open.k ) ); open.i++; }           } else { open =  this.format( adjust, open, false, lock, false ); if ( open.target ) { lock =  true; }           }         }   // open } while ( open );  // do   };   // .w.link.fenced

WLINK.filter =  function (adjust, all) { // Remove undesired chars from wikilink and URL // Precondition: //   adjust  -- string with link target //   all     -- true: titled wikilink or File location // Postcondition: //   Returns  false   if nothing to do, //            string  adjusted identifier //   RegExp was used. // Uses: //   .str.trimL // Requires: JavaScript 1.3  fromCharCode // 2011-07-20 PerfektesChaos@de.wikipedia var scan =  WSTM.str.trimL(adjust, true), shy  =  String.fromCharCode(173), r,         re;   // &shy; if (scan.indexOf(shy) >= 0) { re =  new RegExp(shy, "g"); if (re.test(scan)) { scan =  adjust.replace(re, ""); }  // remove shy }  // shy if (scan.indexOf("&") >= 0) { if (scan.indexOf("&#x") >= 0) { re =  new RegExp("&#x(AD|2028);", "g");   // shy EOL if (re.test(scan)) { scan =  scan.replace(re, ""); }  // remove /*           if (scan.indexOf("&#x200") >= 0) { var got; re  =  new RegExp("&#x(200[ABC]);", "g"); got =  re.exec(scan); // 200A  8203  ZERO WIDTH SPACE // 200B  8204  ZERO WIDTH NON-JOINER // 200C  8205  ZERO WIDTH JOINER if (got !== null) { scan =  scan.replace(re,                             String.fromCharCode(parseInt(got[1], 16))); }  // replace }  // &#x200 }  // &#x if (all) { if (scan.indexOf(" ") >= 0) { re =  new RegExp(" ", "g"); if (re.test(scan)) { scan =  scan.replace(re, " "); }  // remove }  //           }   // titled wikilink or File location }  // &      r  =  (scan === adjust  ?  false  :  scan); return r;   };   // .w.link.filter

WLINK.fire =  function ( adjust, above, adhere, arg ) { // Format and process any internal and external link // Precondition: //   adjust  -- WikiTom top element //   above   -- top level //   adhere  -- true: freeze link targets in this context //   arg     -- template parameter // Postcondition: //   Nodes are modified where suitable. //   RegExp was used. // Uses: //   >< .w.link.re.head //   >< .w.link.web.re      //    >< .o.Wikilink.instance //   .w.link.fenced //   .w.link.web.free // Requires: JavaScript 1.5  RegExp non-capturing parenthese // 2012-05-18 PerfektesChaos@de.wikipedia if ( ! this.re.head ) { this.re.head =  new RegExp( "^( +)?"                                      + "(?:(\\[)" + "|"                                        + "((?:(?:ht|f)tps?:)?//))",                                      "i"); this.web.re  =  new RegExp( "((^|[^:])" + "(\\b(?:https?|ftp):)?)//",                                     "i"); }     if ( ! WSTM.o.Wikilink.instance ) { WSTM.o.Wikilink.instance =  new WSTM.o.Wikilink; }     this.fenced( adjust,                   { i: 0,  k: 0 },                   above,                   adhere );   // '[' this.web.free( adjust,                    { i: 0,  k: 0 },                     true,                     adhere,                     arg );   // "http://" };  // .w.link.fire

WLINK.format =  function (adjust, about, above, adhere) { // Format found '[' in WikiTom, analyze and process link // Precondition: //   adjust  -- WikiTom element //   about   -- location object //              .i   string position of beginning "[" //              .k   sibling number of adjust //   above   -- top level //   adhere  -- true: freeze link targets // Postcondition: //   Returns array with start location for next search //           .i       string position of termination //           .k       sibling number of termination //           .target  WikiTom, if category or interwiki // Uses: //   >  .o.Wikilink.instance //   >  .w.link.re.head //   >  .w.link.maxWikilink //   >  .w.link.maxTitle //   >  .o.Wikilink.ModeIw //   >  .o.Wikilink.ModeFile //   >  .o.WikiTom.LinkFile //   >  .o.Wikilink.ModeCat //   >  .o.WikiTom.LinkCategory //   >  .o.WikiTom.Sortkey //   >  .o.WikiTom.LinkInterWiki //   >  .o.WikiTom.LinkWiki //    < .o.WikiTom.mode //    < .o.WikiTom.lookup //   .o.WikiTom.fetch //   .o.WikiTom.focus //   .o.WikiTom.flip //   .errors.found //   .o.wikilink:: //         .set //         .getChange //         .getError //         .getUserModified //         .getType //         .getTargetLength //         .getIncrement //   .o.WikiTom.folder // 2018-11-25 PerfektesChaos@de.wikipedia var j     =  about.i,          m      =  1, mode  =  0, obj   =  new WSTM.o.Weblink, r     =  { i: j + 1,  k: about.k }, wlink =  WSTM.o.Wikilink.instance, got, i,         n,          s;      if (adjust.fetch(r.k, r.i, true)  ===  91) {   // '[' mode =  10;   // "[["      } else {         s  =  adjust.fetch(r.k, r.i, false);         if (s) {            got  =  this.re.head.exec(s);            if (got) {               if (! got.index) {   // ^ matches multiline                  if (got[1]) {   // bad format: spaces between brackets                     j  +=  got[1].length;                  }                  if (got[2]) {                     mode  =  11;   // "[ [target"                  } else {                     mode  =  20;   // "[//"   or   "[https://" etc.                  }               }            } else {               got  =  /^([^\]\[|\n]+)([^\]\[\n]+)?\](.)/.exec(s);               if (got) {                  if (! got.index) {   // ^ matches multiline                     if (got[3] === "]") {                        if (got[1].length < this.maxWikilink) {                           mode  =  12;   // bad: second bracket missing                           if (got[2]) {                              if (got[2].length > this.maxTitle) {                                 mode  =  0;                              } else {                                 j--;                              }                           }                        }                     }                  }               }            }         }      }      switch (mode) {         case 10 :         case 11 :         case 12 :            wlink.set(adjust,                      { i: j,  k: r.k,  lack: (mode===12) },                      adhere);            if (wlink.getChange) {               n  =  wlink.getRemoveFrom;               s  =  wlink.getTextReplace;               adjust.flip(r.k,                           j + n,                           wlink.getRemoveTo - n,                           s);               if (wlink.getBracketShift) {                  j++;               }               if (wlink.getError  ||  wlink.getUserModified) {                  WSTM.mod.lazy  =  false;               }            }            if (adjust.parent) {               if (wlink.getType === WSTM.o.Wikilink.ModeIw                   &&  ! above) {                  s  =  adjust.fetch(r.k, j, false);                  WSTM.errors.found("wikilinkInterLangDeep",                                    false,                                    s.substr(0, 50));                  mode  =  0;               }   // interwiki            }            if (adhere) {               n  =  wlink.getTargetLength;               if (n) {                  j    +=  2;                  got   =  adjust.folder(j,  r.k,  j + n,  r.k);                  if (got) {                     got.lookup  =  false;                     switch (wlink.getType) {                        case WSTM.o.Wikilink.ModeFile :                           got.mode  =  WSTM.o.WikiTom.LinkFile;                           break;                        case WSTM.o.Wikilink.ModeCat :                           got.mode    =  WSTM.o.WikiTom.LinkCategory;                           got.leader  =  wlink.getLeader;                           r.target    =  got;                           n           =  wlink.getSortkey;                           if (n) {                              r.k++;                              got         =  adjust.folder(0,                                                           r.k + 1,                                                           n + 1,                                                           r.k + 1);                              got.mode    =  WSTM.o.WikiTom.Sortkey;                              got.lookup  =  false;                           }                           break;                        case WSTM.o.Wikilink.ModeIw :                           got.mode    =  WSTM.o.WikiTom.LinkInterWiki;                           got.leader  =  wlink.getLeader;                           r.target    =  got;                           break;                        default:                           got.mode  =  WSTM.o.WikiTom.LinkWiki;                           break;                     }   // switch wlink.mode                     r.k  +=  2;                     j     =  0;                     m     =  0;                  } else {                     m  =  wlink.getIncrement;                  }               }            } else {               m  =  2;            }            if (mode > 10) {               n  =  50;               if (r.k > 2) {                  s  =  adjust.fetch( r.k-2, 0, false ) +                        adjust.fetch( r.k-1, 0, false );                  i  =  s.lastIndexOf("|");                  if  (i >= 0) {                     s  =  s.substr(i+1);                  }                  i  =  s.lastIndexOf("[[");                  if  (i >= 0) {                     s  =  s.substr(i+2);                  }                  if (s.lastIndexOf("]") < s.lastIndexOf("[")) {                     n  =  0;                  }               }               if (n) {                  s  =  adjust.fetch(r.k, j, false);                  WSTM.errors.found("wikilinkBracketsAhead",                                    false,                                    s.substr(0, n));               }            }            break;         case 20 :            r  =  obj.format(adjust,                             { i: j,  j: 0,  k: r.k },                             1,                             false);            if (adhere) {               r  =  obj.freeze(r);            }            break;      }   // switch mode      if (mode !== 20) {         r.i  =  j + m;      }      return  r;   };   // .w.link.format

WLINK.linked =  function (about) { // Check whether WikiTom is some link target // Precondition: //   about  -- WikiTom element // Postcondition: //   Returns true if about is wikilink // Uses: //   >  .o.WikiTom.mode //   >  .o.WikiTom.LinkWiki //   >  .o.WikiTom.LinkWeb // 2012-04-22 PerfektesChaos@de.wikipedia return (about.mode >= WSTM.o.WikiTom.LinkWiki  &&               about.mode <= WSTM.o.WikiTom.LinkWeb); };  // .w.link.linked

NAMESPACE.collection =  {  "4": "Project", "8": "MediaWiki", "12": "Help" };  // .w.link.namespace.collection    2012-10-19 NAMESPACE.nsMedia    =    -2; NAMESPACE.nsSpecial  =    -1; NAMESPACE.nsUser     =     2; NAMESPACE.nsFile     =     6; NAMESPACE.nsTemplate =    10; NAMESPACE.nsCategory =    14; NAMESPACE.collection[NAMESPACE.nsMedia]    =  "Media"; NAMESPACE.collection[NAMESPACE.nsSpecial]  =  "Special"; NAMESPACE.collection[NAMESPACE.nsUser]     =  "User"; NAMESPACE.collection[NAMESPACE.nsFile]     =  "File"; NAMESPACE.collection[NAMESPACE.nsTemplate] =  "Template"; NAMESPACE.collection[NAMESPACE.nsCategory] =  "Category"; NAMESPACE.pagesSpecial                     =  [ // .w.link.namespace.pagesSpecial   2013-11-27 "AbuseFilter", "AbuseLog", "AncientPages", "ArticleFeedback", "AutoLogin", "Blankpage", "Block", "BlockList", "Blockme", "Book", "BookSources", "BrokenRedirects", "Categories", "CategoryTree", "Cite", "ComparePages", "Contributions", "DeadendPages", "Disambiguations",  // Pages linking to disambiguation pages "DoubleRedirects", "EditWatchlist", "EmailUser", "ExpandTemplates", // "Export",  // mul "FewestRevisions", "FileDuplicateSearch", "Filepath", "Gadgets", "GlobalUsage", "Hieroglyphs", "Import", "Interwiki", "LinkSearch", "ListAdmins", "ListBots", "ListFiles", "ListGrouprights", "ListRedirects", "ListUsers", "Log", "LonelyPages", "LongPages", "Massmessage", "MergeAccount", "MergeHistory", "MIMEsearch", "MobileFeedback", "MobileOptions", "MostUsedTemplates", "Movepage", "MyContributions", "MyPage", "MyTalk", "MyUploads", "NewImages", "NewPages", "Notifications", "Nuke", "Oversight", "PagesWithProp", "PasswordReset", "PermanentLink", "PrefSwitch", "Preferences", "Prefixindex", "ProtectedPages", "ProtectedTitles", "RandomPage", "RandomRedirect", "RecentChanges", "RecentChangeslinked", "RemoveGlobalBlock", "Renameuser", "RevisionDelete", "Search", "SecurePoll", "SiteMatrix", "SpecialPages", "Tags", "Unblock", "UncategorizedCategories", "UncategorizedFiles", "UncategorizedPages", "UncategorizedTemplates", "UnusedCategories", "UnusedFiles", "UnusedTemplates", "Upload", "UploadStash", "UserLogin", "UserLogout", "UserRights", // "Version",  // mul "WantedCategories", "WantedFiles", "WantedPages", "WantedTemplates", "Watchlist", "Whatlinkshere", "WithoutInterwiki" ];

WLINK.namespace.factory =  function (apply, achieve) { // Initialize namespace keyword translation // Precondition: //   apply    -- 0: read/write,  -1: read,  1: write //   achieve  -- false: any;  or string with ID (read only) // Uses: //   >  .w.link.namespace.collection //   >  .lang.translate.read //   >  .lang.translate.d      //    >  .lang.translate.write //   >< .w.link.namespace.detect //   >< .w.link.namespace.write //   .lang.translate.feed // 2013-03-15 PerfektesChaos@de.wikipedia var i,         n,          seek, scan, space, target, trsl; if (apply <= 0) { scan   =  ""; target =  (achieve ? achieve : WSTM.lang.translate.read); for (space in this.collection) { seek =  this.collection[space]; scan =  scan + "#" + space + "|"; scan =  WSTM.lang.translate.feed(scan,                                              seek + ":",                                              seek,                                              target,                                              false); if (seek === "File") { scan =  WSTM.lang.translate.feed(scan,                                                 "Image:",                                                 "Image",                                                 target,                                                 false); }        }   // for space in .collection this.detect[ (achieve ? achieve : "*") ] =  scan.toLowerCase; }  // read if (apply >= 0) { target =  { }; n      =  WSTM.lang.translate.write.length; for (space in this.collection) { seek =  this.collection[space]; trsl =  WSTM.lang.translate.d[ seek + ":" ]; if (trsl) { for (i = 0; i < n;  i++) { scan =  trsl[ WSTM.lang.translate.write[i] ]; if ( scan ) { if ( typeof scan ===  "object" ) { scan =  scan[0]; }                    switch ( typeof scan ) { case "object" : scan =  WSTM.lang.translate.fiat(scan); break; case "boolean" : scan =  seek; break; }  // switch typeof scan target[ seek ] =  scan; break;  // for i                  } }  // for i            }   // translation possible }  // for space in .collection this.write[ "*" ] =  target; }  // write };  // .w.link.namespace.factory

WLINK.namespace.feed =  function (assigned, avoid, array) { // Populate Array with additional translation items // Precondition: //   assigned  -- unit with namespace translations, or empty //   avoid     -- generic item, not to be collected //   array     -- Array to be extended (by push) // Postcondition: //   Returns  modified array // Uses: //   .lang.translate.fiat //   .util.isElement // 2012-09-22 PerfektesChaos@de.wikipedia var r =  array, e,         i,          n,          s;      if ( assigned ) { if ( typeof assigned ===  "object" ) { e =  assigned; n =  e.length; } else { e =  [ assigned ]; n =  1; }        for (i = 0;  i < n;  i++) { s =  e[i]; if (s) { s =  WSTM.lang.translate.fiat(s); if (s !== avoid) { if (! WSTM.util.isElement(r, s)) { r.push(s); }              }            }         }   // for i      } return r;   };   // .w.link.namespace.feed

WLINK.namespace.females =  function (ask) { // Preserve gender variant of user namespace keyword // Precondition: //   ask  -- user namespace keyword (downcased) //   Not in external link nor export context. // Postcondition: //   Returns  code   .nsUser  or  decimal variant // Uses: //   >  .link.namespace.sUser //   >  .lang.translate.d      //    >  .g.wDBname //   >  .g.projLang //   >  .link.namespace.nsUser //   >< .link.namespace.sUserL //   >< .link.namespace.users //   >< .link.namespace.collection //   .w.link.namespace.feed //   .str.fromNum // 2012-09-22 PerfektesChaos@de.wikipedia var r =  this.nsUser, i,         n,          q;      if (! this.sUserL) { this.sUserL =  true; this.sUser  =  this.write["*"]; if (this.sUser) { this.sUser =  this.sUser.User; if (this.sUser) { this.sUserL =  this.sUser.toLowerCase; }        }      }      if (ask !== this.sUserL) { if (! this.users) { this.users =  [ ]; q          =  WSTM.lang.translate.d["User:"]; if (q) { this.users =  this.feed(q[WSTM.g.wDBname],                                        this.sUser,                                        this.users); this.users =  this.feed(q[WSTM.g.projLang],                                        this.sUser,                                        this.users); }           n  =  this.users.length; for (i = 0; i < n;  i++) { q =  this.nsUser   +   0.1  *  (i + 1); q =  WSTM.str.fromNum(q); this.collection[ q ] =  this.users[i]; }  // for i         } for (q in this.collection) { if (this.collection[q].toLowerCase === ask) { r =  parseFloat(q, 10); break;  // for q            } }  // for q in .collection }     return  r;   };   // .w.link.namespace.females

WLINK.namespace.fetch =  function (assigned, abroad, about) { // Retrieve assigned appropriate namespace keyword // Precondition: //   assigned  -- keyword code (number) //   abroad    -- project identifier, if any;  or false (local) //   about     -- page name, if present // Postcondition: //   Returns  adjcent keyword,  or  English // Uses: //   >  .w.link.namespace.collection //   >  .w.link.namespace.write //   .w.link.namespace.find // 2012-10-01 PerfektesChaos@de.wikipedia var r     =  false, space =  this.collection[assigned], w;     if (space) { if (assigned === this.nsSpecial) { r =  (this.find(about)  ?  "Special"  :  false); }        if (! r) { if (! abroad) { w =  this.write["*"]; if (w) { r =  w[space]; }           }            if (! r) { r =  space; }        }      }      return  r;   };   // .w.link.namespace.fetch

WLINK.namespace.find =  function (ask) { // Find canonical special page name // Precondition: //   ask  -- page title, might start with standard keyword // Postcondition: //   Returns modified ask, if canonical; or false // Uses: //   >  .w.link.namespace.pagesSpecial //   >< .w.link.namespace.reSpecial // 2012-11-06 PerfektesChaos@de.wikipedia var r =  false, s =  ask, i,         j,          n;      if (s) { if (! this.reSpecial) { this.reSpecial =  new RegExp("^([^/#]+)[/#]", ""); }        j  =  this.reSpecial.exec(s); if (j) { j =  j[1].length; s =  ask.substr(0, j); }        s  =  s.toLowerCase; n =  this.pagesSpecial.length; if (n) {  // .length is available for (i = 0; i < n;  i++) { if (this.pagesSpecial[i].toLowerCase === s) { r =  this.pagesSpecial[i]; if (j) { r =  r + ask.substr(j); }                 break;   // for i               } }  // for i         } }     return  r;   };   // .w.link.namespace.find

WLINK.namespace.furnish =  function (ahead, abroad, adjacent) { // Retrieve keyword code if "File" or "Category" or localized // Precondition: //   ahead     -- string  keyword only, no ":" //   abroad    -- string  other language, or false //   adjacent  -- string  other project, or false // Postcondition: //   Returns  code   .nsFile .nsCategory etc.      //             false, if not detected // Uses: //   >  .w.link.namespace.detect //   >  .w.link.namespace.nsUser //   >  .w.lang.write //   >  .w.link.namespace.nsMedia //   >  .w.link.namespace.nsSpecial //   >  .w.link.namespace.nsFile //   >  .w.link.namespace.nsTemplate //   >  .w.link.namespace.nsCategory //   .str.trimL //   .w.link.namespace.factory //   .w.link.namespace.females // 2019-08-01 PerfektesChaos@de.wikipedia var r     =  false, scope =  "*", story =  WSTM.str.trimL(ahead.toLowerCase, true), got, re; if (abroad) { if (! this.detect[abroad]) { this.factory(-1, abroad); }        scope  =  abroad; }     scope  =  this.detect[scope]; if (scope) { if (scope.indexOf("|" + story + "|") >  0) { re  =  "#(-?[0-9]+)\\|([^#]+\\|)*" + story + "\\|"; re  =  new RegExp(re, ""); got =  re.exec(scope); if (got) { r =  parseInt(got[1], 10); switch (r) { case this.nsUser : if (! abroad &&  ! adjacent  &&                         ! WSTM.lang.write) { r =  this.females(story); }                    break; case this.nsMedia : case this.nsSpecial : case this.nsFile : case this.nsTemplate : case this.nsCategory : break; default: // not Project: ! r =  false; }  //            }         }      }      return  r;   };   // .w.link.namespace.furnish

WLINK.projects.factory =  function  { // Make RegExp alternative string for major sister projects // Postcondition: //   Returns  string with no counted brackets // 2016-05-31 PerfektesChaos@de.wikipedia return "mediawiki" + "|wik" +    "(?:i"              +       "(?:books" +        "|data" +        "|media" +        "|news" +        "|pedia" +        "|quote" +        "|source" +        "|species" +        "|tech" +        "|versity" +        "|voyage)"              +       "|tionary)"; };  // .w.link.projects.factory

WLINK.projects.find =  function (apply, achieve, about) { // Find // Precondition: //   apply    -- Array[2] with domain parts //               [0] 2nd level domain //               [1] language (subdomain) //   achieve  -- path; or false //   about    -- linktext, following ' '  --  or false // Postcondition: //   Returns  String with URL or Array[3] //            [0] project type //            [1] language //            [2] title // Uses: //   >  .w.link.protocol.secure //   .w.link.projects.upload // Requires: JavaScript 1.3  charCodeAt // 2012-11-15 PerfektesChaos@de.wikipedia var r   =  [ apply[2], apply[1], false ], got; if (achieve) { r[2] =  achieve; switch (r[0]) { case "mediawiki" : r[1] =  ""; break; case "wikimedia" : if (r[1].length < 4) { r =  false; } else if (achieve.charCodeAt(0) === 119) {  // 'w'                  switch (r[1]) { case "commons" : case "meta" : r[0] =  r[1]; r[1] =  ""; break; case "upload" : got =  this.upload(achieve, about); if (got) { r =  got; }                       break; }  // switch r[1] }              break; case "wikisource" : if (! r[1]) { r[0] =  ""; r[1] =  "OldWikisource"; }              break; case "wikivoyage" : if (! r[1]) { got =  /^([a-z][a-z])\//.exec(r[2]); if (got) { r[1] =  r[2].substr(0, 2); r[2] =  "wiki"  +  r[2].substr(2); } else { r[1] =  ""; }              }               break; default : if (r[1] === "www") { r =  "//www." + r[0] + ".org" + "/" + (achieve ? achieve : ""); if (WLINK.protocol.secure.indexOf("|" + r[0] + "|")                      >=  0) { r =  "https:" + r;                   } } else if (! r[1]) {  // undefined r[1] =  ""; }        }   // switch r[0] }     return  r;   };   // .w.link.projects.find

WLINK.projects.friend =  function (affiliate, assign) { // Is the current wiki project matched, or abbreviated // Precondition: //   affiliate  -- project name, also abbreviated //   assign     -- return also reformatted namespace // Postcondition: //   Returns false     unknown project or language or space //           array[2]  project identified //                     [0]  mode //                          1      affiliate already abbreviation //                          2      full name, abbreviated //                          3      commons  meta  mediawiki //                          false  namespace if assign //                     [1]  false  if current wiki project matches //                          string abbreviated name or      //                                  reformatted namespace if assign // Uses: //   >  .g.projType // 2016-05-31 PerfektesChaos@de.wikipedia var r      =  false, m      =  -99, sister =  affiliate.toLowerCase, scope; if (sister === WSTM.g.projType) { sister =  false; m      =  2; } else if (sister.length < 8) {  // abbreviated scope =  false; if (sister.length === 1) { sister =  affiliate; // ":sv:S:t Eriksplan (tunnelbanestation)" }        switch (sister) { case "commons" : scope =  "commons"; m     =  3; break; case "b" : scope =  "wikibooks"; break; case "d" : scope =  "wikidata"; break; case "n" : scope =  "wikinews"; break; case "m" : scope  =  "meta";   // meta.wikimedia.org sister =  "meta"; m      =  3; break; case "mw" : scope =  "mediawiki";   // mediawiki.org m     =  3; break; case "q" : scope =  "wikiquote"; break; case "s" : scope =  "wikisource"; break; case "v" : scope =  "wikiversity"; break; case "voy" : scope =  "wikivoyage"; break; case "w" : scope =  "wikipedia"; break; case "wikt" : scope =  "wiktionary"; break; }  // switch sister if (scope &&  m < 0) { m =  1; }        if (scope === WSTM.g.projType) { sister =  false; } else if (sister === WSTM.g.projType) { sister =  false; m      =  2; }     }      if (sister) { if (m < 0) { m =  2; switch (sister) { case "wikipedia" : sister =  "w"; break; case "wikibooks" : case "wikidata" : case "wikinews" : case "wikiquote" : case "wikisource" : case "wikiversity" : sister =  sister.substr(4, 1); break; case "species" : case "wikispecies" : sister =  "species"; break; case "wikitech" : sister =  "wikitech"; break; case "wikivoyage" : sister =  "voy"; break; case "wiktionary" : sister =  "wikt"; break; case "meta" : sister =  "meta"; m      =  3; break; default: m =  -1; break; }  // switch sister }  // find abbreviation if (m > 0) { r =  [m, sister]; }  // identified } else { r =  [m, false]; if (assign) {  // namespace reformatting? if (m === 2) { if (affiliate.toLowerCase === WSTM.g.projType) { r =  false; } else {  // reformatting r =  [ false, WSTM.g.projType ]; }  // space }        }      }      return  r;   };   // .w.link.projects.friend

WLINK.projects.upload =  function (achieve, about) { // Reformat any http link to a wiki upload as a wikilink // Precondition: //   achieve  -- path, following '//upload.wikimedia.org/' //   about    -- linktitle, following ' '  --  or false // Postcondition: //   Returns  false    if not to be formatted as wikilink //            array[3] [0] "" or prefix string terminated with ':' //                     [1] target of wikilink //                     [2] title of wikilink //   RegExp was used. // Uses: //   >  .g.projType //   >  .g.projLang //   >  .w.link.mediatypes //   >< .g.projUploadPath //   >< .w.link.namespace.sFile //   >< .g.re.stripFileExt //   .w.link.projects.friend //   .w.link.wiki.target //   .w.link.namespace.fetch // Requires: JavaScript 1.3  charCodeAt // 2012-11-15 PerfektesChaos@de.wikipedia var r     =  false, swift =  false, space =  false, got, n,         re; if (achieve.substr(0, 18) ===  "wikipedia/commons/") { swift =  achieve.substr(18); } else { if ( typeof WSTM.g.projUploadPath !==  "string" ) { WSTM.g.projUploadPath =  WSTM.g.projType + "/" + WSTM.g.projLang + "/"; }        n  =  WSTM.g.projUploadPath.length; if (achieve.substr(0, n) ===  WSTM.g.projUploadPath) { swift =  achieve.substr(n); } else { re  =  /^(([a-z]+)\/([a-z]+)\/)(.+)$/; got =  re.exec(achieve); if (got) { space =  this.friend(got[2], false); if (space) { space =  space[1]; if (! space) { space =  ""; }                 space  =  space + ":" + got[3] + ":File:"; swift =  got[4]; }           }         }      }      if (swift) { if (swift.charCodeAt(1) === 47 &&   // '/'             swift.charCodeAt(4) === 47  &&   // '/'             swift.charCodeAt(0) === swift.charCodeAt(2)) { swift =  swift.substr(5); r =  WLINK.wiki.target(swift); if (r) { swift =  r;            } if (! space) { if (! WLINK.namespace.sFile) { WLINK.namespace.sFile = WLINK.namespace.fetch(WLINK.namespace.nsFile,                                                 false); }              space  =  ":" + WLINK.namespace.sFile + ":"; }           r  =  new Array(3); r[0] =  space; r[1] =  swift; if (about) { r[2] =  about; } else { // -> WSTM.w.img.file if ( typeof WSTM.g.re.stripFileExt !==  "object" ) { re =  " *\\." + WLINK.mediatypes + "$"; WSTM.g.re.stripFileExt =  new RegExp(re); }              r[2]  =  swift.replace(WSTM.g.re.stripFileExt, ""); }        }      }      return  r;   };   // .w.link.wiki.projects.upload

WLINK.re.factory =  function ( ancient ) { // Initialize global variables for WMF URL // Precondition: //   ancient  -- true:  secure.wikimedia.org //               false: unified http or https since fall 2011 // Uses: //   >  .w.link.protocol.secure //   >  .w.link.protocol.relative //   >  .w.link.langs //    < .w.link.re.secure //    < .w.link.re.domain //   .w.link.projects.factory // 2019-08-20 PerfektesChaos@de.wikipedia var reProj =  "(commons"                     + WLINK.protocol.secure                     + "meta"                     + WLINK.protocol.relative                     + WLINK.langs                     + ")", reSite =  "(" + WLINK.projects.factory + ")", source; if (ancient) { source      =  "^" + reSite + "/" + reProj + "/"; this.secure =  new RegExp( source, "" ); } else { source      =  "^(?:" + reProj + "\\.)?" + "(?:m\\.)?" + reSite + "\\.org"; this.domain =  new RegExp( source, "i" ); }  };   // .w.link.re.factory

WLINK.replace.factory =  function (apply) { // Validate user defined link replacement request // Precondition: //   apply  -- .raw   array with user defined link replacements //                    Each element is an array with two elements //                    Both elements are either //                    string  with //                            [0] link full regexp //                            [1] replacement //                    Array  with 3/4 elements, //                            each pair strings regexp/replace //                           [0] prolog RE string / replacement //                               or  false / false //                           [1] link full RE string / replacement //                           [2] epilog RE string / replacement //                               or  false / false //                           [3] true: search case sensitive //                               (apply[][0]) //                               true: unlink //                               (apply[][1]) //             .name  name of user defined request variable // Postcondition: //   Returns  apply.parsed //    < apply.parsed  array with validated elements. //                    Both elements are arrays of length 3. // Uses: //   .util.isArray //   .main.fault // TODO: //   Split by recognized namespace // 2013-12-14 PerfektesChaos@de.wikipedia var r =  [ ], s =  " user definition element #", u =  apply.raw, n =  u.length, a,         e,          f,          i,          j,          k,          m,          t;      for (i = 0;  i < n;  i++) { a =  u[i]; if ( typeof a !==  "object" ) { a =  false; }        if ( ! WSTM.util.isArray(a)) { WSTM.main.fault("Invalid Syntax in" + s + i,                           apply.name); a =  [false, false]; }        f  =  a[0]; t =  a[1]; m =  typeof t;         if ( typeof f  ===  "string"   &&             ( m === "string"  ||  m === "function" ) ) { f =  [false, f, false, false]; t =  [false, t, false, false]; } else if (WSTM.util.isArray(f) && WSTM.util.isArray(t)) { m =  f.length; k =  t.length; if ((m === 3 ||  m === 4)   &&   (k === 3  ||  k === 4)) { if (m === 3) { f =  [f[0], f[1], f[2], false]; }              for (j = 0;  j < 3;  j++) { e =  f[j]; if ( typeof e ===  "string" ) { if (e.length === 0 &&  j === 1) { f =  false; break;  // for j                     } } else if (e) {  // invalid type f =  false; break;  // for j                  } else if (j === 1) {   // link regexp false f =  false; break;  // for j                  } }  // for j               for (j = 0;  j < 3;  j++) { e =  t[j]; if (e) { m =  typeof e;                     if (m !== "string"  &&  m !== "function") { f =  false; WSTM.main.fault("Invalid" + s + i,                                       apply.name); }                 }               }   // for j            } else { f =  false; }        } else {   // invalid format f =  false; }  // string or array if (f) { m =  (f[3] ? "i" : ""); for (j = 0; j < 3;  j++) { e =  f[j]; if ( typeof e ===  "string" ) { switch (j) { case 0:  // prolog e =  e + "\f"; break; case 1:  // link e =  "^" + e + "$"; break; case 2:  // epilog e =  "\f" + e;                     break; }  // j                  try { f[j] =  new RegExp(e, m); } catch (err) { WSTM.main.fault("Invalid" + s + i                                    + "\nUser link RegExp\n" + err                                     + "\n>>>" + e + "<<<\n" + f,                                     apply.name); f =  false; }              }            }   // for j            if (f) { r.push([ [f[0], f[1], f[2], f[3]],                       [t[0], t[1], t[2], t[3]] ]); }        }   // valid }  // for i      r             =  (r.length ? r : false); apply.parsed =  (r.length ? r : false); return r;   };   // .w.link.replace.factory

WLINK.replace.flip =  function (apply, adjust, ahead, after, about) { // Perform user defined link replacement // Precondition: //   apply   -- array with user defined link replacements //              Each element is an array with two elements //              Both elements are //              array  with 3 elements, each pairwise scan/replace //                     [0] prolog regexp string / replacement //                         or  false / false //                     [1] link full regexp / replacement //                     [2] epilog regexp / replacement //                         or  false / false //              Array is validated //   adjust  -- current link target //   ahead   -- prolog, may be false //   after   -- epilog, may be false //   about   -- informative hint for user defined functions // Postcondition: //   Returns  false     if not changed, //            string    adjusted link specification only //            array[3]  prolog and/or epilog modified also // Uses: //    < .mod.lazy //   .str.trimL //   .w.link.fence // 2013-12-01 PerfektesChaos@de.wikipedia var r =  false, n =  apply.length, q =  [(ahead  ?  ahead + "\f"  :  "\f"), adjust, (after ?  "\f" + after  :  "\f")], a,         e,          f,          i,          t;      for (i = 0;  i < n;  i++) { a =  apply[i]; f =  a[0]; e =  f[1]; r =  e.test(q[1]); if (r) {  // target match e =  f[0]; if (e) {  // prolog present r =  e.test(q[0]);   //   e.test(ahead); }           if (r) {   // target and prolog match e =  f[2]; if (e) {  // epilog present r =  e.test(q[2]);   //   e.test(after); }           }         }         if (r) {   // every request matching t =  a[1]; e =  typeof t[ 1 ]; if ( e === "string" ) { q[1] =  q[1].replace(f[1], t[1]); } else if ( e === "function" ) { q[1] =  q[1].replace(f[1],                                     t[1](about, i, 0, q[1])); }           if (q[0] && f[0]) { e =  typeof t[ 0 ]; if ( e === "string" ) { q[0] =  q[0].replace(f[0],  t[0] + "\f"); } else if ( e === "function" ) { q[0] =  q[0].replace(f[0],                                        t[0](about, i, -1, q[0]) + "\f"); }           }            if (q[2] && f[2]) { if ( typeof t[2] ===  "string" ) { q[2] =  q[2].replace(f[2],  "\f" + t[2]); } else if (e === "function") { q[2] =  q[2].replace(f[2],                                        "\f" + t[2](about, i, 1, q[2])); }           }            if (t[3]) { q[3] =  true; }           r  =  q[1].lastIndexOf("[") + 1; if (r > 0) { e    =  q[1].substr(0, r)  +  "\f"; q[1] =  q[1].substr(r); if (q[0]) { q[0] =  q[0].substr(0,  q[0].length - 1)   +   e;               } else { q[0] =  e;               } }           r  =  WLINK.fence(q[1], 0, true); if (r) { e    =  "\f" + WSTM.str.trimL(q[1].substr(r), false); q[1] =  q[1].substr(0, r); if (q[2]) { q[2] =  e + q[2].substr(1); } else { q[2] =  e;               } }           r  =  false; }  // match }  // for i      if (q[0]  ===  (ahead  ? ahead + "\f" :  "\f")) { q[0] =  false; }     if (q[2]  ===  (after  ? "\f" + after :  "\f")) { q[2] =  false; }     if (q[0] || q[2]) { if (q[0]) { q[0] =  q[0].substr(0,  q[0].length - 1); }        if (q[2]) { q[2] =  q[2].substr(1); }        r  =  q;      } else if (q[1] !== adjust) { r =  q[1]; }     if (r) { WSTM.mod.lazy =  false; }     return  r;   };   // .w.link.replace.flip

WLINK.replace.flipper =  function (adjust, ahead, after, area) { // Perform user defined link replacement request // DEPRECATED // Precondition: //   adjust  -- current link target //   ahead   -- prolog, may be false //   after   -- epilog, may be false //   area    -- canonical namespace name, may be false //              "File", "Template" //   Replacement Array is parsed and validated // Postcondition: //   Returns  false     if not changed, //            string    adjusted link specification only //            array[3]  prolog and/or epilog modified also // Uses: //   >  .mod.wikilink //   >  .w.link.namespace.write //   .w.link.replace.flip // 2013-03-27 PerfektesChaos@de.wikipedia var r =  this.flip(WSTM.mod.wikilink, adjust, ahead, after,                          "link4"), s;     if (! r  &&  area) { s =  WLINK.namespace.write["*"][area] + ":"; if (adjust.indexOf(s) === 0) { r =  this.flip(WSTM.mod.wikilink,                            s + adjust,                            ahead,                            after,                            "link:" + area + "4"); }        if (! r  &&  ! ahead  &&  area === "Template") { r =  this.flip(WSTM.mod.wikilink,                            adjust,                            "{{",                            after,                            "template4"); }     }      return  r;   };   // .w.link.replace.flipper

WLINK.web.fetch =  function ( analyze ) { // URL parsing until "//" // Precondition: //   analyze  -- object //               >  .limited //               >  .source //               >  .index //               >< .multiple //                < .mark //                < .met //                < .scheme //                < .lowScheme //                < .lackScheme // Uses: //   .str.isBlank //   .str.isLetter //   .hooks.fire // Requires: JavaScript 1.3  charCodeAt // 2015-12-22 PerfektesChaos@de.wikipedia var c, i, k, s;     analyze.met     =  analyze.index; analyze.scheme =  false; if ( analyze.limited ) {  // '[' pointing analyze.mark =  1; k            =  analyze.source.indexOf( "//", analyze.index ); if ( k > 0 ) { for ( i = analyze.met + 1; i < k;  i++ ) { c =  analyze.source.charCodeAt(i); if ( WSTM.str.isBlank( c, true ) ) { analyze.mark++; } else if ( c === 91 ) {  // '[' analyze.multiple++; analyze.mark++; } else { analyze.scheme =  analyze.source.substr( i,  k - i ); break;  // for i               } }  // for i         } } else if ( analyze.met ) { analyze.mark     =  0; analyze.multiple =  0; c                =  analyze.source.charCodeAt( analyze.met ); if ( c === 58 ) {  // ':' k =  analyze.met - 1; } else { k =  0; }        if ( k ) {   // '://' pointing for ( i = k; i >= 0;  i-- ) { c =  analyze.source.charCodeAt( i ); if ( ! WSTM.str.isLetter(c) ) { i++; break;  // for i               } }  // for i-- i =  (i > 0  ?  i  :  0); if ( analyze.met > i ) { k              =  analyze.met + 1; analyze.scheme =  analyze.source.substring( i, k ); analyze.met    =  i;            } }        if ( analyze.met ) { for ( i = analyze.met - 1; i >= 0;  i-- ) { c =  analyze.source.charCodeAt( i ); if ( c === 91 ) {  // '[' analyze.mark =  1; analyze.met--; analyze.multiple++; } else if ( ! WSTM.str.isBlank( c, true ) ) { break;  // for i               } }  // for i-- }     }      if ( analyze.scheme ) { s                 =  analyze.scheme.toLowerCase; analyze.lowScheme =  ( analyze.scheme !== s ); if ( analyze.lowScheme ) { analyze.scheme =  s;         } analyze.lackScheme =  false; } else { analyze.lackScheme =  WSTM.hooks.fire("https"); if ( analyze.lackScheme ) { analyze.scheme =  "https"; }        analyze.lowScheme  =  false; }  };   // .w.link.web.fetch

WLINK.web.free =  function (adjust, access, above, adhere, arg) { // Format and process any unbracketed URL, protocol required // Precondition: //   adjust  -- WikiTom top element //   access  -- location object //              .i  position to start searching for "://" //              .k  sibling number //   above   -- top level //   adhere  -- true: freeze link targets in this context //   arg     -- template parameter // Postcondition: //   Nodes are modified where suitable. //   RegExp was used. // Uses: //   >  .w.link.web.re      //     < .mod.lazy //   .o.WikiTom.find //   .w.link.web.free  -- recursive //   .o.WikiTom.format //   .o.WikiTom.freeze // 2013-06-16 PerfektesChaos@de.wikipedia var got =  access, obj =  new WSTM.o.Weblink, deep, pre;             // recent ROI start do { pre =  { i: got.i,  k: got.k }; got =  adjust.find("://", got.i, got.k, true, false, false); if (got) { deep =  got.child; if (deep) { this.free(deep.o, deep, true, adhere, arg);  // self got.i =  0; got.k++; } else if (got.i < 3) { got.i +=  6; } else { got =  obj.format(adjust,                                  { i: got.i,  j: 0,  k: got.k },                                  0,                                  arg); if (adhere) { got =  obj.freeze(got); }           }         }      } while (got); };  // .w.link.web.free

WLINK.wiki.decode =  function (adjust, article, after, alone,assume){ // Standardize wiki identifier part, decode URL // Precondition: //   adjust   -- string with identifier (article or anchor) //   article  -- true if identifier is article, not anchor //   after    -- false: trailing space not permitted and to remove //   alone    -- true if entire link -- false if titled //   assume   -- true: space for underscore -- false: keep '_' // Postcondition: //   Returns  false   if nothing to do, //            string  adjusted identifier //   RegExp was used. // Uses: //   >  .lang.ltr //   >< .w.link.wiki.reTitleSpace //   >< .w.link.wiki.reTitleSpaces //   .str.setString //   .str.setChar //   .str.trimL //   .str.trimR //   .str.substrEnd //   .lang.forward //   .str.decodeOctet // Requires: JavaScript 1.3  charCodeAt   fromCharCode(Unicode) // 2015-11-05 PerfektesChaos@de.wikipedia var c      =  false, learnt =  false, match  =  0, stuff  =  adjust, suffix =  false, i,         k1, k2, k3, n,         qc, qn, s;     if ( ! alone  &&  stuff.indexOf( "&" ) >= 0 ) {   // titled link if ( typeof this.reTitleSpace !==  "object" ) { this.reTitleSpace =  "( |&thinsp;|&#8201;|&#8239;)"; this.reTitleSpace =  new RegExp(this.reTitleSpace, "g"); }        n      =  stuff.length; stuff =  stuff.replace(this.reTitleSpace, " "); if (stuff.length < n) { learnt =  true; }     }   // ! alone if (assume) { for (i = stuff.length - 1; i >= 0;  i--) { if (stuff.charCodeAt(i) === 95) {  // '_' stuff  =  WSTM.str.setChar(stuff, 32, i);   // ' ' learnt =  true; }  // replace underscore }  // for i      } n     =  stuff.length; stuff =  WSTM.str.trimL(stuff, true); if (stuff.length < n) { learnt =  true; n      =  stuff.length; }  // ltrim stuff =  WSTM.str.trimR(stuff, false, false, false); if (WSTM.str.substrEnd(stuff, 5) ===  "&lrm;") { //   if (stuff.slice(-5) === "&lrm;") { stuff =  stuff.slice(0, -5); }     if (stuff.length < n) { learnt =  true; if (after) { suffix =  " "; n      =  n - stuff.length - 1; while (n) { suffix +=  " "; n--; }  // while n         } }  // rtrim i =  stuff.indexOf("  "); while (i >= 0) { stuff  =  WSTM.str.setString(stuff, i, 2, " "); i      =  stuff.indexOf("  "); learnt =  true; }  // while if (stuff.charCodeAt(0) === 38) {   // & if (stuff.substr(3, 2) === "m;") { WSTM.lang.forward; s =  stuff.substr(1, 2); if ((  WSTM.lang.ltr  &&  s === "lr")   ||                ( ! WSTM.lang.ltr &&  s === "rl")) { stuff  =  stuff.substr(5); learnt =  true; }  // heading superfluous char }  // m;      }   // & if (WSTM.str.substrEnd(stuff, 2) ===  "m;") { //   if (stuff.slice(-2) === "m;") { s =  WSTM.str.substrEnd(stuff, 5, 3); //         s  =  stuff.slice(-5, -2); WSTM.lang.forward; if ((  WSTM.lang.ltr  &&  s === "&lr")   ||             ( ! WSTM.lang.ltr &&  s === "&rl")) { stuff  =  stuff.substr(0,  stuff.length - 5); learnt =  true; }  // trailing superfluous char }  // m;      if (suffix) { stuff =  stuff + suffix; }  // ! after if (article) { qc =  "%"; qn =  37; } else { qc =  "."; qn =  46; }     match  =  stuff.indexOf(qc, match); while (match >= 0) { n  =  3; k1 =  WSTM.str.decodeOctet(stuff,  match + 1); if (k1 < 32) {  // invalid } else if (k1 < 48) {   // single ASCII c =  k1; } else if (k1 < 58) {   // invalid } else if (k1 < 65) {   // single ASCII c =  k1; } else if (k1 < 91) {   // invalid } else if (k1 < 97) {   // single ASCII c =  k1; } else if (k1 < 123) {  // invalid } else if (k1 < 128) {  // single ASCII c =  k1; } else if (k1 < 192) {  // invalid } else if (k1 < 240) {  // UTF-8 k2 =  (stuff.charCodeAt(match + 3)  ===  qn); if (k2) { k2 =  WSTM.str.decodeOctet(stuff,  match + 4); }           if (k2) { n =  6; if (k1 < 224) {  // byte pair if (k2 > 127 &&  k2 < 192) { c =  (k1 - 192)  *  64   +   k2   -   128; }  // k2 valid } else {  // byte triplet k3 =  (stuff.charCodeAt(match + 6)  ===  qn); if (k3) { k3 =  WSTM.str.decodeOctet(stuff,  match + 7); }                 if (k3) { n =  9; if (k3 > 127 &&  k3 < 192) { c =  (((k1 - 224)  *  64   +   k2   -   128)                               *    64) +    k3    -    128; }  // k3 valid }  // URL-encoded byte #3 }           }   // URL-encoded byte #2 }  // first byte switch (c) {  // required escapes case 32 : // ' ' if (! article) {  // in anchors c =  false;   // ".20" not to be replaced, '_' used }              break; case 35 : // # if (article) { break; }  // fall through case 38 : // & case 91 : // [ case 93 : // ] case 124 : // | c =  false; break; }  // switch c         if (c) { c      =  String.fromCharCode(c); stuff  =  WSTM.str.setString(stuff, match, n, c); learnt =  true; n      =  1; c      =  false; }  // decode match =  stuff.indexOf(qc,  match + 1); }  // while URL-encoded char if (stuff.indexOf(" ") > 0) { if ( typeof this.reTitleSpaces !==  "object" ) { this.reTitleSpaces =  new RegExp( " +", "g" ); }        stuff   =  stuff.replace(this.reTitleSpaces, " "); learnt =  true; }  // ! alone return (learnt  ?  stuff  :  false); };  // .w.link.wiki.decode

WLINK.wiki.file =  function (adjust) { // Standardize presumable file link // Precondition: //   Text has been read until end // Uses: //   >  .w.link.namespace.nsFile //   >< .w.link.namespace.sFile //   .w.link.wiki.decode //   .w.link.namespace.furnish //   .w.link.namespace.fetch // 2012-09-21 PerfektesChaos@de.wikipedia var r =  this.decode(adjust, true, false, true, true), k;     if (! r) { r =  adjust; }     k  =  r.indexOf(":"); if (k > 1) { if (WLINK.namespace.furnish(r.substr(0, k), false,  false)             ===  WLINK.namespace.nsFile) { if (! WLINK.namespace.sFile) { WLINK.namespace.sFile = WLINK.namespace.fetch(WLINK.namespace.nsFile, false); }           r  =  WLINK.namespace.sFile + r.substr(k); }     }      return  r;   };   // .w.link.wiki.file

WLINK.wiki.finalize =  function  { // Finalize category and interwiki link structure // Precondition: //   Text has been read until end // Uses: //   >< .w.encountered.cats //   >< .w.encountered.iwiki //   .errors.found // 2012-04-27 PerfektesChaos@de.wikipedia var r   =  false, got =  false, say =  false, i,         n;      switch (r) { case WSTM.o.WikiTom.LinkCategory : got =  WSTM.w.encountered.cats; break; case WSTM.o.WikiTom.LinkInterWiki : got =  WSTM.w.encountered.iwiki; break; }  // switch r      if (say) { if (got) { n =  got.length; for (i = 1; i < n;  i++) { if (got[i] === r.source) { WSTM.errors.found("???.w.link.wiki.finalize",                                   false,                                    r.source); }           }   // for i         } }  };   // .w.link.wiki.finalize

WLINK.wiki.flat =  function ( access, area ) { // Normalize wikilink target string // Precondition: //   about  -- string with wikilink target //   area   -- optional number with default namespace // Postcondition: //   Returns  string with wikilink target // Uses: //   >  .mod.wikilink //   .w.link.wiki.target //   .w.link.namespace.furnish //   .w.link.namespace.fetch //   .w.link.replace.flip //   .errors.found // 2019-08-15 PerfektesChaos@de.wikipedia var r =  access, i, lead, ns, scan, shift; /*       Kommentar elminieren; später hinten dran hängen */     if ( r.indexOf( "|" )  <  0   &&           r.indexOf( "]" )  <  0 ) { r =  this.target( r, true ); i =  r.indexOf( ":" ); if ( ! i ) { lead =  true; r    =  r.substr( 1 ); i    =  r.indexOf( ":" ); }        if ( i > 1 ) { ns =  WLINK.namespace.furnish( r.substr( 0,  i - 1 ) ); if ( ns ) { r =  r.substr( i + 1 ); if ( ns === area ) { lead =  false; } else { r =  WLINK.namespace.fetch( ns ) +  ":" + r;               } }        }         if ( WSTM.mod.wikilink ) { if ( ns === area ) { scan =  WLINK.namespace.fetch( ns ) +  ":" + r;               i     =  scan.length; scan =  scan +  ":" + r;            } else { scan =  r;            } shift =  WLINK.replace.flip( WSTM.mod.wikilink,                                          scan,                                          false,                                          false,                                          "linkPar" ); if ( shift !== scan ) { if ( ns === area ) { r =  shift.substr( i + 1 ); } else { r =  shift; }           }          }         if ( lead ) { r =  ":" + r;         } } else { WSTM.errors.found( "badPageName", false, r ); }  };   // .w.link.wiki.flat

WLINK.wiki.flush =  function (apply) { // Remove any wikilink from WikiTom // Precondition: //   apply  -- WikiTom, might contain wikilinks as children // Postcondition: //   Returns  false  if nothing to do,  else true if modified // Uses: //   >  .o.WikiTom.LinkWikiPipe //   >  .o.WikiTom.TextOnly //   .w.link.linked //   .o.WikiTom.fetch //   .str.substrEnd //   .o.WikiTom.find //   .o.WikiTom.focus //   .o.WikiTom.fresh //   .o.WikiTom.flush // 2015-08-25 PerfektesChaos@de.wikipedia var e =  apply.children, r =  false, i,         p,          q,          n,          s,          t;      if (e) { n =  e.length; if (n > 1) { for (i = n - 2; i >= 0;  i--) { if (this.linked(e[i])) { p =  apply.fetch(i - 1); if (WSTM.str.substrEnd(p, 2) ===  "") { //                if (p.slice(-2) === "[[") {                     r  =  true;                     q  =  e[i + 1];                     if (q.mode === WSTM.o.WikiTom.LinkWikiPipe) {                        t  =  apply.find("",                                         0,                                         i + 2,                                         true,                                         false,                                         false);                        if (t) {                           s  =  apply.fetch(t.k);                           s  =  s.substr(0, t.i)  +  s.substr(t.i + 2);                           t  =  apply.focus(t.k).fresh(s);                           apply.flush(i + 1);                        }                     } else {                        s  =  q.toString;                        if (s.substr(0, 2)  ===  "]]") { s =  e[i].toString  +  s.substr(2); q.fresh(s); }                    }                     apply.flush(i); i--; s =  p.toString; n =  s.length - 2; if (n) { e[i].fresh(s.substr(0, n)); } else { apply.flush(i); }                 }               }            }   // for i         } }     if (e.length === 1) { p =  e[0]; if (p.mode <= WSTM.o.WikiTom.TextOnly) { if (! p.children) { s          =  p.source; apply.mode =  p.mode; delete apply.children; apply.fresh(s); }        }      }      return  r;   };   // .w.link.wiki.flush

WLINK.wiki.fore =  function (aftermath, align) { // Find length of titled wikilink aftermath, if any // Precondition: //   aftermath  -- string with follower of a titled wikilink //   align      -- first character in aftermath to consider // Postcondition: //   Returns  false   if nothing to do, //            number  of characters to join with wikilink title //                    (terminated by interpunction etc.) // Uses: //   .str.isLetter // Requires: JavaScript 1.3  charCodeAt // 2013-06-24 PerfektesChaos@de.wikipedia var r,         c,          i,          n  =  aftermath.length; for (i = align; i < n;  i++) { c =  aftermath.charCodeAt(i); if (WSTM.str.isLetter(c)) { c =  String.fromCharCode(c); if (c.toLowerCase !== c) { break;  // for i            } // Messages*.php  "Linktrail"    /^([äöüßa-z]+)(.*)$/ } else { break;  // for i         } }  // for i      r  =  (i > align   ?   i - align   :   false); return r;   };   // .w.link.wiki.fore

WLINK.wiki.further =  function (about) { // Handle special category or interwiki link // Precondition: //   about  -- link information //             >  .mode //             >  .source // Postcondition: //   Returns true iff first occurence of this type // Uses: //   >  .o.WikiTom.LinkCategory //   >  .o.WikiTom.LinkInterWiki //   >< .w.encountered.cats //   >< .w.encountered.iwiki // 2012-04-26 PerfektesChaos@de.wikipedia var r =  false, s;     switch (about.mode) { case WSTM.o.WikiTom.LinkCategory : s =  "cats"; break; case WSTM.o.WikiTom.LinkInterWiki : s =  "iwiki"; break; }  // switch mode if (s) { if (WSTM.w.encountered[s]) { WSTM.w.encountered[s].push(about.source); } else { WSTM.w.encountered[s] =  [ about.source ]; r =  true; }     }      return  r;   };   // .w.link.wiki.further

WLINK.wiki.iwMap =  function (adjust) { // Check possible interwiki whether it is mapped to URL //   Interwiki map // Precondition: //   adjust  -- possible mapped interwiki, leading ' ' permitted // Postcondition: //   Returns adjusted string, if mapped, or false //   RegExp was used. // Uses: //   >  .w.link.wiki.iwURL //   >  .w.link.wiki.iwFamily; //   >< .w.link.wiki.iwikiMap //   >< .w.link.wiki.re_iwikiMap // 2014-09-08 PerfektesChaos@de.wikipedia var r   =  false, re, got; if ( ! this.re_iwikiMap ) { this.iwikiMap    =  this.iwURL + this.iwFamily; re               =  "^ *(" + this.iwikiMap.substr(1) + ":";         this.re_iwikiMap  =  new RegExp(re, "i");      }      got  =  this.re_iwikiMap.exec(adjust + ":");      if (got) {         re   =  new RegExp("\\|(" + got[1] + ")\\|",  "i");         got  =  re.exec(this.iwikiMap);         if (got) {            r  =  got[1];         }      }   // interwiki map      return  r;   };   // .w.link.wiki.iwMap

WLINK.wiki.linked =  function ( about ) { // Check whether WikiTom is wikilink target // Precondition: //   about  -- WikiTom element // Postcondition: //   Returns true if about is wikilink // Uses: //   >  .o.WikiTom.mode //   >  .o.WikiTom.LinkWiki //   >  .o.WikiTom.LinkExtWiki // 2012-04-18 PerfektesChaos@de.wikipedia return ( about.mode >= WSTM.o.WikiTom.LinkWiki  &&                about.mode <= WSTM.o.WikiTom.LinkExtWiki ); };  // .w.link.wiki.linked

WLINK.wiki.remove =  function (adjust) { // Remove any wikilink from content string // Precondition: //   adjust  -- string, might contain wikilinks // Postcondition: //   Returns  false   if nothing to do      //             string  with removed wikilinks //   RegExp was used. // Uses: //   .w.link.wiki.target //   .str.trimL // Requires: JavaScript 1.3  charCodeAt // Remark:  Unused but neat // 2011-01-26 PerfektesChaos@de.wikipedia var i    =  adjust.indexOf(""),          r     =  false,          fa,          j,          n,          re,          s,          scan,          show;      if (i >= 0) {         scan  =  adjust;         r  =  "";         while (i >= 0) {            r     =  r + scan.substr(0, i);            scan  =  scan.substr(i + 2);            n     =  scan.indexOf("\n");            if (n > 0) {               s  =  scan.substr(0, n);            } else {               s  =  scan;            }            n  =  s.indexOf(""); if (n > 0) { s =  s.substr(0, n); j =  s.indexOf("|"); if (j < 0) { show =  this.target(s, true); r    =  r  +  (show ? show : s); } else { s =  WSTM.str.trimL(s.substr(j + 1),  false); if (s.charCodeAt(0) === 124) {  // '|' re =  new RegExp("^(:?[a-zA-Z]+:)?" +                                        "([^|(,]+).*\\|", "");                    fa  =  re.exec(scan);                     if (fa !== null) {                        show  =  this.target(fa[2], true);                        s     =  (show ? show : fa[2]);                    }                  }                  r  =  r + s;               }               scan  =  scan.substr(n+2);            } else {               r     =  r + "[[";            }            i  =  scan.indexOf("[[");         }   // while i         r  =  r + scan;      }   // something to do      return  r;   };   // .w.link.wiki.remove

WLINK.wiki.target =  function ( adjust, alone ) { // Standardize target identifier in the wiki world // Precondition: //   adjust  -- string with link specification //   alone   -- true if entire link -- false if titled // Postcondition: //   Returns  false   if nothing to do, //            string  adjusted link specification // Uses: //   >< .w.link.re.dirent //   .hooks.fire //   .w.link.wiki.decode // 2020-02-05 PerfektesChaos@de.wikipedia var joint =  adjust.indexOf( "#" ), r     =  false, stuff =  adjust, sub   =  false, s;     if ( joint >= 0 ) {   // fragment sub =  stuff.substr( joint + 1 ); if ( joint === 0 ) { stuff =  ""; } else { stuff =  stuff.substr( 0, joint ); }        if ( sub.indexOf( ":" )  >  0 ) {   // anchor template? s =  WSTM.hooks.fire( "fragment", sub ); if ( s ) { sub =  s;               r    =  true; }        }         s  =  this.decode( sub, false, false, alone, true ); if ( s ) { if ( s === "" ) { sub =  false; } else { sub =  s;            } r =  true; } else if ( sub === "" ) { sub =  false; r   =  true; }     }   // anchor s =  this.decode( stuff, true, sub, alone, true ); if ( s ) { stuff =  s;         r      =  true; }     if ( stuff.indexOf( "&" )  >=  0 ) { if ( typeof WLINK.re.dirent !==  "object" ) { WLINK.re.dirent =  new RegExp( "&(?:lrm|rlm);", "g" ); }        s  =  stuff.replace( WLINK.re.dirent, "" ); if ( s !== stuff ) { stuff =  s;            r      =  true; }     }      if ( sub ) { stuff =  stuff + "#" + sub; }     r  =  ( r ? stuff : false ); return r;   };   // .w.link.wiki.target

WLINK.wiki.url =  function (access, address, achieve, about) { // Reformat any http link to a wiki project as a wikilink or else // Precondition: //   access   -- length of protocol part   2: relative //                                         7: http //                                         8: https //   address  -- domain and subdomains, maybe any wiki project //               downcased //   achieve  -- path, if any, following '/'  --  or false //   about    -- linktext, following ' '  --  or false // Postcondition: //   Returns  false    if not to be formatted as wikilink //            array[3] [0] "" or prefix string terminated with ':' //                     [1] target of wikilink //                     [2] title of wikilink //            string   reformatted URL //   RegExp was used. // Uses: //   >  .w.link.re.secure //   >  .g.projLang //   >  .w.link.re.domain //   >  .g.wNsNumber //   >  .w.link.protocol.secure //   >  .w.link.protocol.relative //   >  .g.projType //   >  .w.link.namespace.nsFile //   >  .w.link.namespace.nsCategory //   >< .w.link.re.titleID //   >< .w.link.re.uselang //   >< .w.link.re.urlpar //    < .mod.lazy //   .str.substrEnd //   .w.link.re.factory //   .w.link.projects.upload //   .w.link.wiki.target //   .w.link.projects.friend //   .w.link.namespace.furnish //   .str.trimL //   .str.camelCasing //   .w.link.namespace.fetch // Requires: JavaScript 1.3  charCodeAt // 2019-10-01 PerfektesChaos@de.wikipedia var life   =  true, r      =  false, domain, got, j,         key, layer, learn, mode, n,         pars, s,         scope, show, sister, slang, stuff; if (WSTM.str.substrEnd(address, 4) ===  ".org") { //   if (address.slice(-4) === ".org") { domain =  address.substr(access); layer  =  false; if (access === 8) {  // https layer =  (domain === "secure.wikimedia.org"); if (layer) { r =  [false, false, false]; if (achieve) { if (! WLINK.re.secure) { WLINK.re.factory(true); }                 got  =  WLINK.re.secure.exec(achieve.toLowerCase); if (got) { if (got[4] === "commons") { r[0] =  "commons"; r[1] =  ""; } else { r[0] =  got[1];   // reSite r[1] =  got[4];   // reProj }                    if ( achieve.charCodeAt(0) === 119) {   // 'w'                        r[2]  =  achieve.substr(got[0].length); } else { r[2] =  achieve; }                    r[2]  =  achieve.substr(got[0].length); } else { r =  false; }              } else { r[0] =  "wikimedia"; r[1] =  WSTM.g.projLang; }           }   // https://secure.wikimedia.org until summer 2011 }  // https if (! layer) {  // protocol relative / http or https 2011-10...            if (! WLINK.re.domain) { WLINK.re.factory(false); }           domain  =  WLINK.re.domain.exec(domain); if (domain) { r =  [domain[2], domain[1], false]; if (achieve) { r[2] =  achieve; if (r[0] === "wikimedia") { if (r[1].length < 4) { r =  false; } else if (achieve.charCodeAt(0) === 119) {  // 'w'                        switch (r[1]) { case "commons" : case "meta" : r[0] =  r[1]; r[1] =  ""; break; case "species" : r[0] =  "wikispecies"; r[1] =  ""; break; case "upload" : mode =  WLINK.projects.upload(achieve,                                                             about); if (mode) { r    =  mode; life =  false; }                             break; }  // switch r[1] } // case "mediawiki" : } else if (r[0] === "mediawiki") { r[1] =  ""; // case "wikisource" : } else if (r[0] === "wikisource") { if (! r[1]) { r[0] =  ""; r[1] =  "OldWikisource"; } // case "wikivoyage" : } else if (r[0] === "wikivoyage") { if (! r[1] ||  r[1] === "www") { got  =  /^([a-z][a-z])\//.exec(r[2]); if (got) { r[1] =  r[2].substr(0, 2); r[2] =  "wiki"  +  r[2].substr(2); } else { r[1] =  ""; }                    } // default : } else if (r[1] === "www") { r =  "//www." + r[0] + ".org" + "/" + (achieve ? achieve : ""); if (WLINK.protocol.secure.indexOf("|" + r[0] + "|")                        >=  0) { r =  "https:" + r;                     } life =  false; } else if (! r[1]) {  // undefined r[1] =  ""; }              }   // path }  // .link.projects.find }     }   // .org if (r && life) {  // It's a wiki. learn =  false; if (r[2]) { stuff =  r[2]; life  =  (stuff.charCodeAt(1) === 47);   // '/' ("w/") if (life) { learn =  (stuff.substr(2, 11)  ===  "wiki.phtml?"); if (learn) {  // ~2004 stuff  =  stuff.substr(13); r[2]   =  "w/index.php" + stuff; } else if (stuff.substr(2, 10) ===  "index.php?") { stuff =  stuff.substr(12); } else { life =  false; }           }            if (r[2].indexOf("uselang=") >= 0  &&  ! WSTM.g.wNsNumber) { if ( typeof WLINK.re.uselang !==  "object" ) { WLINK.re.uselang =  "([?&])uselang=[-a-z]+(&?)"; WLINK.re.uselang =  new RegExp(WLINK.re.uselang, "i"); }              got  =  WLINK.re.uselang.exec(r[2]); if (got) { if (got[1] === "?" &&  ! got[2]) { got[1] =  ""; }                 r[2]   =  r[2].replace(WLINK.re.uselang, got[1]); stuff =  r[2]; }           }            if ( life ) { if ( stuff.indexOf( "title=" ) >=  0   ||                    stuff.indexOf( "oldid=" )  >=  0 ) { pars =  { }; if ( typeof WLINK.re.titleID !==  "object" ) { WLINK.re.titleID =  "^(" +                                            "(.*&)" +                                            "(title|oldid)=" +                                            "([^&]+)&)"; WLINK.re.titleID =  new RegExp( WLINK.re.titleID ); }                 s    =  "&" + stuff + "&"; got =  WLINK.re.titleID.exec( s ); if ( got ) { pars[ got[ 3 ] ] =  got[ 4 ]; s                =  s.substr( got[ 1 ].length ); got =  WLINK.re.titleID.exec( s ); if ( got ) { pars[ got[ 3 ] ] =  got[ 4 ]; s                =  s.substr( got[ 1 ].length ); }                 }                  if (s === "&") { learn =  true; life  =  false; if (pars.oldid) { r[2] =  "Special:PermanentLink/" + pars.oldid; if (pars.title) { r[2] =  r[2]  + "?title=" + pars.title; }                    } else { r[2] =  pars.title; }                 }               } else { life =  false; }              if (! learn  &&  access !== 2) { learn =  true; }           }            if (!  (life || learn)) { learn =  (stuff.substr(0, 5)  ===  "wiki/"); if (learn) { r[2] =  stuff.substr(5); }              if (! r[2]) {   // on every project in any language r[2] =  "Main Page";   // default }           }         }         if (life) { s =  ".org/"; if (r[2]) { s =  s + r[2]; }           if (r[1] === "") { if (r[0] === "wikimedia") { r =  r[0] + ".wikimedia" + s;               } else if (r[0] === "mediawiki") { r =  "www.mediawiki" + s;               } else { r =  false; }           } else if (r[1]) { r =  r[1] + "." + r[0] + s;           } else { r =  r[0] + s;            } if (r) { r =  "//" + r;            } } else if (r) { mode =  access; if ( typeof WLINK.re.urlpar !==  "object" ) { WLINK.re.urlpar =  ".+\\?[a-z]+=(.?)"; WLINK.re.urlpar =  new RegExp( WLINK.re.urlpar, "i" ); }           got  =  WLINK.re.urlpar.exec(r[2]); if (got) { } else if (r[0] === "wikimedia") { s =  "|" + r[1] + "|"; if (WLINK.protocol.secure.indexOf(s) >= 0) { if (mode === 8) { r =  false; } else { s =  r[2]; r =  "https://" + r[1] + ".wikimedia.org"; if (s) { r =  r + "/" + s;                     } }                 mode  =  false; }           } else if (r[0] === "commons") { mode =  false; } else if (r[0] === "mediawiki") { mode =  false; r[0] =  "mw"; } else if (r[0] === "meta") { mode =  false; } else if (r[1] === "OldWikisource") { mode =  false; }           if (mode === 2) { r =  false; } else if (mode) { if (r[0] === "wikimedia") { s =  "|" + r[1] + "|"; if (WLINK.protocol.relative.indexOf(s) >=  0) { s =  r[2]; r =  "//" + r[1] + ".wikimedia.org"; if (s) { r =  r + "/" + s;                     } }              }            }            if ( typeof r  ===  "object" ) { if ( learn ) { s =  this.target(r[2], true); if (s) { r[2] =  s;                   }   // decoded } else if (r[1]) { r =  "//" + r[1] + "." + r[0] + ".org/" + r[2]; }           }         }         if ( typeof r  ===  "object" ) { show   =  about; sister =  false; slang  =  false; stuff  =  r[2]; j      =  stuff.indexOf(":"); if (r[0]) { sister =  r[0]; s      =  WLINK.projects.friend(sister, false); if ( s ) { if ( s[ 0 ] !== 1 &&                       WSTM.g.projType === "wikipedia" ) { slang =  ":en:"; }                 sister =  s[1]; if (sister) { r[0] =  sister + ":"; } else { r[0] =  ""; }  // prefix required }  // project identified }  // sister if (r[1]) { slang =  r[1]; if (slang === WSTM.g.projLang) { slang =  false; } else if (sister) { r[0] =  r[0] + slang + ":"; } else if (slang === "OldWikisource") { r[0] =  "OldWikisource:"; } else { r[0] =  ":" + slang + ":"; }           }            n  =  stuff.indexOf(":"); if (n > 2) {  // maybe File: etc.               scope  =  stuff.substr(0, n); key   =  WLINK.namespace.furnish(scope, slang, sister); if (key) { stuff =  WSTM.str.trimL(stuff.substr(n + 1),  true); if (! show) { show =  stuff; }                 stuff  =  WSTM.str.camelCasing(stuff); s     =  WLINK.namespace.fetch(key, slang); if (s) { scope =  s;                  } stuff =  scope + ":" + stuff; if ((key === NAMESPACE.nsFile || key === NAMESPACE.nsCategory)                     &&   r[0] === "") { stuff =  ":" + stuff; }  // own DB itself }           }            r[1]  =  stuff; n    =  stuff.indexOf("|"); if (show) { s =  WSTM.str.trimL(show,  true); } else { WSTM.mod.lazy =  false; }           if (n < 0) { r[2] =  (show  ?  s  :  stuff); } else { WSTM.mod.lazy =  false; r[1]          =  stuff.substr(0, n); stuff         =  WSTM.str.trimL(stuff.substr(n + 1),                                                true); if (show) { if (stuff.length > 0) { stuff =  stuff + " " + s;                  } else { stuff =  s;                  } }              r[2]  =  stuff; }           n  =  r[2].indexOf("?title="); if (n > 0) { r[2] =  r[2].substr(n + 7); }        }   // replace target by wikilink }  // replace return r;   };   // .w.link.wiki.url

};  // .bb.link mw.libs.WikiSyntaxTextMod.bb.link(mw.libs.WikiSyntaxTextMod); delete mw.libs.WikiSyntaxTextMod.bb.link;

//---

( function ( WSTM ) {  "use strict";   var sub      =  "H",       self     =  WSTM.w.link.self,       version  =  WSTM.w.link.vsn,       rls;   if ( typeof WSTM.main  ===  "object" &&    WSTM.main   && typeof WSTM.main.wait ===  "function" ) {      // Start on import: callback to waiting ...      WSTM.main.wait( sub, version );   } else if ( typeof mw.loader  ===  "object"   && typeof mw.hook !==  "undefined" ) {      rls = { };      rls[ self ] = "ready";      mw.loader.state( rls );      mw.hook( "WikiSyntaxTextMod/" + sub + ".ready" )        .fire( [ sub, version ] );   } } ( mw.libs.WikiSyntaxTextMod ) );

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

/// EOF  WikiSyntaxTextMod/dH.js