User:Jasonzhuocn/popups.js - 維基百科，自由嘅百科全書

# User:Jasonzhuocn/popups.js

### 出自維基百科，自由嘅百科全書

< User:Jasonzhuocn

注意：喺儲存之後，你可能要先略過你嘅瀏覽器快取去睇到更改。Mozilla / Firefox / Safari: 㩒住Shift掣再撳重新載入，又或者㩒Ctrl-Shift-R（喺蘋果Mac中㩒Cmd-Shift-R掣）； IE: 㩒住Ctrl掣再撳重新整理，又或者㩒Ctrl-F5掣； Konqueror: 就咁以撳個重載掣，又或者㩒F5； Opera嘅用戶可能需要先喺工具→喜好設定之中清佢哋嘅快取。

    var popupVersion="Wed Jan 4 17:14:42 EST 2006";
    // **********************************************************************
    // **                             Warning                              **
    // **********************************************************************
    // ** if you edit this file, be sure that your editor recognizes it as **
    // **   utf8, or the weird and wonderful characters in the namespaces  **
    // **   below will be completely broken. You can check with the show   **
    // **            changes button before submitting the edit.            **
    // **                      test: مدیا מיוחד Мэдыя                      **
    // **********************************************************************

    // CONTENTS

    // Stylesheets

    // Utility functions

    // Popup stuff
    //   global variables
    //   html generation
    //   downloading
    //   link generation
    //   manipulation functions
    //   tests
    //   actions
    //   thingies

    ////////////////////////////////////////////////////////////////////
    // Import stylesheet(s)
    ////////////////////////////////////////////////////////////////////

    document.write('<link rel="stylesheet" type="text/css" href="'
                 + 'http://en.wikipedia.org/w/index.php?title=User:Lupin/menus.css'
                 + '&action=raw&ctype=text/css&dontcountme=s">');

    ////////////////////////////////////////////////////////////////////
    // Utility functions
    ////////////////////////////////////////////////////////////////////

    function time() {
      var d=new Date();
      return d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() +
        '.' + (d.getTime() % 1000);
    };

    var gMsg='';
    function log(x) { if(gMsg!='')gMsg += '\n'; gMsg+=time() + ' ' + x; };

    function myalert(x) { return alert(time()+'\n'+ x); };

    ////////////////////////////////////////////////////////////////////
    // Popup stuff
    ////////////////////////////////////////////////////////////////////

    // livepreview uses a broken hex_md5 function, so we avoid it
    function md5_hex(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); };

    /////////////////////
    // GLOBAL VARIABLES //
    //////////////////////

    // Notes for translators
    // If there's a string that I've not included below, please drop a note at [[:en:User_talk:Lupin]].
    // These strings can be changed if they're impossible to translate to more flexible versions.
    // Just ask.

    function popupString(str) {
      if (popupStrings[str]) return popupStrings[str];
      return str;
    }
    if (typeof window.popupStrings=='undefined') window.popupStrings={};
    popupStrings['#']='#';
    popupStrings['actions']='操作';
    popupStrings['arin']='ARIN 查詢';
    popupStrings['article']='條目';
    popupStrings['block']='封禁';
    popupStrings['BlockipHint']='封禁用戶 %s';
    popupStrings['block log']='封禁日誌';
    popupStrings['blockLogHint']='顯示封禁用戶 %s 的紀錄';
    popupStrings['block user']='封禁用戶';
    popupStrings['Bypass redirect']='重定向';
    popupStrings['bytes']='位元組';
    popupStrings['category']='個分類';
    popupStrings['categories']='分類';
    popupStrings['Click to disambiguate this link to:']='本消歧義頁面鏈接到：';
    popupStrings['contribs']='貢獻';
    popupStrings['contributions']='貢獻';
    popupStrings['ContributionsHint']='用戶 %s 的貢獻';
    popupStrings['cookies']='cookies';
    popupStrings['count']='統計';
    popupStrings['cur']='當前';
    popupStrings['day']='天';
    popupStrings['days']='天';
    popupStrings['defaultpopupFixDabsSummary']='[[:en:Wikipedia:Tools/Navigation_popups|Popups]]工具-輔助自動修正歧義鏈接 [[%s]] 到 [[%s]]';
    popupStrings['defaultpopupFixRedirsSummary']='[[:en:Wikipedia:Tools/Navigation_popups|Popups]]工具-輔助自動修正重定向鏈接 [[%s]] 到 [[%s]]';
    popupStrings['defaultpopupRevertSummary']='[[:en:Wikipedia:Tools/Navigation_popups|Popups]]工具-輔助自動回退到版本 %s';
    popupStrings['defaultpopupRmDabLinkSummary']='[[:en:Wikipedia:Tools/Navigation_popups|Popups]]-assisted removal of dab link to [[%s]]';
    popupStrings['del']='刪除';
    popupStrings['delete']='刪除';
    popupStrings['diffCur']='當前差異';
    popupStrings['disambig']='消歧義頁';
    popupStrings['deleteHint']='刪除頁面 %s';
    popupStrings['disambigHint']='鏈接到 [[%s]] 的消歧義';
    popupStrings['Display navigation links at the top of the popup']='在popup的上部顯示導航鏈接';
    popupStrings['Download preview data']='從維基媒體伺服器下載預覽數據';
    popupStrings['edit article']='編輯條目';
    popupStrings['edit counter']='詳細編輯統計';
    popupStrings['edit']='編輯';
    popupStrings['editHint']='修改 %s 的內容';
    popupStrings['editOld']='編輯舊版本';
    popupStrings['edit talk']='編輯討論頁';
    popupStrings['edit user talk']='編輯用戶討論頁';
    popupStrings['email']='發郵件';
    popupStrings['email user']='發郵件給該用戶';
    popupStrings['EmailuserHint']='給用戶 %s 發送電子郵件';
    popupStrings['Empty page']='空頁面';
    popupStrings['Fix this redirect']='修正這個重定向';
    popupStrings['global']='全域';
    popupStrings['globalSearchHint']='在所有語言版本中搜尋 %s';
    popupStrings['hist']='歷史';
    popupStrings['historyHint']='顯示頁面 %s 的編輯歷史';
    popupStrings['history']='歷史';
    popupStrings['hour']='小時';
    popupStrings['hours']='小時';
    popupStrings['IpblocklistHint']='解封用戶 %s';
    popupStrings['image']='圖像';
    popupStrings['images']='圖像';
    popupStrings['katelinkHint']='用戶 %s 的編輯統計';
    popupStrings['kB']='KB';
    popupStrings['lastEdit']='最近編輯';
    popupStrings['last']='最近';
    popupStrings['leave comment']='編輯評論';
    popupStrings['links here']='鏈入頁面';
    popupStrings['Load images']='加載圖像';
    popupStrings['log']='日誌';
    popupStrings['mainlink']='主鏈接';
    popupStrings['minute']='分鐘';
    popupStrings['minutes']='分鐘';
    popupStrings['move']='移動';
    popupStrings['MovepageHint']='改變 %s 的標題';
    popupStrings['move page']='移動頁面';
    popupStrings['Never download extra stuff for images/previews']='不從圖像或預覽下載額外的信息';
    popupStrings['new']='新';
    popupStrings['newSectionHint']='在 %s 上新增一個討論主題';
    popupStrings['new topic']='新話題';
    popupStrings['nullEditHint']='清空 %s 的內容';
    popupStrings['null edit']='空編輯';
    popupStrings['old']='前編輯';
    popupStrings['oldEdit']='先前';
    popupStrings['Open full-size image']='打開完整圖像';
    popupStrings['Only start downloading when told to do so']='僅在點擊後開始下載';
    popupStrings['PrefixindexHint']='%s 的用戶頁面';
    popupStrings['Preview only on click']='僅在滑鼠單次點選時預覽';
    popupStrings['protectHint']='限制 %s 的編輯權限';
    popupStrings['protect']='保護';
    popupStrings['RecentchangeslinkedHint']='頁面 %s 的鏈出更改';
    popupStrings['Redirects']='重定向'; // as in Redirect to ...
    popupStrings['related changes']='鏈出更改';
    popupStrings['relatedChanges']='鏈出更改';
    popupStrings['related']='相關';
    popupStrings['remove all links to this disambig page from this article']='移動所有的鏈接到這個頁面的消歧義頁面';
    popupStrings['remove this link']='移動這個鏈接';
    popupStrings['revertHint']='回退到 %s';
    popupStrings['revert']='回退';
    popupStrings['revision %s of %s']='%s 的 %s 的版本';
    popupStrings['rv']='回退';
    popupStrings['SearchHint']='搜尋包含 %s 的條目';
    popupStrings['search']='搜尋';
    popupStrings['second']='秒';
    popupStrings['seconds']='秒';
    popupStrings['Show changes since revision %s']='顯示自版本%s的更改';
    popupStrings['Show/hide options']='顯示或隱藏這個選項';
    popupStrings['Show image previews']='顯示圖像預覽';
    popupStrings['show last edit']='顯示最近編輯';
    popupStrings['Show navigation links']='顯示導航鏈接';
    popupStrings['Show page summary data']='顯示頁面摘要數據';
    popupStrings['Show previews']='顯示預覽';
    popupStrings['Show summary data']='顯示摘要數據';
    popupStrings['Show text previews']='顯示文字預覽';
    popupStrings['Show the edit made to get revision']='顯示與最早版本的差異';
    popupStrings['Show the last edit']='顯示最後一次編輯差異';
    popupStrings['Simple popups']='簡單彈出信息';
    popupStrings['spacebar']='空格';
    popupStrings['stub']='小作品';
    popupStrings['space']='空';
    popupStrings['talk page']='討論頁面';
    popupStrings['talk']='討論';
    popupStrings['this&nbsp;revision']='這個版本';
    popupStrings['Toggle image size']='縮放圖片大小';
    popupStrings['Toggle this option']='開啟或關閉這個選項';
    popupStrings[' to ']=' 到 '; // as in Redirects to ...
    popupStrings['unblockShort']='停止';
    popupStrings['UndeleteHint']='顯示 %s 的刪除歷史';
    popupStrings['undeleteShort']='恢復';
    popupStrings['unprotectHint']='解除保護頁面 %s ，允許用戶編輯';
    popupStrings['unprotectShort']='解除';
    popupStrings['unwatchHint']='將 %s 從我的監視列表中移除';
    popupStrings['unwatchShort']='停止';
    popupStrings['Use cookies to store popups options']='使用 cookies 存儲 popups 選項';
    popupStrings['userLogHint']='顯示 %s 的用戶日誌';
    popupStrings['user log']='用戶日誌';
    popupStrings['user page']='用戶頁面';
    popupStrings['user talk']='用戶討論頁面';
    popupStrings['user']='用戶';
    popupStrings['view article']='瀏覽條目';
    popupStrings['viewHint']='轉到 %s';
    popupStrings['watchHint']='將 %s 增加到監視列表';
    popupStrings['watchThingy']='監視';
    popupStrings['week']='週';
    popupStrings['weeks']='週';
    popupStrings['what links here']='鏈入本頁面的所有頁面';
    popupStrings['whatLinksHere']='鏈入頁面';
    popupStrings['WhatlinkshereHint']='顯示 %s 的鏈入頁面';
    popupStrings['wikiLinks']='內部鏈接';
    popupStrings['autoClicked']='正自動載入下一頁，請等待！';

    var splitLoc=window.location.href.split('/');
    var thisWiki=splitLoc[2];
    var wikiLang=thisWiki.split('.')[0];

    // regexes and so on

    // this stuff should be customized for different languages

    var popNamespaces = ["Media", "Special", "Talk", "User", "User talk", "Wikipedia", "Wikipedia talk", "Image", "Image talk", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk", "Portal", "Portal talk"];

    switch (wikiLang) {
     case "af": popNamespaces=["Media", "Spesiaal", "Bespreking", "Gebruiker", "Gebruikerbespreking", "Wikipedia", "Wikipediabespreking", "Beeld", "Beeldbespreking", "MediaWiki", "MediaWikibespreking", "Sjabloon", "Sjabloonbespreking", "Hulp", "Hulpbespreking", "Kategorie", "Kategoriebespreking"]; break;
     case "als": popNamespaces=["Media", "Spezial", "Diskussion", "Benutzer", "Benutzer Diskussion", "Wikipedia", "Wikipedia Diskussion", "Bild", "Bild Diskussion", "MediaWiki", "MediaWiki Diskussion", "Vorlage", "Vorlage Diskussion", "Hilfe", "Hilfe Diskussion", "Kategorie", "Kategorie Diskussion"]; break;
     case "ar": popNamespaces=["ملف", "خاص", "نقاش", "مستخدم", "نقاش المستخدم", "ويكيبيديا", "نقاش ويكيبيديا", "صورة", "نقاش الصورة", "ميدياويكي", "نقاش ميدياويكي", "Template", "نقاش Template", "مساعدة", "نقاش المساعدة", "تصنيف", "نقاش التصنيف"]; break;
     case "ast": popNamespaces=["Media", "Especial", "Discusión", "Usuariu", "Usuariu discusión", "Uiquipedia", "Uiquipedia discusión", "Imaxen", "Imaxen discusión", "MediaWiki", "MediaWiki discusión", "Plantilla", "Plantilla discusión", "Ayuda", "Ayuda discusión", "Categoría", "Categoría discusión"]; break;
     case "be": popNamespaces=["Мэдыя", "Спэцыяльныя", "Абмеркаваньне", "Удзельнік", "Гутаркі ўдзельніка", "Вікіпэдыя", "Абмеркаваньне Вікіпэдыя", "Выява", "Абмеркаваньне выявы", "MediaWiki", "Абмеркаваньне MediaWiki", "Шаблён", "Абмеркаваньне шаблёну", "Дапамога", "Абмеркаваньне дапамогі", "Катэгорыя", "Абмеркаваньне катэгорыі"]; break;
     case "bg": popNamespaces=["Медия", "Специални", "Беседа", "Потребител", "Потребител беседа", "Уикипедия", "Уикипедия беседа", "Картинка", "Картинка беседа", "МедияУики", "МедияУики беседа", "Шаблон", "Шаблон беседа", "Помощ", "Помощ беседа", "Категория", "Категория беседа"]; break;
     case "bm": popNamespaces=["Media", "Special", "Discuter", "Utilisateur", "Discussion Utilisateur", "Wikipedia", "Discussion Wikipedia", "Image", "Discussion Image", "MediaWiki", "Discussion MediaWiki", "Modèle", "Discussion Modèle", "Aide", "Discussion Aide", "Catégorie", "Discussion Catégorie"]; break;
     case "bn": popNamespaces=["বিশেষ", "আলাপ", "ব্যবহারকারী", "ব্যবহারকারী আলাপ", "উইকিপেডিয়া", "উইকিপেডিয়া আলাপ", "চিত্র", "চিত্র আলাপ", "MediaWik i আলাপ", "Media", "MediaWiki", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "br": popNamespaces=["Media", "Dibar", "Kaozeal", "Implijer", "Kaozeadenn Implijer", "Wikipedia", "Kaozeadenn Wikipedia", "Skeudenn", "Kaozeadenn Skeudenn", "MediaWiki", "Kaozeadenn MediaWiki", "Patrom", "Kaozeadenn Patrom", "Skoazell", "Kaozeadenn Skoazell", "Rummad", "Kaozeadenn Rummad"]; break;
     case "ca": popNamespaces=["Media", "Especial", "Discussió", "Usuari", "Usuari Discussió", "Viquipèdia", "Viquipèdia Discussió", "Imatge", "Imatge Discussió", "MediaWiki", "MediaWiki Discussió", "Template", "Template Discussió", "Ajuda", "Ajuda Discussió", "Categoria", "Categoria Discussió"]; break;
     case "cs": popNamespaces=["Média", "Speciální", "Diskuse", "Wikipedista", "Wikipedista diskuse", "Wikipedie", "Wikipedie diskuse", "Soubor", "Soubor diskuse", "MediaWiki", "MediaWiki diskuse", "Šablona", "Šablona diskuse", "Nápověda", "Nápověda diskuse", "Kategorie", "Kategorie diskuse"]; break;
     case "csb": popNamespaces=["Media", "Specjalnô", "Diskùsëjô", "Brëkòwnik", "Diskùsëjô brëkòwnika", "Wiki", "Diskùsëjô Wiki", "Òbrôzk", "Diskùsëjô òbrôzków", "MediaWiki", "Diskùsëjô MediaWiki", "Szablóna", "Diskùsëjô Szablónë", "Pòmòc", "Diskùsëjô Pòmòcë", "Kategòrëjô", "Diskùsëjô Kategòrëji"]; break;
     case "cv": popNamespaces=["Медиа", "Ятарлă", "Сӳтсе явасси", "Хутшăнакан", "Хутшăнаканăн канашлу страници", "Wikipedia", "0", "Ӳкерчĕк", "Ӳкерчĕке сӳтсе явмалли", "MediaWiki", "MediaWiki сӳтсе явмалли", "Шаблон", "Шаблона сӳтсе явмалли", "Пулăшу", "Пулăшăва сӳтсе явмалли", "Категори", "Категорине сӳтсе явмалли"]; break;
     case "cy": popNamespaces=["Media", "Arbennig", "Sgwrs", "Defnyddiwr", "Sgwrs Defnyddiwr", "Wicipedia", "Sgwrs Wicipedia", "Delwedd", "Sgwrs Delwedd", "MediaWiki", "Sgwrs MediaWiki", "Nodyn", "Sgwrs Nodyn", "Help", "Help talk", "Category", "Category talk"]; break;
     case "da": popNamespaces=["Media", "Speciel", "Diskussion", "Bruger", "Bruger diskussion", "Wikipedia", "Wikipedia diskussion", "Billede", "Billede diskussion", "MediaWiki", "MediaWiki diskussion", "Skabelon", "Skabelon diskussion", "Hjælp", "Hjælp diskussion", "Kategori", "Kategori diskussion"]; break;
     case "de": popNamespaces=["Media", "Spezial", "Diskussion", "Benutzer", "Benutzer Diskussion", "Wikipedia", "Wikipedia Diskussion", "Bild", "Bild Diskussion", "MediaWiki", "MediaWiki Diskussion", "Vorlage", "Vorlage Diskussion", "Hilfe", "Hilfe Diskussion", "Kategorie", "Kategorie Diskussion", "Portal", "Portal Diskussion"]; break;
     case "el": popNamespaces=["Μέσον", "Ειδικό", "Συζήτηση", "Χρήστης", "Συζήτηση χρήστη", "Βικιπαίδεια", "Βικιπαίδεια συζήτηση", "Εικόνα", "Συζήτηση εικόνας", "MediaWiki", "MediaWiki talk", "Πρότυπο", "Συζήτηση προτύπου", "Βοήθεια", "Συζήτηση βοήθειας", "Κατηγορία", "Συζήτηση κατηγορίας"]; break;
     case "eo": popNamespaces=["Media", "Speciala", "Diskuto", "Vikipediisto", "Vikipediista diskuto", "Vikipedio", "Vikipedio diskuto", "Dosiero", "Dosiera diskuto", "MediaWiki", "MediaWiki diskuto", "Ŝablono", "Ŝablona diskuto", "Helpo", "Helpa diskuto", "Kategorio", "Kategoria diskuto"]; break;
     case "es": popNamespaces=["Media", "Especial", "Discusión", "Usuario", "Usuario Discusión", "Wikipedia", "Wikipedia Discusión", "Imagen", "Imagen Discusión", "MediaWiki", "MediaWiki Discusión", "Plantilla", "Plantilla Discusión", "Ayuda", "Ayuda Discusión", "Categoría", "Categoría Discusión"]; break;
     case "et": popNamespaces=["Meedia", "Eri", "Arutelu", "Kasutaja", "Kasutaja arutelu", "Vikipeedia", "Vikipeedia arutelu", "Pilt", "Pildi arutelu", "MediaWiki", "MediaWiki arutelu", "Mall", "Malli arutelu", "Juhend", "Juhendi arutelu", "Kategooria", "Kategooria arutelu"]; break;
     case "eu": popNamespaces=["Media", "Aparteko", "Eztabaida", "Lankide", "Lankide eztabaida", "Wikipedia", "Wikipedia eztabaida", "Irudi", "Irudi eztabaida", "MediaWiki", "MediaWiki eztabaida", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "fa": popNamespaces=["مدیا", "ویژه", "بحث", "کاربر", "بحث کاربر", "ویکیپدیا", "بحث ویکیپدیا", "تصویر", "بحث تصویر", "مدیاویکی", "بحث مدیاویکی", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "fi": popNamespaces=["Media", "Toiminnot", "Keskustelu", "Käyttäjä", "Keskustelu käyttäjästä", "Wikipedia", "Keskustelu Wikipediasta", "Kuva", "Keskustelu kuvasta", "MediaWiki", "MediaWiki talk", "Malline", "Keskustelu mallineesta", "Ohje", "Keskustelu ohjeesta", "Luokka", "Keskustelu luokasta"]; break;
     case "fo": popNamespaces=["Miðil", "Serstakur", "Kjak", "Brúkari", "Brúkari kjak", "Wikipedia", "Wikipedia kjak", "Mynd", "Mynd kjak", "MidiaWiki", "MidiaWiki kjak", "Fyrimynd", "Fyrimynd kjak", "Hjálp", "Hjálp kjak", "Bólkur", "Bólkur kjak"]; break;
     case "fr": popNamespaces=["Media", "Special", "Discuter", "Utilisateur", "Discussion Utilisateur", "Wikipédia", "Discussion Wikipédia", "Image", "Discussion Image", "MediaWiki", "Discussion MediaWiki", "Modèle", "Discussion Modèle", "Aide", "Discussion Aide", "Catégorie", "Discussion Catégorie", "Portail", "Discussion Portail"]; break;
     case "fur": popNamespaces=["Media", "Speciâl", "Discussion", "Utent", "Discussion utent", "Vichipedie", "Discussion Vichipedie", "Figure", "Discussion figure", "MediaWiki", "Discussion MediaWiki", "Model", "Discussion model", "Jutori", "Discussion jutori", "Categorie", "Discussion categorie"]; break;
     case "fy": popNamespaces=["Media", "Wiki", "Oerlis", "Meidogger", "Meidogger oerlis", "Wikipedy", "Wikipedy oerlis", "Ofbyld", "Ofbyld oerlis", "MediaWiki", "MediaWiki oerlis", "Berjocht", "Berjocht oerlis", "Hulp", "Hulp oerlis", "Kategory", "Kategory oerlis"]; break;
     case "ga": popNamespaces=["Meán", "Speisialta", "Plé", "Úsáideoir", "Plé úsáideora", "Vicipéid", "Plé Vicipéide", "Íomhá", "Plé íomhá", "MediaWiki", "Plé MediaWiki", "Teimpléad", "Plé teimpléid", "Cabhair", "Plé cabhrach", "Catagóir", "Plé catagóire"]; break;
     case "gu": popNamespaces=["Media", "Special", "Talk", "User", "User talk", "વિકિપીડિયા", "વિકિપીડિયા talk", "Image", "Image talk", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "he": popNamespaces=["Media", "מיוחד", "שיחה", "משתמש", "שיחת משתמש", "ויקיפדיה", "שיחת ויקיפדיה", "תמונה", "שיחת תמונה", "MediaWiki", "שיחת MediaWiki", "תבנית", "שיחת תבנית", "עזרה", "שיחת עזרה", "קטגוריה", "שיחת קטגוריה"]; break;
     case "hi": popNamespaces=["Media", "विशेष", "वार्ता", "सदस्य", "सदस्य वार्ता", "विकिपीडिया", "विकिपीडिया वार्ता", "चित्र", "चित्र वार्ता", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "श्रेणी", "श्रेणी वार्ता", "Help", "Help talk"]; break;
     case "hr": popNamespaces=["Mediji", "Posebno", "Razgovor", "Suradnik", "Razgovor sa suradnikom", "Wikipedia", "Razgovor Wikipedia", "Slika", "Razgovor o slici", "MediaWiki", "MediaWiki razgovor", "Predložak", "Razgovor o predlošku", "Pomoć", "Razgovor o pomoći", "Kategorija", "Razgovor o kategoriji"]; break;
     case "hu": popNamespaces=["Média", "Speciális", "Vita", "User", "User vita", "Wikipédia", "Wikipédia vita", "Kép", "Kép vita", "MediaWiki", "MediaWiki vita", "Sablon", "Sablon vita", "Segítség", "Segítség vita", "Kategória", "Kategória vita"]; break;
     case "ia": popNamespaces=["Media", "Special", "Discussion", "Usator", "Discussion Usator", "Wikipedia", "Discussion Wikipedia", "Imagine", "Discussion Imagine", "MediaWiki", "Discussion MediaWiki", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "id": popNamespaces=["Media", "Istimewa", "Bicara", "Pengguna", "Bicara Pengguna", "Wikipedia", "Pembicaraan Wikipedia", "Gambar", "Pembicaraan Gambar", "MediaWiki", "Pembicaraan MediaWiki", "Templat", "Pembicaraan Templat", "Bantuan", "Pembicaraan Bantuan", "Kategori", "Pembicaraan Kategori"]; break;
     case "is": popNamespaces=["Miðill", "Kerfissíða", "Spjall", "Notandi", "Notandaspjall", "Wikipedia", "Wikipediaspjall", "Mynd", "Myndaspjall", "Melding", "Meldingarspjall", "Snið", "Sniðaspjall", "Hjálp", "Hjálparspjall", "Flokkur", "Flokkaspjall"]; break;
     case "it": popNamespaces=["Media", "Speciale", "Discussione", "Utente", "Discussioni utente", "Wikipedia", "Discussioni Wikipedia", "Immagine", "Discussioni immagine", "MediaWiki", "Discussioni MediaWiki", "Template", "Discussioni template", "Aiuto", "Discussioni aiuto", "Categoria", "Discussioni categoria"]; break;
     case "ja": popNamespaces=["Media", "特別", "ノート", "利用者", "利用者‐會話", "Wikipedia", "Wikipedia‐ノート", "畫像", "畫像‐ノート", "MediaWiki", "MediaWiki‐ノート", "Template", "Template‐ノート", "Help", "Help‐ノート", "Category", "Category‐ノート"]; break;
     case "ka": popNamespaces=["მედია", "სპეციალური", "განხილვა", "მომხმარებელი", "მომხმარებელი განხილვა", "ვიკიპედია", "ვიკიპედია განხილვა", "სურათი", "სურათი განხილვა", "მედიავიკი", "მედიავიკი განხილვა", "თარგი", "თარგი განხილვა", "დახმარება", "დახმარება განხილვა", "კატეგორია", "კატეგორია განხილვა"]; break;
     case "ko": popNamespaces=["Media", "특수기능", "토론", "사용자", "사용자토론", "위키백과", "위키백과토론", "그림", "그림토론", "분류", "분류토론", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk"]; break;
     case "ku": popNamespaces=["Medya", "Taybet", "Nîqaş", "Bikarhêner", "Bikarhêner nîqaş", "Wîkîpediya", "Wîkîpediya nîqaş", "Wêne", "Wêne nîqaş", "MediaWiki", "MediaWiki nîqaş", "Şablon", "Şablon nîqaş", "Alîkarî", "Alîkarî nîqaş", "Kategorî", "Kategorî nîqaş"]; break;
     case "la": popNamespaces=["Specialis", "Disputatio", "Usor", "Disputatio Usoris", "Vicipaedia", "Disputatio Vicipaediae", "Imago", "Disputatio Imaginis", "MediaWiki", "Disputatio MediaWiki", "Formula", "Disputatio Formulae", "Auxilium", "Disputatio Auxilii", "Categoria", "Disputatio Categoriae", "Media"]; break;
     case "li": popNamespaces=["Media", "Speciaal", "Euverlik", "Gebroeker", "Euverlik gebroeker", "Wikipedia", "Euverlik Wikipedia", "Aafbeilding", "Euverlik afbeelding", "MediaWiki", "Euverlik MediaWiki", "Sjabloon", "Euverlik sjabloon", "Help", "Euverlik help", "Kategorie", "Euverlik kategorie"]; break;
     case "lt": popNamespaces=["Medija", "Specialus", "Aptarimas", "Naudotojas", "Naudotojo aptarimas", "Wikipedia", "Wikipedia aptarimas", "Vaizdas", "Vaizdo aptarimas", "MediaWiki", "MediaWiki aptarimas", "Šablonas", "Šablono aptarimas", "Pagalba", "Pagalbos aptarimas", "Kategorija", "Kategorijos aptarimas"]; break;
     case "mk": popNamespaces=["Медија", "Специјални", "Разговор", "Корисник", "Корисник разговор", "Wikipedia", "Wikipedia разговор", "Слика", "Слика разговор", "МедијаВики", "МедијаВики разговор", "Шаблон", "Шаблон разговор", "Помош", "Помош разговор", "Категорија", "Категорија разговор"]; break;
     case "ms": popNamespaces=["Media", "Istimewa", "Perbualan", "Pengguna", "Perbualan Pengguna", "Wikipedia", "Perbualan Wikipedia", "Imej", "Imej Perbualan", "MediaWiki", "MediaWiki Perbualan", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "mt": popNamespaces=["Media", "Special", "Talk", "User", "User talk", "Wikipedija", "Wikipedija talk", "Image", "Image talk", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "nap": popNamespaces=["Media", "Speciale", "Discussione", "Utente", "Discussioni utente", "Wikipedia", "Discussioni Wikipedia", "Immagine", "Discussioni immagine", "MediaWiki", "Discussioni MediaWiki", "Template", "Discussioni template", "Aiuto", "Discussioni aiuto", "Categoria", "Discussioni categoria"]; break;
     case "nds": popNamespaces=["Media", "Spezial", "Diskuschoon", "Bruker", "Bruker Diskuschoon", "Wikipedia", "Wikipedia Diskuschoon", "Bild", "Bild Diskuschoon", "MediaWiki", "MediaWiki Diskuschoon", "Vörlaag", "Vörlaag Diskuschoon", "Hülp", "Hülp Diskuschoon", "Kategorie", "Kategorie Diskuschoon"]; break;
     case "nl": popNamespaces=["Media", "Speciaal", "Overleg", "Gebruiker", "Overleg gebruiker", "Wikipedia", "Overleg Wikipedia", "Afbeelding", "Overleg afbeelding", "MediaWiki", "Overleg MediaWiki", "Sjabloon", "Overleg sjabloon", "Help", "Overleg help", "Categorie", "Overleg categorie"]; break;
     case "nn": popNamespaces=["Filpeikar", "Spesial", "Diskusjon", "Brukar", "Brukardiskusjon", "Wikipedia", "Wikipedia-diskusjon", "Fil", "Fildiskusjon", "MediaWiki", "MediaWiki-diskusjon", "Mal", "Maldiskusjon", "Hjelp", "Hjelpdiskusjon", "Kategori", "Kategoridiskusjon"]; break;
     case "no": popNamespaces=["Medium", "Spesial", "Diskusjon", "Bruker", "Brukerdiskusjon", "Wikipedia", "Wikipedia-diskusjon", "Bilde", "Bildediskusjon", "MediaWiki", "MediaWiki-diskusjon", "Mal", "Maldiskusjon", "Hjelp", "Hjelpdiskusjon", "Kategori", "Kategoridiskusjon"]; break;
     case "nv": popNamespaces=["Media", "Special", "Naaltsoos baa yinísht'į́", "Choinish'įįhí", "Choinish'įįhí baa yinísht'į́", "Wikiibíídiiya", "Wikiibíídiiya baa yinísht'į́", "E'elyaaígíí", "E'elyaaígíí baa yinísht'į́", "MediaWiki", "MediaWiki baa yinísht'į́", "Template", "Template talk", "Aná'álwo'", "Aná'álwo' baa yinísht'į́", "T'ááłáhági át'éego", "T'ááłáhági át'éego baa yinísht'į́"]; break;
     case "oc": popNamespaces=["Especial", "Discutir", "Utilisator", "Discutida Utilisator", "Oiquipedià", "Discutida Oiquipedià", "Image", "Discutida Image", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Media", "Help", "Help talk", "Category", "Category talk"]; break;
     case "os": popNamespaces=["Media", "Сæрмагонд", "Дискусси", "Архайæг", "Архайæджы дискусси", "Wikipedia", "0", "Ныв", "Нывы тыххæй дискусси", "MediaWiki", "Дискусси MediaWiki", "Шаблон", "Шаблоны тыххæй дискусси", "Æххуыс", "Æххуысы тыххæй дискусси", "Категори", "Категорийы тыххæй дискусси"]; break;
     case "pa": popNamespaces=["ਮੀਡੀਆ", "ਖਾਸ", "ਚਰਚਾ", "ਮੈਂਬਰ", "ਮੈਂਬਰ ਚਰਚਾ", "Wikipedia", "Wikipedia ਚਰਚਾ", "ਤਸਵੀਰ", "ਤਸਵੀਰ ਚਰਚਾ", "ਮੀਡੀਆਵਿਕਿ", "ਮੀਡੀਆਵਿਕਿ ਚਰਚਾ", "ਨਮੂਨਾ", "ਨਮੂਨਾ ਚਰਚਾ", "ਮਦਦ", "ਮਦਦ ਚਰਚਾ", "ਸ਼੍ਰੇਣੀ", "ਸ਼੍ਰੇਣੀ ਚਰਚਾ"]; break;
     case "pl": popNamespaces=["Media", "Specjalna", "Dyskusja", "Wikipedysta", "Dyskusja Wikipedysty", "Wikipedia", "Dyskusja Wikipedii", "Grafika", "Dyskusja grafiki", "MediaWiki", "Dyskusja MediaWiki", "Szablon", "Dyskusja szablonu", "Pomoc", "Dyskusja pomocy", "Kategoria", "Dyskusja kategorii", "Portal", "Dyskusja portalu"]; break;
     case "pt": popNamespaces=["Media", "Especial", "Discussão", "Usuário", "Usuário Discussão", "Wikipedia", "Wikipedia Discussão", "Imagem", "Imagem Discussão", "MediaWiki", "MediaWiki Discussão", "Predefinição", "Predefinição Discussão", "Ajuda", "Ajuda Discussão", "Categoria", "Categoria Discussão"]; break;
     case "ro": popNamespaces=["Media", "Special", "Discuţie", "Utilizator", "Discuţie Utilizator", "Wikipedia", "Discuţie Wikipedia", "Imagine", "Discuţie Imagine", "MediaWiki", "Discuţie MediaWiki", "Format", "Discuţie Format", "Ajutor", "Discuţie Ajutor", "Categorie", "Discuţie Categorie"]; break;
     case "ru": popNamespaces=["Медиа", "Служебная", "Обсуждение", "Участник", "Обсуждение участника", "Википедия", "Обсуждение Википедии", "Изображение", "Обсуждение изображения", "MediaWiki", "Обсуждение MediaWiki", "Шаблон", "Обсуждение шаблона", "Справка", "Обсуждение справки", "Категория", "Обсуждение категории"]; break;
     case "sc": popNamespaces=["Speciale", "Contièndha", "Utente", "Utente discussioni", "Wikipedia", "Wikipedia discussioni", "Immàgini", "Immàgini contièndha", "Media", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "sk": popNamespaces=["Médiá", "Špeciálne", "Diskusia", "Redaktor", "Diskusia s redaktorom", "Wikipédia", "Diskusia k Wikipédii", "Obrázok", "Diskusia k obrázku", "MediaWiki", "Diskusia k MediaWiki", "Šablóna", "Diskusia k šablóne", "Pomoc", "Diskusia k pomoci", "Kategória", "Diskusia ku kategórii"]; break;
     case "sl": popNamespaces=["Media", "Posebno", "Pogovor", "Uporabnik", "Uporabniški pogovor", "Wikipedija", "Pogovor k Wikipediji", "Slika", "Pogovor k sliki", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "sq": popNamespaces=["Media", "Speciale", "Diskutim", "Përdoruesi", "Përdoruesi diskutim", "Wikipedia", "Wikipedia diskutim", "Figura", "Figura diskutim", "MediaWiki", "MediaWiki diskutim", "Stampa", "Stampa diskutim", "Ndihmë", "Ndihmë diskutim", "Category", "Category talk"]; break;
     case "sr": popNamespaces=["Media", "Посебно", "Разговор", "Корисник", "Разговор са корисником", "Википедија", "Разговор о Википедији", "Слика", "Разговор о слици", "МедијаВики", "Разговор о МедијаВикију", "Шаблон", "Разговор о шаблону", "Помоћ", "Разговор о помоћи", "Категорија", "Разговор о категорији", "Портал", "Разговор о порталу"]; break;
     case "sv": popNamespaces=["Media", "Special", "Diskussion", "Användare", "Användardiskussion", "Wikipedia", "Wikipediadiskussion", "Bild", "Bilddiskussion", "MediaWiki", "MediaWiki diskussion", "Mall", "Malldiskussion", "Hjälp", "Hjälp diskussion", "Kategori", "Kategoridiskussion"]; break;
     case "ta": popNamespaces=["ஊடகம்", "சிறப்பு", "பேச்சு", "பயனர்", "பயனர் பேச்சு", "Wikipedia", "Wikipedia பேச்சு", "படிமம்", "படிமப் பேச்சு", "மீடியாவிக்கி", "மீடியாவிக்கி பேச்சு", "வார்ப்புரு", "வார்ப்புரு பேச்சு", "உதவி", "உதவி பேச்சு", "பகுப்பு", "பகுப்பு பேச்சு"]; break;
     case "th": popNamespaces=["Media", "พิเศษ", "พูดคุย", "ผู้ใช้", "คุยเกี่ยวกับผู้ใช้", "Wikipedia", "Wikipedia talk", "ภาพ", "คุยเกี่ยวกับภาพ", "MediaWiki", "คุยเกี่ยวกับ MediaWiki", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; break;
     case "tlh": popNamespaces=["Doch", "le'", "ja'chuq", "lo'wI'", "lo'wI' ja'chuq", "wIqIpe'DIya", "wIqIpe'DIya ja'chuq", "nagh beQ", "nagh beQ ja'chuq", "MediaWiki", "MediaWiki ja'chuq", "chen'ay'", "chen'ay' ja'chuq", "QaH", "QaH ja'chuq", "Segh", "Segh ja'chuq"]; break;
     case "tr": popNamespaces=["Media", "Özel", "Tartışma", "Kullanıcı", "Kullanıcı mesaj", "Vikipedi", "Vikipedi tartışma", "Resim", "Resim tartışma", "MedyaViki", "MedyaViki tartışma", "Şablon", "Şablon tartışma", "Yardım", "Yardım tartışma", "Kategori", "Kategori tartışma"]; break;
     case "tt": popNamespaces=["Media", "Maxsus", "Bäxäs", "Äğzä", "Äğzä bäxäse", "Wikipedia", "Wikipedia bäxäse", "Räsem", "Räsem bäxäse", "MediaWiki", "MediaWiki bäxäse", "Ürnäk", "Ürnäk bäxäse", "Yärdäm", "Yärdäm bäxäse", "Törkem", "Törkem bäxäse"]; break;
     case "uk": popNamespaces=["Медіа", "Спеціальні", "Обговорення", "Користувач", "Обговорення користувача", "Wikipedia", "Обговорення Wikipedia", "Зображення", "Обговорення зображення", "MediaWiki", "Обговорення MediaWiki", "Шаблон", "Обговорення шаблону", "Довідка", "Обговорення довідки", "Категорія", "Обговорення категорії"]; break;
     case "vi": popNamespaces=["Phương tiện", "Đặc biệt", "Thảo luận", "Thành viên", "Thảo luận Thành viên", "Wikipedia", "Thảo luận Wikipedia", "Hình", "Thảo luận Hình", "MediaWiki", "Thảo luận MediaWiki", "Tiêu bản", "Thảo luận Tiêu bản", "Trợ giúp", "Thảo luận Trợ giúp", "Thể loại", "Thảo luận Thể loại"]; break;
     case "wa": popNamespaces=["Media", "Sipeciås", "Copene", "Uzeu", "Uzeu copene", "Wikipedia", "Wikipedia copene", "Imådje", "Imådje copene", "MediaWiki", "MediaWiki copene", "Modele", "Modele copene", "Aidance", "Aidance copene", "Categoreye", "Categoreye copene"]; break;
    }

    var popNamespacesWithTalk=[null]; // NB root (article) corresponds with this entry, null
    var popTalkNamespaces=[popNamespaces[2]];

    // if the number of namespaces changes then this will have to be changed
    // maybe the easiest way is to specify the arrays by hand as in the comments following the loop

    for (var i=3; i+1<popNamespaces.length; i=i+2) {
      popNamespacesWithTalk.push(popNamespaces[i]);
      popTalkNamespaces.push(popNamespaces[i+1]);
    }

    var popSpecialNamespace=popNamespaces[1];
    var popImageNamespace=popNamespaces[7];
    var popUserNamespace=popNamespaces[3];
    var popCategoryNamespace=popNamespaces[15];
    var stubRegex= RegExp('stub[}][}]|This .*-related article is a .*stub', 'im') ;
    var disambigRegex=RegExp('([{][{]\\s*disambig|disambig\\s*[}][}]|dab\\s*[}][}])' +
                             '|[{][{]\\s*(geodis)\\s*[}][}]' + // explicit, whole template names on this line
                             '|is a .*disambiguation.*page', 'im') ;
    var popNonArticleNamespaces=popNamespaces.slice(0,2).concat(popNamespaces.slice(2));

    // end of language-specific things

    var popContribsPage=popSpecialNamespace+':' + 'Contributions';
    var popEmailPage=popSpecialNamespace+':' + 'Emailuser';

    var exceptions=RegExp('((title=|/)'+popSpecialNamespace+':|section=[0-9])') ;
    var contributions=RegExp('(title=|/)'+popContribsPage+'(&target=|/|/'+
                             popUserNamespace+':)(.*)') ;
    var emailuser=    RegExp('(title=|/)'+popEmailPage   +'(&target=|/|/'+
                             popUserNamespace+':)(.*)') ;

    //                      (^|\[\[)image: *([^|\]]*[^|\] ]) *
    //                      (^|\[\[)image: *([^|\]]*[^|\] ])([^0-9\]]*([0-9]+) *px)?
    //                                                        $4 = 120 as in 120px
    var imageRegex= RegExp('(^|\\[\\[)'+
                           popImageNamespace+
                           ': *([^|\\]]*[^|\\] ])([^0-9\\]]*([0-9]+) *px)?',
                           'img') ;
    var imageRegexBracketCount = 4;

    var categoryRegex= RegExp('\\[\\['+popCategoryNamespace+
                              ': *([^|\\]]*[^|\\] ]) *', 'i') ;
    var categoryRegexBracketCount = 1;

    var ipUserRegex=RegExp('('+popUserNamespace+':)?' +
                           '((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}' +
                           '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])');

    var oldidRegex=RegExp('[?&]oldid=([0-9]*)');

    var wikimediaWiki=RegExp('wiki([pm]edia|source|books|news|quote)\\.org|wiktionary\\.org').test(thisWiki);
    var localWiki=RegExp('^localhost').test(thisWiki);
    var protocol=splitLoc[0].split(':')[0];

    var titletail='/index.php?title=';
    if (wikimediaWiki) titletail = '/w' + titletail;
    else if (localWiki) titletail = '/wiki' + titletail;

    // /REGEX

    // we're not set up for interwiki stuff yet - only affect en, commons
    // and wiktionary links

    var reStart='[^:]*://';
    var preTitles='wiki/|w/index\\.php\\?title=';

    if (!wikimediaWiki) {
      preTitles = 'wiki/index\\.php\\?title=|wiki/index\\.php/|'+preTitles
        + '|index\\.php\\?title=' ;
    }
    var reEnd='/(' + preTitles + ')([^&?]*)';
    var re = RegExp(reStart + thisWiki.split('.').join('\\.') + reEnd);

    var titlebase=protocol+'://'+thisWiki+titletail;
    var wikibase=protocol+'://'+thisWiki+'/wiki/';

    var popupImageSize=60;

    var imageSources=new Array ();

    var commonsWiki='commons.wikimedia.org';

    // frequently seen thumbs
    imageSources.push(
       {wiki: thisWiki, thumb: true,  width: 180}, // default
       {wiki: thisWiki, thumb: true,  width: 120} // gallery
     );

    // frequently seen thumbs on commons
    if (wikimediaWiki && thisWiki!=commonsWiki) {
      imageSources.push(
        {wiki: commonsWiki, thumb: true,  width: 180},
        {wiki: commonsWiki, thumb: true,  width: 120}
      );
    }

    // unusual thumb sizes and full-size
    imageSources.push(
       {wiki: thisWiki, thumb: true,  width: 200}, // common?
       {wiki: thisWiki, thumb: true,  width: 250}, // common?
       {wiki: thisWiki, thumb: true,  width: 300},
       {wiki: thisWiki, thumb: true,  width: 210},
       {wiki: thisWiki, thumb: true,  width: 230},
       {wiki: thisWiki, thumb: false, width: 0} // no comma
    );

    // full-size on commons
    if (wikimediaWiki && thisWiki!=commonsWiki) {
      imageSources.push({wiki: commonsWiki, thumb: false, width: 0});
    }

    // downloading images are put here
    var imageArray=new Array();

    // page caching
    var gCachedPages = new Array ();
    var gImageCache = new Array();

    // FIXME what is this for?
    var gImage=null; // global for image

    // check to see if images are done with this timer
    var popupImageTimer=null;

    // misc debug messages
    var popupDebug=null;

    // These are for checkImages()
    var counter=0;
    var checkImagesTimer=null;
    var checkPoupPositionTimer=null;
    var loopcounter=0;

    // ids change with each popup: popupImage0, popupImage1 etc
    var popupIdNumber=0;

    var kateBase='http://tools.wikimedia.de/~interiot/cgi-bin/count_edits?dbname=';
    switch(thisWiki) {
     case commonsWiki:          kateBase += 'commonswiki';  break;
     case  'en.wiktionary.org': kateBase += 'enwiktionary';  break;
     default:
       kateBase += 'zh_yue'+'wiki';
    }
    kateBase += '_p';
    kateBase += '&user=';

    // for myDecodeURI
    var decodeExtras = new Array ();
    decodeExtras.push (
      {from: '%2C', to: ',' },
      {from: '_',   to: ' ' },
      {from: '%24', to: '$'},
      {from: '%26',   to: '&' } // no ,
    );

    // for setPopupHTML - needed for timers and stuff
    var popupHTMLTimers=new Array();
    var popupHTMLLoopFunctions = new Array();

    // FIXME - eliminate this
    var redirCount=0;

    // Cookie handling
    // pasted straight from http://www.quirksmode.org/js/cookies.html

    function createCookie(name,value,days)
    {
      var expires;
      if (days)
        {
          var date = new Date();
          date.setTime(date.getTime()+(days*24*60*60*1000));
          expires = "; expires="+date.toGMTString();
        }
      else expires = "";
      document.cookie = name+"="+value+expires+"; path=/";
    };

    function readCookie(name)
    {
      var nameEQ = name + "=";
      var ca = document.cookie.split(';');
      for(var i=0;i < ca.length;i++)
        {
          var c = ca[i];
          while (c.charAt(0)==' ') c = c.substring(1,c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
      return null;
    };

    function eraseCookie(name)
    {
      createCookie(name,"",-1);
    };

    // options

    // if there's no cookie, this should expand to something like
    // if (window.foo===null) window.foo=window.dfoo;
    function defaultize(x) {
      var val=null;
      var a='window.'+x;
      var b='window.d'+x;
      if (x!='popupCookies') {
        defaultize('popupCookies');
        if (popupCookies && (val=readCookie(x))) {
          eval(a + '=' + val + ';');
          return;
        }
      }
      eval('if ('+a+'===null) '+a+'=' + b + ';');
    };

    // this should expand to something like
    // if (typeof window.foo=='undefined') { window.foo=null; }; window.dfoo = 0.5;
    function newOption(x, def) {
      var a='window.'  + x;
      var b='window.d' + x;
      eval('if (typeof '+ a + '==\'undefined\') {' + a + '=null; }; ' + b + '=' + def + ';');
    };

    function getValueOf(varName) {defaultize(varName); return eval(varName);};

    // user-settable parameters and defaults
    // names beginning with a d are probably a bad idea!
    // NB strings must be "'double-quoted'"
    newOption('popupDelay', 0.5);
    newOption('removeTitles', true);
    newOption('imagePopupsForImages', true);
    newOption('popupSummaryData', true);
    newOption('simplePopups',  false);
    newOption('popupAdminLinks',  false);
    newOption('popupImages', true);
    newOption('popupPreviews', true);
    newOption('popupMaxPreviewSentences', 4);
    newOption('popupMaxPreviewCharacters', 600);
    newOption('popupNavLinks', true);
    newOption('popupNavLinkSeparator', "' &sdot; '");
    newOption('popupOnlyArticleLinks', true);
    newOption('popupNeverGetThumbs', false);
    newOption('popupImagesFromThisWikiOnly', false);
    newOption('popupAppendRedirNavLinks', true);
    newOption('popupMaxWidth', 300);
    newOption('popupSimplifyMainLink', true);
    newOption('popupMinImageWidth', 50);
    newOption('popupLastEditLink', true);
    newOption('popupHistoricalLinks', true);
    newOption('popupFixRedirs', true);
    newOption('popupLiveOptions', false);
    newOption('popupCookies', false);
    newOption('popupUnsimplifyLink', false);
    newOption('popupLoadImagesSequentially', false);
    newOption('popupShortcutKeys', false);
    newOption('popupLiveOptionsExpanded', false);
    newOption('popupFixDabs', false);
    newOption('popupImagesToggleSize',true);
    newOption('popupNewWindows', false);
    // see later - default for popupStructure is "'original'" if simplePopups is true
    newOption('popupStructure', "'menus'");
    newOption('popupInitialWidth', false); // integer or false
    newOption('popupNavLinkStyle', "'default'");
    newOption('popupDragging', true);
    newOption('popupLastModified', true);
    newOption('popupActionsMenu', true);
    newOption('popupFixDabsSummary', "'" + popupString('defaultpopupFixDabsSummary') + "'");
    newOption('popupRevertSummary', "'" + popupString('defaultpopupRevertSummary') + "'");
    newOption('popupFixRedirsSummary', "'" + popupString('defaultpopupFixRedirsSummary') + "'");
    newOption('popupRmDabLinkSummary', "'" + popupString('defaultpopupRmDabLinkSummary') + "'");
    newOption('popupPreviewKillTemplates', true);
    newOption('popupPreviewRawTemplates', false);
    newOption('popupRevertSummaryPrompt', false); // not yet implemented
    // browser-specific hacks

    if (typeof window.opera != 'undefined') {
      dpopupStructure='original';
    } else if ((self.navigator.appName)=='Konqueror') {
      dpopupNavLinkSeparator=' &bull; ';
    } else if ((self.navigator.appName).indexOf("Microsoft")!=-1) {
      dpopupNavLinkSeparator=' &#183; ';
      dpopupStructure='original';
      window.popups_isIE=true;
    }
    // IE madness with encoding
    // ========================
    //
    // suppose throughout that the page is in utf8, like wikipedia
    //
    // if a is an anchor DOM element and a.href should consist of
    //
    // http://host.name.here/wiki/foo?bar=baz
    //
    // then IE gives foo as "latin1-encoded" utf8; we have foo = decode_utf8(decodeURI(foo_ie))
    // but IE gives bar=baz correctly as plain utf8
    //
    // ---------------------------------
    //
    // IE's xmlhttp doesn't understand utf8 urls. Have to use encodeURI here.
    //
    // ---------------------------------
    //
    // summat else

    // String.prototype.parenSplit should do what ECMAscript says
    // String.prototype.split does, interspersing paren matches between
    // the split elements

    if (String('abc'.split(/(b)/))!='a,b,c') {
      // broken String.split, e.g. konq, IE
      String.prototype.parenSplit=function (re) {
        var m=re.exec(this);
        if (!m) return [this];
        // without the following loop, we have
        // 'ab'.parenSplit(/a|(b)/) != 'ab'.split(/a|(b)/)
        for(var i=0; i<m.length; ++i) {
          if (typeof m[i]=='undefined') m[i]='';
        }
        return [this.substring(0,m.index)]
          .concat(m.slice(1))
          .concat(this.substring(m.index+m[0].length).parenSplit(re));
      };
    } else {
      String.prototype.parenSplit=function (re) {return this.split(re);};
    }

    /////////////////////
    // HTML GENERATION //
    /////////////////////

    // generate html for popup image
    // <a id="popupImageLinkn"><img id="popupImagen">
    // where n=popupIdNumber
    function imageHTML(article) {
      var ret='';
      ret += '<a id="popupImageLink' + popupIdNumber + '">';
      ret += '<img align="right" valign="top" id="popupImg' + popupIdNumber + '" '
        + 'style="display: none;"></img>';
      ret += '</a>';
      return ret;
    };

    function isInToc(a) { return isSubElementOf(a,'toc'); };

    function isInArticle(a) {
      // content is for monobook.. damn. was hoping to avoid wikipedia skin references
      if (document.getElementById('article')) return isSubElementOf(a, 'article');
      else return isSubElementOf(a, 'content');
    };

    function isSubElementOf(a, tag) {
      var obj = a;
      var i=0;
      // this may well slow things down when this function is iterated
      // would perhaps be more efficient to cache this result before the
      // function is called. or maybe the browser does that magically anyway
      var tagged=document.getElementById(tag);
      if (!tagged) return false;

      do {obj = obj.parentNode; ++i; }
      while (obj != tagged && obj.nodeName != 'HTML');

      if (obj.nodeName == 'HTML') return false;
      return true;
    };

    // Source: http://aktuell.de.selfhtml.org/artikel/javascript/utf8b64/utf8.htm
    function encode_utf8(rohtext) {
      // dient der Normalisierung des Zeilenumbruchs
      rohtext = rohtext.replace(/\r\n/g,"\n");
      var utftext = "";
      for(var n=0; n<rohtext.length; n++)
        {
          // ermitteln des Unicodes des  aktuellen Zeichens
          var c=rohtext.charCodeAt(n);
          // alle Zeichen von 0-127 => 1byte
          if (c<128)
            utftext += String.fromCharCode(c);
          // alle Zeichen von 127 bis 2047 => 2byte
          else if((c>127) && (c<2048)) {
            utftext += String.fromCharCode((c>>6)|192);
            utftext += String.fromCharCode((c&63)|128);}
          // alle Zeichen von 2048 bis 66536 => 3byte
          else {
            utftext += String.fromCharCode((c>>12)|224);
            utftext += String.fromCharCode(((c>>6)&63)|128);
            utftext += String.fromCharCode((c&63)|128);}
        }
      return utftext;
    }

    function decode_utf8(utftext) {
      var plaintext = ""; var i=0; var c=c1=c2=0;
      // while-Schleife, weil einige Zeichen uebersprungen werden
      while(i<utftext.length)
        {
          c = utftext.charCodeAt(i);
          if (c<128) {
            plaintext += String.fromCharCode(c);
            i++;}
          else if((c>191) && (c<224)) {
            c2 = utftext.charCodeAt(i+1);
            plaintext += String.fromCharCode(((c&31)<<6) | (c2&63));
            i+=2;}
          else {
            c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2);
            plaintext += String.fromCharCode(((c&15)<<12) | ((c2&63)<<6) | (c3&63));
            i+=3;}
        }
      return plaintext;
    }

    function articleFromURL(h) {
      if (typeof h != 'string') h=String(h);
      if (window.popups_isIE) {
        // IE is stupid, basically. it doesn't "get" this new-fangled utf-8 thing
    	// no, wait. it's worse than that
    	// IE seems to treat the query string differently to the rest of the url
    	// the query is treated as bona-fide utf8, but the first bit of the url is pissed around with
        var splitted=h.split('?');
    	h=decode_utf8(decodeURI(splitted[0]));
    	if (splitted.length>1) {
    	  splitted[0]='';
    	  var query=splitted.join('?');
    	  h+=decodeURI(query);
    	}
      }
      else h=decodeURI(h);

      var article=null;

      var contribs=contributions.exec(h);
      if (contribs != null) { article=popUserNamespace+':'+contribs[3];  return article;  }

      var email=emailuser.exec(h);
      if (email != null) { article=popUserNamespace+':'+email[3]; return article;  }

      // no more special cases to check --
      // hopefully it's not a disguised user-related page

      var m=re.exec(h);
      if(m===null) return null;
      article=m[2];
      return article;
    };

    function articleFromAnchor(a) {return articleFromURL(a.href);};

    function oldidFromAnchor(a) { var m=oldidRegex.exec(a.href); if (m) return m[1]; return null; };

    function fillEmptySpans(args) { return fillEmptySpans2(args); }

    function fillEmptySpans2(args) { // if redir is present and true then redirTarget is mandatory
      var redir=true;
      if (typeof args != 'object' || typeof args.redir == undef || !args.redir) redir=false;
      var a=window.currentLink;
      log('fillEmptySpans: a='+a+', window.currentLink='+window.currentLink);
      if (!a) { log('*****\nfillEmptySpans: a is no good\n*****'); return; }

      var article, hint, oldid;
      if (redir && typeof args.redirTarget == typeof '') {
        article=args.redirTarget; hint=null;
        // Gah.
        if (window.popups_isIE) article=decodeURI(article);
      } else {
        article=articleFromAnchor(a);
        hint=a.originalTitle;
        if (hint == '' || hint == null) hint = safeDecodeURI(article);
        oldid=(getValueOf('popupHistoricalLinks'))?oldidFromAnchor(a):null;
      }

      log('fillEmptySpans: redir='+redir+', article='+article);
      var x={article: article,
             hint: hint,
             oldid: oldid };

      defaultize('popupStructure');
      var structure=window.popupStructures[popupStructure];
      if (typeof structure != 'object') {
        setPopupHTML('popupError', 'Unknown structure: '+ popupStructure);
        return;
      }
      var spans=flatten(window.popupLayout);
      var redirs=window.popupRedirSpans;
      log('fillEmptySpans: spans.length='+spans.length);
      for (var i=0; i<spans.length; ++i) {
        var f=findThis(redirs, spans[i]);
        log('redir='+redir+', f='+f+', spans[i]='+spans[i]);
        if ( (f!=null && !redir) || (f==null && redir) ) {
          log('skipping this set of the loop');
          continue;
        }
        var structurefn=structure[spans[i]];
        switch (typeof structurefn) {
        case 'function':
          log('running '+spans[i]+'({article:'+x.article+', hint:'+x.hint+', oldid: '+x.oldid+'})');
          setPopupHTML(structurefn(x), spans[i]);
          break;
        case 'string':
          setPopupHTML(structurefn, spans[i]);
          break;
        default:
          log('unknown thing with label '+spans[i]);
          break;
        }
      }
    };

    // flatten an array
    function flatten(list, start) {
      var ret=[];
      if (typeof start == undef) start=0;
      for (var i=start; i<list.length; ++i) {
        if (typeof list[i] == typeof []) {
          return ret.concat(flatten(list[i])).concat(flatten(list, i+1));
        }
        else ret.push(list[i]);
      }
      return ret;
    };

    window.popupStructures = new Object;

    window.popupStructures.original=new Object;

    window.popupStructures.original.popupLayout=function () {
      return ['popupError', 'popupImage', 'popupTopLinks', 'popupTitle', 'popupData', 'popupOtherLinks',
              'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'],
              'popupMiscTools', ['popupLiveOptions', 'popupUnsimplify'],
              'popupPreview', 'popupFixDab'];
    };
    window.popupStructures.original.popupRedirSpans=function () {
      return ['popupRedir', 'popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'];
    };
    window.popupStructures.original.popupTitle=function (x) {
      log ('defaultstructure.popupTitle');
      if (!getValueOf('popupNavLinks')) return navlinkStringToHTML('<b><<mainlink>></b>',x.article,x.oldid);
      return '';
    };
    window.popupStructures.original.popupTopLinks=function (x) {
      log ('defaultstructure.popupTopLinks');
      if (getValueOf('popupNavLinks')) return navLinksHTML(x.article, x.hint, x.oldid);
      return '';
    };
    window.popupStructures.original.popupImage=function(x) {
      log ('original.popupImage, x.article='+x.article+', popupIdNumber='+popupIdNumber);
      return imageHTML(x.article);
    };
    window.popupStructures.original.popupUnsimplify=function(x) {
      if (getValueOf('popupUnsimplifyLink')) return '<br><span onClick="javascript:popupUnsimplify()" '
        + 'style="cursor:pointer; border: thin dotted black" '
        + 'title="' +popupString('Download preview data') + '">'
        + 'Get preview data'
        + '</span>';
      return '';
    };
    window.popupStructures.original.popupRedirTitle=window.popupStructures.original.popupTitle;
    window.popupStructures.original.popupRedirTopLinks=window.popupStructures.original.popupTopLinks;

    var prop;

    function copyStructure(oldStructure, newStructure) {
      window.popupStructures[newStructure]=new Object();
      for (var prop in window.popupStructures[oldStructure])
        window.popupStructures[newStructure][prop]=window.popupStructures[oldStructure][prop];
    }

    /** -- fancy -- **/
    copyStructure('original', 'fancy');
    window.popupStructures.fancy.popupTitle=function (x) {
      return navlinkStringToHTML('<font size=+0><<mainlink>></font>',x.article,x.oldid);
    };
    window.popupStructures.fancy.popupTopLinks=function(x) {
      var hist='<<history|shortcut=h|hist>>|<<lastEdit|shortcut=/|last>>';
      var watch='<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
      var move='<<move|shortcut=m|move>>';
      return navlinkStringToHTML('if(talk){'
                                +'<<edit|shortcut=e>>|<<new|shortcut=+|+>>*' + hist + '*'
                                +'<<article|shortcut=a>>|<<editArticle|edit>>' + '*' + watch + '*' + move
                                +'}else{<<edit|shortcut=e>>*' + hist
                                +'*<<talk|shortcut=t|>>|<<editTalk|edit>>|<<newTalk|shortcut=+|new>>'
                                +'*' + watch + '*' + move+'}<br>', x.article, x.oldid);
    };
    window.popupStructures.fancy.popupOtherLinks=function(x) {
      var admin='<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*<<undelete|undeleteShort>>|<<delete|shortcut=d|del>>';
      var user='<<contribs|shortcut=c>>';
      if (wikimediaWiki) user+='if(ipuser){}else{|<<count|shortcut=#|#>>}';
      user+='if(ipuser){|<<arin>>}else{*<<email|shortcut=E|'+
        popupString('email')+'>>}if(admin){*<<block|shortcut=b>>}';

      var normal='<<whatLinksHere|shortcut=l|links here>>*<<relatedChanges|shortcut=r|related>>';
      return navlinkStringToHTML('<br>if(user){' + user + '*}if(admin){'+admin+'if(user){<br>}else{*}}'
                +normal, x.article, x.oldid);
    };
    window.popupStructures.fancy.popupRedirTitle=window.popupStructures.fancy.popupTitle;
    window.popupStructures.fancy.popupRedirTopLinks=window.popupStructures.fancy.popupTopLinks;
    window.popupStructures.fancy.popupRedirOtherLinks=window.popupStructures.fancy.popupOtherLinks;

    /** -- fancy2 -- **/
    // hack for [[User:MacGyverMagic]]
    copyStructure('fancy', 'fancy2');
    window.popupStructures.fancy2.popupTopLinks=function(x) { // hack out the <br> at the end and put one at the beginning
      return '<br>'+window.popupStructures.fancy.popupTopLinks(x).replace(RegExp('<br>$','i'),'');
    };
    window.popupStructures.fancy2.popupLayout=function () { // move toplinks to after the title
      return ['popupError', 'popupImage', 'popupTitle', 'popupData', 'popupTopLinks', 'popupOtherLinks',
              'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'],
              'popupMiscTools', ['popupLiveOptions', 'popupUnsimplify'],
              'popupPreview', 'popupFixDab'];
    };

    /** -- menus -- **/
    copyStructure('original', 'menus');
    window.popupStructures.menus.popupLayout=function () {
      return ['popupError', 'popupImage', 'popupTopLinks', 'popupTitle', 'popupOtherLinks',
              'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'],
              'popupData', 'popupMiscTools', ['popupLiveOptions', 'popupUnsimplify'],
              'popupPreview', 'popupFixDab'];
    };

    window.popupStructures.menus.popupTopLinks = function (x) {
      var s='';
      var hist='<<history|shortcut=h>>';
      var lastedit='<<lastEdit|shortcut=/|show last edit>>';
      var linkshere='<<whatLinksHere|shortcut=l|what links here>>';
      var related='<<relatedChanges|shortcut=r|related changes>>';
      var search='<<search|shortcut=s>>';
      if (wikimediaWiki) search += '|<<globalsearch|shortcut=g|global>>';
      var watch='<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';
      var protect='<<unprotect|unprotectShort>>|<<protect|shortcut=p>>';
      var del='<<undelete|undeleteShort>>|<<delete|shortcut=d>>';
      var move='<<move|shortcut=m|move page>>';
      var dropdiv='<div class="popup_drop">';
      var menuspan='<span class="popup_menu">';
      var rowspan='<span class="popup_menu_row">';
      var enddiv='</div>';
      var endspan='</span>';
      if (getValueOf('popupActionsMenu')) s += '<<mainlink>>*' + dropdiv + '<a href="#">'+popupString('actions') + '</a>';
      else s+= dropdiv + '<<mainlink>>';
      s+= menuspan
            + 'if(oldid){'+rowspan+'<<edit|shortcut=e>>|<<editOld|shortcut=e|this&nbsp;revision>>' + endspan
            + '<<revert|shortcut=v>>'
            + '}else{<<edit|shortcut=e>>}'
            + 'if(talk){<<new|shortcut=+|new topic>>}'
            + hist + lastedit + move
            + linkshere + related
            + '<<nullEdit|shortcut=n|null edit>>'
            + rowspan + search + endspan
            + '<hr>'
            + rowspan + watch + endspan
            + 'if(admin){' + rowspan + protect + endspan + rowspan + del + endspan + '}'
            + 'if(talk){'
            + '<hr>'
            + '<<article|shortcut=a|view article>>'
            + '<<editArticle|edit article>>'
            + '}else{'
            + '<hr>'
            + '<<talk|shortcut=t|talk page>>'
            + '<<editTalk|edit talk>>'
            + '<<newTalk|shortcut=+|new topic>>'
            + '}'
            + endspan
      + enddiv;
      s+='if(user){*' + dropdiv + '<a href="#">'+popupString('user')+'</a>' + menuspan
            + rowspan + '<<userPage|shortcut=u|user page>>|<<userSpace|space>>' + endspan
            + '<<userTalk|shortcut=t|user talk>>'
            + '<<editUserTalk|edit user talk>>'
            + '<<newUserTalk|shortcut=+|leave comment>>'
            + 'if(ipuser){<<arin>>}else{<<email|shortcut=E|email user>>}'
            + '<hr>'
            + '<<contribs|shortcut=c|contributions>>'
            + '<<userlog|shortcut=L|user log>>'
            + ((wikimediaWiki)?'<<count|shortcut=#|edit counter>>':'')
            + 'if(admin){' + rowspan + '<<unblock|unblockShort>>|<<block|shortcut=b|block user>>' + endspan +'}'
            + '<<blocklog|shortcut=B|block log>>'
            + endspan + enddiv
            + '}';
      return navlinkStringToHTML(s, x.article, x.oldid);
    };

    window.popupStructures.menus.popupRedirTitle=window.popupStructures.menus.popupTitle;
    window.popupStructures.menus.popupRedirTopLinks=window.popupStructures.menus.popupTopLinks;

    // Generate html for whole popup
    function popupHTML (a) {
      defaultize('popupStructure');
      var structure=window.popupStructures[popupStructure];
      if (typeof structure != 'object') return 'Unknown structure: '+popupStructure;
      if (typeof structure.popupLayout != 'function') return 'Bad layout';
      window.popupLayout=structure.popupLayout();
      if (typeof structure.popupRedirSpans == 'function') window.popupRedirSpans=structure.popupRedirSpans();
      else window.popupRedirSpans=[];
      return makeEmptySpans(window.popupLayout);
    };

    function makeEmptySpans (list) {
      var ret='';
      for (var i=0; i<list.length; ++i) {
        if (typeof list[i] == typeof '')
          ret += emptySpanHTML(list[i], popupIdNumber);
        else if (typeof list[i] == typeof [] ) {
          ret = ret.substring(0,ret.length-'</span>'.length) + makeEmptySpans(list[i]) + '</span>';
        }
      }
      return ret;
    };

    function popupUnsimplify() {};

    function isIpUser(user) {return ipUserRegex.test(user);};

    function popupToggleVar(varstring) {
      defaultize(varstring);
      //eval('window.'+varstring+'=!window.' + varstring);
      window[varstring] = !window[varstring];
      defaultize('popupCookies');
      if (popupCookies) createCookie(varstring, String(window[varstring]));
    };

    function popupToggleShowOptions (dummy) {
      // just update state if dummy is true
      defaultize('popupLiveOptionsExpanded');
      if (!dummy) window.popupLiveOptionsExpanded=!window.popupLiveOptionsExpanded;
      setPopupHTML((window.popupLiveOptionsExpanded) ? '&lt;&lt;' : '&gt;&gt;',
                   'optionPopped');
      var s=document.getElementById('popupOptionsDiv');
      // if (!s) return;
      if (window.popupLiveOptionsExpanded) s.style.display='inline';
      else s.style.display='none';
    };

    function popupOptionsCheckboxHTML(varstring, label, title) {
      var html='<br>';
      html += '<span title="'+title+'">';
      html += '<input type="checkbox" id="'+varstring+'Checkbox" ';
      html += (window[varstring]) ? 'checked="checked" ' : '';
      html += 'onClick="javascript:popupToggleVar(' + "'" + varstring + "'" +
        ')">' + label + '</input></span>';
      return html;
    };

    function popupLiveOptionsHTML() {
      var html = '';
      html += '<br>';
      html += '<span title="' + popupString('Show/hide options') + '" ';
      html += 'style="border: thin dotted black; cursor: pointer" ';
      html += 'onClick="javascript:popupToggleShowOptions()">';
      html += 'Options <span id="optionPopped' + popupIdNumber + '"></span>';
      html += '</span>';
      html += '<div style="display: none" id="popupOptionsDiv">';
      html += popupOptionsCheckboxHTML('simplePopups', popupString('Simple popups'),
                   popupString('Never download extra stuff for images/previews'));
      html += popupOptionsCheckboxHTML('popupUnsimplifyLink', popupString('Preview only on click'),
                   popupString('Only start downloading when told to do so'));
      //html += popupOptionsCheckboxHTML('popupCookies', popupString('cookies'),
      //             popupString('Use cookies to store popups options'));
      html += popupOptionsCheckboxHTML('popupNavLinks', popupString('Show navigation links'),
                   popupString('Display navigation links at the top of the popup'));
      html += popupOptionsCheckboxHTML('popupImages', popupString('Show image previews'),
                   popupString('Load images'));
      html += popupOptionsCheckboxHTML('popupSummaryData', popupString('Show summary data'),
                   popupString('Show page summary data'));
      html += popupOptionsCheckboxHTML('popupPreviews', popupString('Show text previews'),
                   popupString('Show previews'));

      var extraOptions=[
                        'imagePopupsForImages',
                        'popupAdminLinks',
                        'popupAppendRedirNavLinks',
                        'popupCookies',
                        'popupFixDabs',
                        'popupFixRedirs',
                        'popupHistoricalLinks',
                        'popupImagesFromThisWikiOnly',
                        'popupImagesToggleSize',
                        'popupLastEditLink',
                        'popupLiveOptions',
                        'popupLoadImagesSequentially',
                        'popupNeverGetThumbs',
                        'popupOnlyArticleLinks',
                        'popupPreviewKillTemplates',
                        'popupPreviewFirstParOnly',
                        'popupShortcutKeys',
                        'popupSimplifyMainLink',
                        'removeTitles' // no ,
      ];
      for (var i=0; i<extraOptions.length; ++i) {
        html += popupOptionsCheckboxHTML(extraOptions[i], extraOptions[i], popupString('Toggle this option'));
      }

      html += '</div>';
      return html;
    };

    function emptySpanHTML(name, id) {return '<span id="' + name + id + '"></span>';};

    function addLinkProperty(html, property) {
      // take "<a href=...>...</a> and add a property
      // not sophisticated at all, easily broken
      var i=html.indexOf('>');
      if (i<0) return html;
      return html.substring(0,i) + ' ' + property + html.substring(i);
    };

    function addPopupShortcut(html, key) {
      if (!getValueOf('popupShortcutKeys')) return html;
      var ret= addLinkProperty(html, 'popupkey="'+key+'"');
      if (key==' ') key=popupString('spacebar');
      return ret.replace(RegExp('^(.*?)(title=")(.*?)(".*)$', 'i'),'$1$2$3 ['+key+']$4');
    };

    function defaultNavlinkSpec() {
      var str='';
      str += '<b><<mainlink|shortcut= >></b>';
      if (getValueOf('popupLastEditLink')) str += '*<<lastEdit|shortcut=/>>if(oldid){|<<oldEdit>>|<<diffCur>>}';
      str+='<<imagestatus>>';

      // user links
      // contribs - log - count - email - block
      // count only if applicable; block only if popupAdminLinks
      str += 'if(user){<br><<contribs|shortcut=c>>*<<userlog|shortcut=L|log>>';
      if (wikimediaWiki) str+='if(ipuser){*<<arin>>}else{*<<count|shortcut=#>>}';
      str+='if(ipuser){}else{*<<email|shortcut=E>>}if(admin){*<<block|shortcut=b>>}}';

      // editing links
      // talkpage   -> edit|new - history - un|watch - article|edit
      // other page -> edit - history - un|watch - talk|edit|new
      var editstr='<<edit|shortcut=e>>';
      var editOldidStr='if(oldid){<<editOld|shortcut=e>>|<<revert|shortcut=v|rv>>|<<edit|cur>>}else{' + editstr + '}'
      var historystr='<<history|shortcut=h>>';
      var watchstr='<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>';

      str+='<br>if(talk){' +
        editOldidStr+'|<<new|shortcut=+>>' + '*' + historystr+'*'+watchstr + '*' + '<b><<article|shortcut=a>></b>|<<editArticle|edit>>'
        + '}else{' // not a talk page
        + editOldidStr + '*' + historystr + '*' + watchstr + '*' + '<b><<talk|shortcut=t>></b>|<<editTalk|edit>>|<<newTalk|shortcut=+|new>>'
        + '}';

      // misc links
      str += '<br><<whatLinksHere|shortcut=l>>*<<relatedChanges|shortcut=r>>*<<move|shortcut=m>>';

      // admin links
      str += 'if(admin){<br><<unprotect|unprotectShort>>|<<protect|shortcut=p>>*' + '<<undelete|undeleteShort>>|<<delete|shortcut=d>>}';
      return str;
    };

    function navLinksHTML (article, hint, oldid) {
      //  defaultize('popupNavLinkSeparator');
      var str = '<span class="popupNavLinks">';
      var style=getValueOf('popupNavLinkStyle');
      switch (style) {
      case 'default':
        str += defaultNavlinkSpec();
        break;
      default:
        if (typeof style == 'function') str += style();
        else str+=String(style);
      }
      str += '</span>';

      // BAM
      return navlinkStringToHTML(str, article, oldid);
    };

    function reportErrorHTML(err) {
      return 'Error: '+err+ ' Please <a href="' +
        'http://en.wikipedia.org/wiki/User_talk:Lupin?action=edit&section=new' +
        '">report this</a>!';
    };

    function expandConditionalNavlinkString(s,article,oldid,recursionCount) {
      // nested conditionals (up to 10 deep) are ok, hopefully! (work from the inside out)
      if (typeof recursionCount!=typeof 0) recursionCount=0;
      var conditionalSplitRegex=RegExp(
        '(;?\\s*if\\s*\\(\\s*([a-z]*)\\s*\\)\\s*\\{([^{}]*)\\}(\\s*else\\s*\\{([^{}]*?)\\}|))', 'i');
      var splitted=s.parenSplit(conditionalSplitRegex);
      // $1: whole conditional
      // $2: user|talk
      // $3: true expansion
      // $4: else clause (possibly empty)
      // $5: false expansion (possibly null)
      var numParens=5;
      ret = splitted[0];
      for (var i=1; i<splitted.length; i=i+numParens+1) {

        var testString=splitted[i+2-1];
        var trueString=splitted[i+3-1];
        var falseString=splitted[i+5-1];
        if (typeof falseString==undef || !falseString) falseString='';
        var testResult=null;

        switch (testString) {
        case 'user':
          testResult=(userName(article))?true:false;
          break;
        case 'talk':
          testResult=(talkPage(article))?false:true; // talkPage converts _articles_ to talkPages
          break;
        case 'admin':
          testResult=getValueOf('popupAdminLinks')?true:false;
          break;
        case 'oldid':
          testResult=(typeof oldid != undef && oldid)?true:false;
          break;
        case 'ipuser':
          testResult=(isIpUser(userName(article)))?true:false;
          break;
        }

        switch(testResult) {
        case null: ret+=splitted[i];  break;
        case true: ret+=trueString;   break;
        case false: ret+=falseString; break;
        }

        // append non-conditional string
        ret += splitted[i+numParens];
      }
      if (conditionalSplitRegex.test(ret) && recursionCount < 10)
        return expandConditionalNavlinkString(ret,article,oldid,recursionCount+1);
      else return ret;
    };

    function navlinkStringToArray(s, article, oldid) {
      s=expandConditionalNavlinkString(s,article,oldid);
      var splitted=s.parenSplit(RegExp('<<(.*?)>>'));
      var ret=[];
      for (var i=0; i<splitted.length; ++i) {
        if (i%2) { // i odd, so s is a tag
          var t=new navlinkTag();
          var ss=splitted[i].split('|');
          t.id=ss[0];
          for (var j=1; j<ss.length; ++j) {
            var sss=ss[j].split('=');
            if (sss.length>1)
              // eval ('t.'+sss[0]+'="'+sss[1]+'";');
              t[sss[0]]=sss[1];
            else // no assignment (no "="), so treat this as a title (overwriting the last one)
              t.text=popupString(sss[0]);
          }
          t.article=article;
          if (typeof oldid != undef && oldid != null) t.oldid=oldid;
          if (!t.text && t.id != 'mainlink') t.text=popupString(t.id);
          ret.push(t);
        }
        else { // plain HTML
          ret.push(splitted[i].split('*').join(getValueOf('popupNavLinkSeparator')));
        }
      }
      return ret;
    };

    // navlinkString: * becomes the separator
    //                <<foo|bar=baz|fubar>> becomes a foo-link with attribute bar='baz'
    //                                      and visible text 'fubar'
    //                if(test){...} and if(test){...}else{...} work too (nested ok)

    function navlinkStringToHTML(s,article,oldid) {
      var p=navlinkStringToArray(s,article,oldid);
      var html='';
      for (var i=0; i<p.length; ++i) {
        if (typeof p[i] == typeof '') {
          html+=p[i];
        } else if (typeof p[i].type != undef && p[i].type=='navlinkTag') {
          html+=p[i].html();
        }
      }
      return html;
    }

    function navlinkTag() {this.type='navlinkTag';};

    navlinkTag.prototype.html=function () {
      this.getPrintFunction();
      var html='';
      if (typeof this.print!='function') {
        log ('Oh dear - invalid print function for a navlinkTag, id='+this.id);
      } else {
        html=this.print(this);
        if (typeof html != typeof '') {html='';}
        else if (typeof this.shortcut!=undef) html=addPopupShortcut(html, this.shortcut);
      }
      return '<span class="popup_'+this.id+'">'+html+'</span>';
    };

    navlinkTag.prototype.getPrintFunction=function() { //think about this some more
      // this.id and this.article should already be defined
      if (typeof this.id!=typeof '' || typeof this.article!=typeof'') return;
      var html='';
      var a,t;

      switch (this.id) {
      case 'email':     case 'contribs':  case 'block':     case 'unblock':
      case 'userlog':   case 'blocklog':  case 'userSpace':
        this.article=userName(this.article);
      }

      switch (this.id) {
        case 'blocklog': this.article=popUserNamespace+':'+this.article;
      }

      switch (this.id) {
      case 'userTalk': case 'newUserTalk': case 'editUserTalk':
      case 'userPage':
        delete this.oldid;
        this.article=popUserNamespace+':'+userName(this.article);
      }

      /*
        if (this.id != 'mainlink') {
        this.article=removeAnchor(this.article);
        if (typeof this.text==undef) this.text=popupString(this.id);
        }
      */

      switch (this.id) {
      case 'undelete':       this.print=specialLink; this.specialpage='Undelete'; this.sep='/'; break;
      case 'whatLinksHere':  this.print=specialLink; this.specialpage='Whatlinkshere'; break;
      case 'relatedChanges': this.print=specialLink; this.specialpage='Recentchangeslinked'; break;
      case 'move':           this.print=specialLink; this.specialpage='Movepage'; break;

      case 'contribs':       this.print=specialLink; this.specialpage='Contributions'; break;
      case 'email':          this.print=specialLink; this.specialpage='Emailuser'; break;
      case 'block':          this.print=specialLink; this.specialpage='Blockip'; this.sep='&ip='; break;
      case 'unblock':        this.print=specialLink; this.specialpage='Ipblocklist'; this.sep='&action=unblock&ip='; break;
      case 'userlog':        this.print=specialLink; this.specialpage='Log'; this.sep='&user='; break;
      case 'blocklog':       this.print=specialLink; this.specialpage='Log'; this.sep='&type=block&page='; break;
      case 'userSpace':      this.print=specialLink; this.specialpage='Prefixindex'; this.sep='&namespace=2&from='; break;
      case 'search':         this.print=specialLink; this.specialpage='Search'; this.sep='&fulltext=Search&search='; break;
      case 'history': case 'unwatch': case 'watch':
      case 'unprotect': case 'protect': case 'delete':
        this.print=wikiLink; this.action=this.id; break;

      case 'edit': case 'view':
        this.print=wikiLink;
        delete this.oldid;
        this.action=this.id; break;
      case 'new':
        this.print=wikiLink; this.action='edit&section=new'; break;
      case 'mainlink':
        if (typeof this.text==undef) this.text=safeDecodeURI(this.article);
        if (getValueOf('popupSimplifyMainLink') && isInStrippableNamespace(this.article)) {
          var s=this.text.split('/'); this.text=s[s.length-1];
          if (this.text=='' && s.length > 1) this.text=s[s.length-2];
        }
        this.print=titledWikiLink;
        if (typeof this.title==undef && window.currentLink && typeof window.currentLink.href != undef) {
          this.title=safeDecodeURI((window.currentLink.originalTitle)?window.currentLink.originalTitle:this.article);
          if (typeof this.oldid != undef && this.oldid) this.title='Revision ' + this.oldid + ' of ' + this.title;
        }
        this.action='view'; break;
      case 'userPage':
      case 'article':
        a=articleFromTalkPage(this.article); if (a) { this.article=a; delete this.oldid; }
        this.print=wikiLink;
        this.action='view'; break;
      case 'editArticle':
        a=articleFromTalkPage(this.article); if (a) { this.article=a; delete this.oldid; }
        this.print=wikiLink;
        this.action='edit'; break;
      case 'userTalk':
      case 'talk':
        t=talkPage(this.article); if(t) { this.article=t; delete this.oldid; }
        this.print=wikiLink;
        this.action='view'; break;
      case 'arin':
        this.print=arinLink; break;
      case 'count':
        this.print=kateLink; break;
      case 'globalsearch':
        this.print=globalSearchLink; break;
      case 'lastEdit':
        this.print=titledDiffLink;
        this.title=popupString('Show the last edit');
        this.from='prev'; this.to='cur'; break;
      case 'oldEdit':
        this.print=titledDiffLink;
        this.title=popupString('Show the edit made to get revision') + ' ' + this.oldid;
        this.from='prev'; this.to=this.oldid; break;
      case 'editOld':
        this.print=wikiLink; this.action='edit'; break;
      case 'revert':
        this.print=wikiLink; this.action='revert'; break;
      case 'nullEdit':
        this.print=wikiLink; this.action='nullEdit'; break;
      case 'diffCur':
        this.print=titledDiffLink;
        this.title=tprintf('Show changes since revision %s', [this.oldid]);
        this.from=this.oldid; this.to='cur'; break;
      case 'editUserTalk':
      case 'editTalk':
        t=talkPage(this.article); if (t) { this.article=t; delete this.oldid; }
        this.action='edit'; this.print=wikiLink; break;
      case 'newUserTalk':
      case 'newTalk':
        t=talkPage(this.article); if (t) { this.article=t; delete this.oldid; }
        this.action='edit&section=new'; this.print=wikiLink; break;
      case 'imagestatus':
        this.print=function () { return emptySpanHTML('popupImageStatus', popupIdNumber); }
        break;
      default:
        this.print=function () {return 'Unknown navlink type: '+this.id+''};
      }
    };

    /////////////////
    // DOWNLOADING //
    /////////////////

    //////////////
    //
    // downloader
    //
    //

    var gDownloadsInProgress = { };

    function downloader(url) {
      // Source: http://jibbering.com/2002/4/httprequest.html
      this.http = false;

      /*@cc_on @*/
      /*@if (@_jscript_version >= 5)
      // JScript gives us Conditional compilation,
      // we can cope with old IE versions.
      // and security blocked creation of the objects.
      try {
      this.http = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
      try {
      this.http = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
      // this.http = false;
      }
      }
      @end @*/

      if (! this.http && typeof XMLHttpRequest!='undefined') this.http = new XMLHttpRequest();

      this.url = url; this.id=null;
      this.lastModified = null;
      this.callbackFunction = null;
    };

    new downloader();

    downloader.prototype.send = function (x) {if (!this.http) return null; return this.http.send(x);};
    downloader.prototype.abort = function () {if (!this.http) return null; return this.http.abort();};
    downloader.prototype.runCallback = function () {this.callbackFunction(this);};
    downloader.prototype.getData = function () {if(!this.http) return null; return this.http.responseText;};
    downloader.prototype.setTarget = function () {if(!this.http) return null; this.http.open("GET", this.url, true);};
    downloader.prototype.getReadyState=function () {if(!this.http) return null; return this.http.readyState;};

    downloader.prototype.start=function () {
      if(!this.http) return null;
      gDownloadsInProgress[this.id] = this;
      return this.http.send(null);
    };

    downloader.prototype.getLastModifiedDate=function () {
      if(!this.http) return null;
      var lastmod=null;
      try {
        lastmod=this.http.getResponseHeader('Last-Modified');
      } catch (err) {}
      if (lastmod) return new Date(lastmod);
      return null;
    }

    downloader.prototype.setCallback = function (f) {
      if(!this.http) return;
      this.http.onreadystatechange = f;
      this.callbackFunction = f;
    };

    function newDownload(url, id, callback) {
      var d=new downloader(url);
      if (!d.http) return 'ohdear';
      d.id=id;
      d.setTarget();
      var f = function () {
        if (d.getReadyState() == 4) {
          delete gDownloadsInProgress[this.id];
          d.data=d.getData();
          d.lastModified=d.getLastModifiedDate();
          callback(d);
        }
      };
      d.setCallback(f);
      return d;//d.start();
    };

    function fakeDownload(url, id, callback, data, lastModified) {
      var d=newDownload(url,callback);
      d.id=id; d.data=data;
      d.lastModified=lastModified;
      return callback(d);
    };

    function startDownload(url, id, callback) {
      var d=newDownload(url, id, callback);
      if (typeof d == typeof '' ) return d;
      return d.start();
    };

    function abortAllDownloads() {
      for ( var x in gDownloadsInProgress ) {
        try {
          gDownloadsInProgress[x].aborted=true;
          gDownloadsInProgress[x].abort();
          delete gDownloadsInProgress[x];
        } catch (e) { }
      }
    };

    //
    //
    // downloader
    //
    //////////////

    // Schematic for a getWiki call
    //
    //   getWiki->-getPageWithCaching
    //                    |
    //       false        |          true
    // getPage<-[findPictureInCache]->-onComplete(a fake download)
    //   \.
    //     (async)->addPageToCache(download)->-onComplete(download)

    function getWiki(wikipage, onComplete, oldid) {
      log('getWiki, wikipage='+wikipage);
      // set global variable (ugh) to holdwikipage
      window.currentArticle=wikipage;
      // IE needs a little help here
      // but even this is buggy :-( FIXME FIXME FIXME eg links on [[Pita Pit]]
      if (window.popups_isIE) wikipage=encodeURI(wikipage);
      // set ctype=text/css to get around opera bug
      var url = titlebase + removeAnchor(wikipage) + '&action=raw&ctype=text/css';
      if (oldid!=null && oldid!='') url += '&oldid='+oldid;
      return getPageWithCaching(url, onComplete);
    };

    // check cache to see if page exists

    function getPageWithCaching(url, onComplete) {
      log('getPageWithCaching, url='+url);
      var i=findInPageCache(url);
      if (i > -1) return fakeDownload(url, popupIdNumber, onComplete, gCachedPages[i].data, gCachedPages[i].lastModified);
      return getPage(url, onComplete);
    };

    function getPage(url, onComplete) {
      log('getPage');
      var callback= function (d) { if (!d.aborted) {addPageToCache(d); onComplete(d)} };
      return startDownload(url, popupIdNumber, callback);
    };

    function findInPageCache(url) {
      for (var i=0; i<gCachedPages.length; ++i) if (url==gCachedPages[i].url) return i;
      return -1;
    };

    function cachedPage (url, data, lastModified) {this.url=url; this.data=data; this.lastModified=lastModified};

    function addPageToCache(download) {
      log('addPageToCache '+download.url);
      var page = new cachedPage(download.url, download.data, download.lastModified);
      return gCachedPages.push(page);
    };

    /////////////////////
    // LINK GENERATION //
    /////////////////////

    // titledDiffLink --> titledWikiLink --> generalLink
    // wikiLink       --> titledWikiLink --> generalLink
    // kateLink --> generalLink

    function titledDiffLink(l) { // article, text, title, from, to) {
      return titledWikiLink({article: l.article, action: l.to + '&oldid=' + l.from,
                                        text: l.text, title: l.title,
                                        /* hack: no oldid here */
                                        actionName: 'diff'});
    };

    function wikiLink(l) {
      //{article:article, action:action, text:text, oldid}) {
      if (! (typeof l.article == typeof ''
             && typeof l.action == typeof '' && typeof l.text==typeof '')) return null;
      if (typeof l.oldid == undef) l.oldid=null;
      if (l.action!='edit' && l.action!='view' && l.action != 'revert') l.oldid=null;
      var hint=popupStrings[l.action + 'Hint'];
      switch (l.action) {
      case 'edit&section=new': hint = popupString('newSectionHint');  break;
      case 'revert':
        l.action='edit&autoclick=wpSave&autosummary=' + simplePrintf(getValueOf('popupRevertSummary'), [ l.oldid ]);
        break;
      case 'nullEdit':
        l.action='edit&autoclick=wpSave&autosummary=null';
        break;
      }

      if (hint) {
        if (l.oldid) hint = simplePrintf(hint, [tprintf('revision %s of %s', [l.oldid, safeDecodeURI(l.article)])]);
        else hint = simplePrintf(hint, [safeDecodeURI(l.article)]);
      }
      else hint = safeDecodeURI(l.article + '&action=' + l.action)
             + (l.oldid) ? '&oldid='+l.oldid : '';

      return titledWikiLink({article: l.article, action: l.action, text: l.text,
                                        title: hint, oldid: l.oldid});
    };

    var undef='undefined';
    var defaultNavlinkClassname='popupNavLink';

    function titledWikiLink(l) {
      // possible properties of argument:
      // article, action, text, title, oldid, actionName, className
      // oldid = null is fine here

      // article and action are mandatory args
      if (typeof l.article == undef || typeof l.action==undef) return null;
      if(window.popups_isIE) {
        var v=encodeURI(l.article);
        /*alert(l.article+'\n'+v);*/
        l.article=v;
      }
      l.article=l.article.split('&').join('%26');
      var base = titlebase +  l.article;
      var url=base;

      if (typeof l.actionName==undef || !l.actionName) l.actionName='action';

      // no need to add &action=view, and this confuses anchors
      if (l.action != 'view') url = base + '&' + l.actionName + '=' + l.action;

      if (typeof l.oldid!=undef && l.oldid) url+='&oldid='+l.oldid;

      var cssClass=defaultNavlinkClassname;
      if (typeof l.className!=undef && l.className) cssClass=l.className;

      return generalLink({url: url,
                                 title: (typeof l.title != undef) ? l.title : null,
                                 newWin: getValueOf('popupNewWindows'),
                                 className: cssClass,
                                 text: (typeof l.text!=undef)?l.text:null});
    };

    function specialLink(l) {
      // properties: article, specialpage, text, sep
      if (typeof l.specialpage==undef||!l.specialpage) return null;
      var base = titlebase +  popSpecialNamespace+':'+l.specialpage;
      if (typeof l.sep == undef || l.sep===null) l.sep='&target=';
      var article=l.article;
      if(window.popups_isIE) {
        var v=encodeURI(article);
        article=v;
      }
      var hint=popupStrings[l.specialpage+'Hint'];
      switch (l.specialpage) {
      case 'Log': hint=(l.sep=='&user=') ? popupString('userLogHint') : popupString('blockLogHint'); break;
      case 'Search':  article=safeDecodeURI(article); break;
      }
      if (hint) hint = simplePrintf(hint, [safeDecodeURI(l.article)]);
      else hint = safeDecodeURI(l.specialpage+':'+l.article) ;

      var url = base + l.sep + article;
      return generalLink({url: url, title: hint, text: l.text,
                                 newWin: getValueOf('popupNewWindows'),
                                 className: 'popupNavLink'});
    };

    function generalLink(l) {
      // l.url, l.text, l.title, l.newWin, l.className

      if (typeof l.url==undef) return null;

      // only quotation marks in the url can screw us up now... I think
      var url=l.url.split('"').join('%22');

      var ret='<a href="' + url + '"';
      if (typeof l.title!=undef && l.title) ret += ' title="' + l.title + '"';
      if (typeof l.newWin!=undef && l.newWin) ret += ' target="_blank"';
      if (typeof l.className!=undef&&l.className) ret+=' class="'+l.className+'"';
      ret += '>';
      if (typeof l.text==typeof '') ret+= l.text;
      ret +='</a>';
      return ret;
    }

    function literalizeRegex(str){
      return str.replace(RegExp('([-.()\\+?*^${}\\[\\]])', 'g'), '\\$1');
    };

    function appendParamsToLink(linkstr, params) {
      var sp=linkstr.parenSplit(RegExp('(href="[^"]+?)"', 'i'));
      if (sp.length<2) return null;
      var ret=sp.shift() + sp.shift();
      ret += '&' + params + '"';
      ret += sp.join('');
     return ret;
    };

    function changeLinkTargetLink(x) { // newTarget, text, hint, summary, clickButton, minor) {
      // optional: oldTarget (in wikitext)
      // if x.newTarget omitted or null, remove the link

      // escape '&' and other nasties
      if(x.newTarget) x.newTarget=encodeURI(x.newTarget);
      //x.text=encodeURI(x.text);  // this buggers things up on zh.wikipedia.org and doesn't seem necessary
      x.clickButton=encodeURI(x.clickButton);

      // this'll break if charAt(0) is nasty
      if (typeof x.oldTarget != typeof '') x.oldTarget=decodeURI(window.currentArticle);
      var cA=literalizeRegex(x.oldTarget);
      var chs=cA.charAt(0).toUpperCase();
      chs='['+chs + chs.toLowerCase()+']';
      var currentArticleRegexBit=chs+cA.substring(1);
      currentArticleRegexBit=currentArticleRegexBit
        .split(RegExp('[_ ]+', 'g')).join('[_ ]+')
        .split('\\(').join('(?:%2528|\\()')
        .split('\\)').join('(?:%2529|\\))');
      currentArticleRegexBit = '\\s*(' + currentArticleRegexBit + ')\\s*';
      // e.g. Computer (archaic) -> \s*([Cc]omputer[_ ](?:%2528|\()archaic(?:%2528|\)))\s*

      // autoedit=s~\[\[([Cc]ad)\]\]~[[Computer-aided%20design|$1]]~g;s~\[\[([Cc]AD)[|]~[[Computer-aided%20design|~g

      // get the page to edit from the title
      try {
        //var title=document.getElementsByTagName('h1')[0].innerHTML.replace(RegExp(' ', 'g'), '_');
        var title=document.title.split(' - ');
        title[title.length-1]='';
        title=title.join(' - ').replace(/ - $/, '');
      } catch (err) { return; }

      var lk=titledWikiLink({article: title,
                                        action:  'edit',
                                        text:    x.text,
                                        title:   x.hint
                                        });
      var cmd='';
      if (x.newTarget) {
        cmd +='s~\\[\\['+currentArticleRegexBit+'\\]\\]~[['+x.newTarget+'|$1]]~g;';
        cmd +=  's~\\[\\['+currentArticleRegexBit+'[|]~[['+x.newTarget+'|~g';
      } else {
        cmd += 's~\\[\\['+currentArticleRegexBit+'\\]\\]~$1~g;';
        cmd += 's~\\[\\['+currentArticleRegexBit+'[|](.*?)\\]\\]~$2~g';
      }
      cmd += '&autoclick='+x.clickButton;
      cmd += '&autominor='+x.minor;
      cmd += '&autosummary='+x.summary;
      return appendParamsToLink(lk, 'autoedit='+cmd);
    };

    newOption('popupRedirAutoClick', "'wpSave'");
    function redirLink(redirMatch) {
      /* NB redirMatch is in wikiText */
      var ret='';

      if (getValueOf('popupAppendRedirNavLinks') && getValueOf('popupNavLinks')) {
        ret += '<hr>';
        if (getValueOf('popupFixRedirs') && typeof autoEdit != 'undefined' && autoEdit) {
          ret += addPopupShortcut(
                                  changeLinkTargetLink({newTarget: redirMatch, text: popupString('Redirects'), hint: popupString('Fix this redirect'),
                                                       summary: simplePrintf(getValueOf('popupFixRedirsSummary'),
                                                              [window.currentArticle.split('_').join(' '), redirMatch ]),
                                                       clickButton: getValueOf('popupRedirAutoClick'), minor: true})
                                  , 'R');
          ret += popupString(' to ');
        }
        else ret += popupString('Redirects') + popupString(' to ');

        fillEmptySpans({redir: true, redirTarget: wikiMarkupToAddressFragment(redirMatch)});
        return ret;
      }

      else return '<br> ' + popupString('Redirects') + popupString(' to ') +
             titledWikiLink({article: myEncodeURI(redirMatch), action: 'view',
                            text: safeDecodeURI(redirMatch), title: popupString('Bypass redirect')});
    };

    function arinLink(l) {
      if (typeof l.article != typeof '' || typeof l.text != typeof '') return null;
      if (!isIpUser(userName(l.article)) || ! wikimediaWiki) return null;

      var uN=safeDecodeURI(userName(l.article));

      var newWin='';
      if (getValueOf('popupNewWindows')) newWin=' target="_blank"';

      return generalLink({url:'http://ws.arin.net/cgi-bin/whois.pl?queryinput=' + uN,
                                title: tprintf('Look up %s in ARIN whois database', [uN]),
                                newWin: getValueOf('popupNewWindows'),
                                className: defaultNavlinkClassname,
                                text: l.text});
    };

    function kateLink(l) {
      if (typeof l.article != typeof '' || typeof l.text != typeof '') return null;
      if (isIpUser(userName(l.article)) || ! wikimediaWiki) return null;

      var uN=safeDecodeURI(userName(l.article));

      var newWin='';
      if (getValueOf('popupNewWindows')) newWin=' target="_blank"';

      return generalLink({url:kateBase + uN,
                                title: tprintf('katelinkHint', [uN]),
                                newWin: getValueOf('popupNewWindows'),
                                className: defaultNavlinkClassname,
                                text: l.text});
    };

    function globalSearchLink(l) {
      if (typeof l.article != typeof '' || typeof l.text != typeof '') return null;

      var newWin='';
      if (getValueOf('popupNewWindows')) newWin=' target="_blank"';

      var base='http://vs.aka-online.de/cgi-bin/globalwpsearch.pl?timeout=120&search=';
      var article=safeDecodeURI(l.article);

      return generalLink({url:base + article,
                                title: tprintf('globalSearchHint', [article]),
                                newWin: getValueOf('popupNewWindows'),
                                className: defaultNavlinkClassname,
                                text: l.text});
    }

    ////////////////////////////
    // MANIPULATION FUNCTIONS //
    ////////////////////////////

    function upcaseFirst(str) {
      if (typeof str != typeof '' || str=='') return '';
      return str.charAt(0).toUpperCase() + str.substring(1);
    };

    function formatBytes(num) {return (num > 949) ? (Math.round(num/100)/10+popupString('kB')) : (num +'&nbsp;' + popupString('bytes')) ;};
    function popupFilterStubDetect(data) {return (isStub(data)) ? popupString('stub') : '';};

    function popupFilterDisambigDetect(data) {
      if (!isDisambig(data)) return '';
      // FIXME: this side-effect should live somewhere else
      return popupString('disambig');
    };

    function simplePrintf(str, subs) {
      if (!subs) return str;
      var ret=[];
      var s=str.split('%s');
      var i=0;
      do {
        if (i >= subs.length) { ret.push(s.join('%s')); break; }
        ret.push(s.shift());
        if (s.length == 0) break;
        ret.push(subs[i]);
        ++i;
      } while (s.length > 0);
      return ret.join('');
    }
    function tprintf(str,subs) {
      if (typeof subs != typeof []) { subs = [subs]; }
      return simplePrintf(popupString(str), subs);
    }

    function listLinks(wikitext, oldTarget) {
      var reg=RegExp('\\[\\[([^|]*?)(\\||\\]\\])', 'gi');
      var ret=[];
      var splitted=wikitext.parenSplit(reg);
      // ^[a-z]+ should match interwiki links, hopefully (case-insensitive)
      // and ^[a-z]* should match those and [[:Category...]] style links too
      var omitRegex=RegExp('^[a-z]*:|^[Ss]pecial:|^[Ii]mage|^[Cc]ategory');
      var friendlyCurrentArticleName=window.currentArticle.split('_').join(' ');

      for (var i=1; i<splitted.length; i=i+3) {
        if (typeof splitted[i] == typeof 'string' && splitted[i].length>0 && !omitRegex.test(splitted[i])) {
          ret.push(changeLinkTargetLink({newTarget: splitted[i],
                                        text: splitted[i].split(' ').join('&nbsp;'),
                                        hint: tprintf('disambigHint', [splitted[i]]),
                                        summary: simplePrintf(getValueOf('popupFixDabsSummary'),
                                                              [friendlyCurrentArticleName, splitted[i] ]),
                                        clickButton: 'wpDiff', minor: true, oldTarget: oldTarget}));
        } /* if */
      } /* for loop */

      ret = rmDupesFromSortedList(ret.sort());

      ret.push(changeLinkTargetLink({ newTarget: null,
                                      text: popupString('remove this link').split(' ').join('&nbsp;'),
                                      hint: popupString("remove all links to this disambig page from this article"),
                                      clickButton: "wpDiff", oldTarget: oldTarget,
                                      summary: simplePrintf(getValueOf('popupRmDabLinkSummary'), [friendlyCurrentArticleName])}));
      return ret;

    };

    function rmDupesFromSortedList(list) {
      var ret=[];
      for (var i=0; i<list.length; ++i) {
        if (ret.length==0 || list[i]!=ret[ret.length-1]) ret.push(list[i]);
      }
      return ret;
    };

    function makeFixDab(data, oldTarget) {
      var list=listLinks(data, oldTarget);
      if (list.length==0) return null;
      var html='<hr>' + popupString('Click to disambiguate this link to:') + '<br>';
      html+=list[0];
      for (var i=1; i<list.length; ++i) html += ', '+list[i];
      return html;
    };

    function popupFilterPageSize(data) {return formatBytes(data.length);};
    function popupFilterCountLinks(data) {
      var num=countLinks(data);return String(num) + '&nbsp;' + ((num!=1)?popupString('wikiLinks'):popupString('wikiLink'));
    }

    function popupFilterCountImages(data) {
      var num=countImages(data);return String(num) + '&nbsp;' + ((num!=1)?popupString('images'):popupString('image'));
    }

    function popupFilterCountCategories(data) {
      var num=countCategories(data); return String(num) + '&nbsp;' + ((num!=1)?popupString('categories'):popupString('category'));
    }

    function popupFilterLastModified(data,download) {
      var lastmod=download.lastModified;
      var now=new Date();
      var age=now-lastmod;
      if (lastmod && getValueOf('popupLastModified'))
        return (formatAge(age) + ' ' + popupString('old')).replace(RegExp(' ','g'), '&nbsp;');
      //String(lastmod)
      //      .replace(RegExp('GMT[+-][0-9]+\\s*[(]([A-Z]{1,4})[)]\\s*'), '$1')
      //      .replace(RegExp('^(... ... )0'),'$1')
      //      .replace(' ','&nbsp;');
      return '';
    }

    function formatAge(age) {
      // coerce into a number
      var a=aa=0+age;

      var seclen=1000;
      var minlen=60*seclen;
      var hourlen=60*minlen;
      var daylen=24*hourlen;
      var weeklen=7*daylen;

      var numweeks=(a-a%weeklen)/weeklen; a=a-numweeks*weeklen; var sweeks=addunit(numweeks, 'week');
      var numdays=(a-a%daylen)/daylen;    a=a-numdays*daylen;   var sdays=addunit(numdays, 'day');
      var numhours=(a-a%hourlen)/hourlen; a=a-numhours*hourlen; var shours=addunit(numhours,'hour');
      var nummins=(a-a%minlen)/minlen;    a=a-nummins*minlen;   var smins=addunit(nummins, 'minute');
      var numsecs=(a-a%seclen)/seclen;    a=a-numsecs*seclen;   var ssecs=addunit(numsecs, 'second');

      //alert( [numdays,numhours,nummins,numsecs].join(':') );

      if (aa > 4*weeklen) return sweeks;
      if (aa > weeklen) return sweeks + ' ' + sdays;
      if (aa > daylen) return sdays + ' ' + shours;
      if (aa > 6*hourlen) return shours;
      if (aa > hourlen) return shours + ' ' + smins;
      if (aa > 10*minlen) return smins;
      if (aa > minlen) return smins + ' ' + ssecs;
      return ssecs;
    }

    function addunit(num,str) {
      return '' + num + ' ' + ((num!=1) ? popupString(str+'s') : popupString(str)) ;}

    var popupFilters=[popupFilterStubDetect,popupFilterDisambigDetect,popupFilterPageSize,popupFilterCountLinks,
                      popupFilterCountImages,popupFilterCountCategories,popupFilterLastModified];

    if (typeof extraPopupFilters=='undefined') { var extraPopupFilters=new Array(); }

    function getPageInfo(data, download) {
      if (!data || data.length == 0) return popupString('Empty page');

      var pageInfoArray=new Array();
      var i,s;
      for (i=0; i<     popupFilters.length; ++i) {s=     popupFilters[i](data,download);if (s!='') pageInfoArray.push(s);}
      for (i=0; i<extraPopupFilters.length; ++i) {s=extraPopupFilters[i](data,download);if (s!='') pageInfoArray.push(s);}

      var pageInfo=pageInfoArray.join(', ');
      if (pageInfo != '' ) pageInfo = upcaseFirst(pageInfo);
      return pageInfo;
    };

    function getValidImageFromWikiText(wikiText) {
      var imagePage=null;
      // nb in imageRegex we're interested in the second bracketed expression
      // this may change if the regex changes :-(
      //var match=imageRegex.exec(wikiText);
      var matched=null;
      var match;
      defaultize('popupMinImageWidth');
      while ( match = imageRegex.exec(wikiText) ) {
        /* now find a sane image name - exclude templates by seeking { */
        var m = match[2];
        var pxWidth=match[4];
        if ( isValidImageName(m) && (!pxWidth || parseInt(pxWidth) >= popupMinImageWidth) ) {
          matched=m;
          break;
        }
      }
      imageRegex.lastIndex=0;
      if (!matched) return null;
      return popImageNamespace+':'+upcaseFirst(matched);
    };

    // this could be improved!
    function countLinks(wikiText) { return wikiText.split('[[').length - 1; };

    // if N = # matches, n = # brackets, then
    // String.parenSplit(regex) intersperses the N+1 split elements
    // with Nn other elements. So total length is
    // L= N+1 + Nn = N(n+1)+1. So N=(L-1)/(n+1).

    function countImages(wikiText) {return (wikiText.parenSplit(imageRegex).length - 1) / (imageRegexBracketCount + 1);};

    function countCategories(wikiText) {return (wikiText.parenSplit(categoryRegex).length - 1) / (categoryRegexBracketCount + 1); };

    // returns /^(Talk|User[_ ]talk|Wikipedia[_ ]talk|...):$/
    function namespaceListToRegex(list) {return RegExp('^('+list.join('|').split(' ').join('[ _]')+'):');};

    function talkPage(article) { // convert article to a talk page, or if we can't return null
      if (article===null) return null;
      var talkRegex=namespaceListToRegex(popTalkNamespaces);
      if (talkRegex.exec(article)) {return null;}

      var nsRegex=namespaceListToRegex(popNamespacesWithTalk);
      var splitted=article.parenSplit(nsRegex);
      if (splitted.length<2) return (popTalkNamespaces[0]+':'+article).split(' ').join('_');
      for (var i=0; i< popNamespacesWithTalk.length; ++i) {
        if (splitted[1]==popNamespacesWithTalk[i]) {
          splitted[1]=popTalkNamespaces[i];
          return splitted.join(':').substring(1).split(' ').join('_');
        }
      }
      return null;
    };

    function articleFromTalkPage(talkpage) {
      var talkRegex=namespaceListToRegex(popTalkNamespaces);
      var splitted=talkpage.parenSplit(talkRegex);
      if (splitted.length < 2 || splitted[0].length > 0) return null;
      if (splitted[1]==popTalkNamespaces[0]) {
        splitted[1]=''; return splitted.join(':').substring(2).split(' ').join('_');
      }
      for (var i=1; i< popTalkNamespaces.length; ++i) {
        if (splitted[1]==popTalkNamespaces[i]
            || splitted[1]==popTalkNamespaces[i].split(' ').join('_')) {
          splitted[1]=popNamespacesWithTalk[i];
          return splitted.join(':').substring(1).split(' ').join('_');
        }
      }
      return null;
    };

    function userName(article) {
      var i=article.indexOf(popUserNamespace);
      var j=article.indexOf(':');
      if  (i != 0 || j == -1) return null;
      var k=article.indexOf('/');
      if (k==-1) return article.substring(j+1);
      else return article.substring(j+1,k);
    };

    function stripNamespace(article) {
      // this isn't very sophisticated
      // it just removes everything up to the final :
      // BUG: probably does silly things for images with colons in the name - check it out
      var list = article.split(':');
      return list[list.length-1];
    };

    // those odd a/a5/ bits of image urls
    function imagePathComponent(article) {
      var stripped=stripNamespace(article);
      var forhash=safeDecodeURI(stripped).split(' ').join('_');
      var hash=md5_hex(forhash);
      return hash.substring(0,1) + '/' + hash.substring(0,2) + '/';
    };

    function getImageUrlStart(wiki) { // this returns a trailing slash
      switch (wiki) {
        case 'en.wikipedia.org':  return 'http://upload.wikimedia.org/wikipedia/en/';
        case commonsWiki:         return 'http://upload.wikimedia.org/wikipedia/commons/';
        case 'en.wiktionary.org': return 'http://en.wiktionary.org/upload/en/';
        default: // unsupported - take a guess
          if (wikimediaWiki) {
            var lang=wiki.split('.')[0];
            return 'http://upload.wikimedia.org/wikipedia/' + lang +'/';
          }
          else /* this should work for wikicities */
            return 'http://' + wiki + '/images/';
      }
    };

    function imageURL(img, wiki) {
      if (getValueOf('popupImagesFromThisWikiOnly') && wiki != thisWiki) return null;
      var imgurl=null;
      if (isImage(img)) {
        var pathcpt = imagePathComponent(img);
        var stripped=stripNamespace(img);
        imgurl=getImageUrlStart(wiki) + pathcpt + stripped;
      }
      return imgurl;
    };

    function imageThumbURL(img, wiki, width) {
      //
      // eg http://upload.wikimedia.org/wikipedia/en/thumb/6/61/
      //           Rubiks_cube_solved.jpg/120px-Rubiks_cube_solved.jpg
      //           ^^^^^^^^^^^^^^^^^^^^^^^
      //          wikicities omits this bit
      //  AND wikicities needs a new pathcpt for each filename including thumbs

      if (getValueOf('popupImagesFromThisWikiOnly') && wiki != thisWiki) return null;
      if (getValueOf('popupNeverGetThumbs')) return null;

      var imgurl=null;
      if (isImage(img)) {
        var stripped=stripNamespace(img);
        var pathcpt;
        if (wikimediaWiki) pathcpt = imagePathComponent(stripped);
        else pathcpt = imagePathComponent(width+'px-'+stripped);
        imgurl=getImageUrlStart(wiki) +  "thumb/" + pathcpt;
        if (wikimediaWiki) imgurl += stripped + '/';
        imgurl += width +"px-" + stripped;
      }
      return imgurl;
    };

    // (a) myDecodeURI (first standard decodeURI, then exceptions)
    // (b) change spaces to underscores
    // (c) encodeURI (just the straight one, no exceptions)

    function wikiMarkupToAddressFragment (str) { // for images
      var ret = safeDecodeURI(str);
      ret = ret.split(' ').join('_');
      ret = encodeURI(ret);
      return ret;
    };

    function addressFragmentToWikiMarkup (str) {
      // seemingly, not :( the inverse of wikiMarkupToAddressFragment
      return safeDecodeURI(str);
    };

    function myDecodeURI (str) {
      // log('myDecodeURI, str=' + str);
      var ret;
      try { ret=decodeURI(str); }
      catch (summat) { return null; }
      for (var i=0; i<decodeExtras.length; ++i) {
        var from=decodeExtras[i].from;
        var to=decodeExtras[i].to;
        ret=ret.split(from).join(to);
      }
      return ret;
    };

    function safeDecodeURI(str) {
      var ret=myDecodeURI(str); return ret || str;
    };

    function myEncodeURI (str) {
      log ('myEncodeURI: str='+str);
      var ret=str;
      ret=encodeURI(ret);
      for (var i=0; i<decodeExtras.length; ++i) {
        var from=decodeExtras[i].from;
        var to=decodeExtras[i].to;
        ret=ret.split(to).join(from);
      }
      return ret;
    };

    function removeAnchor(article) {
      // is there a #? if not, we're done
      var i=article.indexOf('#');
      if (i == -1) return article;
      return article.substring(0,i);
    };

    ///////////
    // TESTS //
    ///////////

    function isStub(data) { return stubRegex.test(data); };
    function isDisambig(data) { return talkPage(window.currentArticle) && disambigRegex.test(data); };

    function isValidImageName(str){ // extend as needed...
      return ( str.indexOf('{') == -1 );
    };

    function isInNamespaceOrTalk(article, namespace) {
      if (isInNamespace(article, namespace)) return true;
      // FIXME: internationalize this
      if  (article.indexOf(namespace+'_talk:') == 0) return true;
      return false;
    };

    function isInNamespace(article, namespace) {
      var list=namespace;
      if (typeof list == typeof '') list=[list];
      for (var i=0; i<list.length; ++i) {
        if (article.indexOf(list[i]+':')==0) return true;
        // should also respect namespaces encoded with wikiMarkupToAddressFragment
        if (article.indexOf(wikiMarkupToAddressFragment(list[i]+':'))==0) return true;
      }
      return false;
    };

    function isInStrippableNamespace(article) {
      return isInNamespace(article, popNonArticleNamespaces);
    };

    function isImage(thing) {return isInNamespaceOrTalk(thing, popImageNamespace);};

    function isImageOk(img)
    {
      // IE test
      if (!img.complete)
        return false;

      // gecko test
      if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0)
        return false;

      // test for konqueror and opera

      // note that img.width must not be defined in the html with a width="..."
      // for this to work.

      // konq seems to give "broken images" width 16, presumably an icon width
      // this test would probably work in gecko too, *except for very small images*
      if (typeof img.width == 'undefined' || img.width <=  16) return false;

      // No other way of checking: assume it's ok.
      return true;
    };

    function anchorContainsImage(a) {
      // iterate over children of anchor a
      // see if any are images
      if (a===null) return false;
      kids=a.childNodes;
      for (var i=0; i<kids.length; ++i) if (kids[i].nodeName=='IMG') return true;
      return false;
    };

    /////////////
    // ACTIONS //
    /////////////

    var imageCache = new Array ();

    function loadThisImage(image) {
      if (getValueOf('popupLoadImagesSequentially')) return sequentialLoadThisImage(image);
      else return parallelLoadThisImage(image);
    };

    function getImageUrls(image) {
      var imageUrls=new Array();
      for (var i=0; i<imageSources.length; ++i) {
        var url;
        if (imageSources[i].thumb)
          url=imageThumbURL(image, imageSources[i].wiki, imageSources[i].width);
        else
          url=imageURL(image, imageSources[i].wiki);
        for (var j=0; j<gImageCache.length; ++j) {
          if (url == gImageCache[j]) {
            loadThisImageAtThisUrl(image, url);
            return null;
          }
        }
        if (url!=null) imageUrls.push(url);
      }
      return imageUrls;
    };

    // this is probably very wasteful indeed of bandwidth
    // hey ho

    function parallelLoadThisImage (image) {
      if (!popupImages) return;
      if (!isValidImageName(image)) return false;

      var imageUrls=getImageUrls(image);
      if (!imageUrls) return null;

      for (var i=0; i<imageUrls.length; ++i) {
        var url = imageUrls[i];
        imageArray[i]=new Image();
        imageArray[i].src=url;
      }
      if (popupImageTimer != null) {
        clearInterval(popupImageTimer);
        counter=0;
      }
      gImage=image;
      popupImageTimer=setInterval("checkImages()", 250);
      return true;
    };

    function nextOne (array, value) {
      // NB if the array has two consecutive entries equal
      //    then this will loop on successive calls
      if (typeof array.length == 'undefined') return null;
      for (var i=0; i<array.length-1; ++i) {
        if (array[i]==value) return array[i+1];
      }
      return null;
    };

    function findThis(array, value) {
      if (typeof array.length == 'undefined') return null;
      for (var i=0; i<array.length; ++i) {
        if (array[i]==value) return i;
      }
      return null;
    };

    // global array for 404'ed image urls
    var gBadImageUrls=[];

    function sequentialLoadThisImage (image) {
      if (!popupImages) return false;
      if (!isValidImageName(image)) return false;

      var imageUrls=getImageUrls(image);
      if (!imageUrls) return null;

      var img=new Image();
      img.isNew=true;
      img.popupIdNumber=popupIdNumber;
      img.counter=1;

      img.onload = function () {
        // clear status thingy
        setImageStatus('');

        var i=findThis(imageUrls, this.src);
        var goodSrc=this.src;

        var setPopupImage=function () {
          var popupImage=document.getElementById("popupImage"+this.popupIdNumber);
          if (popupImage && typeof popupImage.src != 'undefined') {
            clearInterval(popupImageTimer);
            popupImage.src=goodSrc;
            popupImage.width=popupImageSize;
            popupImage.style.display='inline';
            setPopupImageLink(image, imageSources[i].wiki);
            return true;
          } else return false;
        };
        popupImageTimer=setInterval(setPopupImage, 250);
        gImageCache.push(goodSrc);
      };

      img.onerror = function () {
        gBadImageUrls.push(this.src);
        // if the popup is visible, move on
        if (over && over.style.visibility=='visible' && this.popupIdNumber==popupIdNumber) this.setNext();
      };

      img.setNext = function () {
        var currentSrc=null;
        var newSrc;
        if (!this.isNew) currentSrc=this.src;
        this.isNew=false;

        newSrc= (currentSrc) ? nextOne(imageUrls, currentSrc) : imageUrls[0];

        while (findThis(gBadImageUrls, newSrc))  {
          newSrc=nextOne(imageUrls, newSrc);
          if (!newSrc) {
            setImageStatus (' :-(');
            return;
          }
        }
        setImageStatus(' '+findThis(imageUrls, newSrc));
        this.src=newSrc;
      }

      // start the ball rolling
      img.setNext();

    };

    function loadThisImageAtThisUrl(image, url) {
      log('loading "best" image:\n'+url);
      gImage=image;
      imageArray = new Array();
      imageArray[0] = new Image();
      imageArray[0].src=url;
      if (popupImageTimer != null) {
        clearInterval(popupImageTimer);
        counter=0;
      }
      popupImageTimer=setInterval("checkImages()", 250);
      return;
    };

    function loadImages(article) {if(! isImage(article) ) return null; return loadThisImage(article);};

    // this has to use a timer loop as we don't know if the DOM element exists when we want to set the text
    function setPopupHTML (str, elementId, popupId, onSuccess) {
      log('setPopupHTML, str='+str.substring(0,100)+'..., \n elementId='+elementId+', popupId='+popupId);
      if (typeof popupId === 'undefined') popupId = popupIdNumber;
      var popupElement=document.getElementById(elementId+popupId);
      var timer;

      if (typeof popupHTMLTimers[elementId] == 'undefined') timer=null;
      else timer=popupHTMLTimers[elementId];

      if (popupElement != null) {
        if(timer) clearInterval(timer);
        popupHTMLTimers[elementId]=null;
        popupElement.innerHTML=str;
        if (onSuccess) onSuccess();
        return true;
      } else {
        // call this function again in a little while...
        var loopFunction=function() { setPopupHTML(str,elementId,popupId,onSuccess);}
        popupHTMLLoopFunctions[elementId] = loopFunction;
        if (!timer) {
          var doThis = 'popupHTMLLoopFunctions["'+elementId+'"]()';
          popupHTMLTimers[elementId] = setInterval(doThis, 600);
        }
      }
      return null;
    };

    function setImageStatus(str, id) {return setPopupHTML(str, 'popupImageStatus', id);};
    function setPopupTrailer(str,id) {return setPopupHTML(str, 'popupData', id);};

    // methinks this is unbelievably silly
    // it dovetails with the parallel image loader function
    function checkImages() {
      log('checkImages: loopcounter='+loopcounter+'; counter='+counter);
      if (checkImagesTimer!=null) {
        clearInterval(checkImagesTimer);
        checkImagesTimer=null;
        if (loopcounter > 10); {loopcounter=0; log('too many iterations of checkImages'); return;}
        loopcounter++;
      } else counter++;

      var status =  ( counter % 2 ) ? ':' : '.' ;
      setImageStatus(status);

      if (counter > 100) {counter = 0; log ('counter too big in checkImages; returning'); clearInterval(popupImageTimer);}

      var popupImage=null;
      popupImage=document.getElementById("popupImg"+popupIdNumber);
      if (popupImage == null) {
        // this doesn't seem to happen any more in practise for some reason
        // still, I'll leave it in
        log('checkImages: document.getElementById("popupImg'+popupIdNumber+'") is null! retrying in 333ms...');
        checkImagesTimer=setInterval("checkImages()",333);
        return;
      }

      log('checkImages: found element popupImg'+popupIdNumber+', and src='+popupImage.src);

      // get the first image to successfully load
      // and put it in the popupImage
      for(var i = 0; i < imageArray.length; ++i) {
        if(isImageOk(imageArray[i])) {
          // stop all the gubbins, assign the image and return

          log('checkImages: got at pos '+i+', src='+imageArray[i].src);
          clearInterval(popupImageTimer);

          if(isImage(gImage)) {
            popupImage.src=imageArray[i].src;
            popupImage.width=popupImageSize;
            popupImage.style.display='inline';
            // should we check to see if it's already there? maybe...
            gImageCache.push(imageArray[i].src);

            setPopupImageLink(gImage, imageSources[i].wiki);
            stopImagesDownloading();
          }

          setImageStatus('');

          // reset evil nonconstant globals
          delete imageArray; imageArray=new Array();
          popupImageTimer=null;

          counter=0;
          loopcounter=0;

          return popupImage.src;
        }
      }
      log('checkImages: no good image found. retrying in a tic...');
      checkImagesTimer=setInterval("checkImages()",333);
    };

    function stopImagesDownloading() {
      gImage=null;
      if (imageArray == null) return null;
      var i;
      for (i=0; i<imageArray.length; ++i) {
        //imageArray[i].src=''; // this is a REALLY BAD IDEA
        delete imageArray[i];
        //imageArray[i] = new Image();
      }
      imageArray = new Array ();
      return i;
    };

    function toggleSize() {
      var imgContainer=this;
      if (!imgContainer) { alert('imgContainer is null :/'); return;}
      img=imgContainer.firstChild;
      if (!img) { alert('img is null :/'); return;}
      if (!img.style.width || img.style.width=='') img.style.width='100%';
      else img.style.width=''; // popupImageSize+'px';
    };

    function setPopupImageLink (img, wiki) {
      if( wiki === null || img === null ) return null;

      var a=document.getElementById("popupImageLink"+popupIdNumber);
      if (a === null) return null;

      var linkURL = imageURL(img, wiki);
      if (linkURL != null) {
        if (getValueOf('popupImagesToggleSize')) { a.onclick=toggleSize; a.title=popupString('Toggle image size'); }
        else { a.href=linkURL; a.title=popupString('Open full-size image'); }
      }
      return linkURL;
    };

    var ranSetupTooltipsAlready=false;

    function setupTooltips() {
      if (ranSetupTooltipsAlready) return;
      ranSetupTooltipsAlready=true;

      var anchors;

      // article/content is a structure-dependent thing
      if (getValueOf('popupOnlyArticleLinks'))
        anchors=( document.getElementById('article') ||
                  document.getElementById('content')   ).getElementsByTagName('A');
      else
        anchors=document.getElementsByTagName('A');

      for (var i=0; i<anchors.length; ++i) {
        var a=anchors[i];
        if (a.onclick) continue;
        var h=a.href;
        if (
            ( (re.test(h)  && !exceptions.test(h))
              ||
              (contributions.test(h) && h.indexOf('&limit=') == -1 )
            )
            && (! isInToc(a))
           ) {
          a.onmouseover=mouseOverWikiLink;
          a.onmouseout= mouseOutWikiLink;
          a.onclick= killPopup;
          if (getValueOf('removeTitles') && typeof a.originalTitle=='undefined') {
            a.originalTitle=a.title;
            a.title='';
          }
        }
      }
    };

    //////////////
    // THINGIES //
    //////////////

    // How the URLs for images in the popup come about

    //   loadPreviewImage
    //          |
    //       getWiki
    //          |<----------------see other schematic for details
    //    insertPreviewImage      (insertPreviewImage = onComplete)
    //          |
    //          |            insertPreviewImage gets a wikiText fragment from
    //          |                       the wikiText downloaded by getWiki
    //          |
    //  [wikiMarkupToAddressFragment]
    //       |
    //       |                     mouseOverWikiLink  (gets an "address fragment",
    //       |                            |            no processing needed)
    //       \->-loadThisImage---<----loadImages
    //                 |
    //           [image(Thumb)URL]-->--hopefully valid image urls

    window.currentLink=null;

    function popupHandleKeypress(evt) {
      var keyCode = evt.keyCode ? evt.keyCode :
        evt.charCode ? evt.charCode : evt.which;
      if (!keyCode || !over) return;
      if (keyCode==27) { // escape
        killPopup();
        return;
      }

      var letter=String.fromCharCode(keyCode);
      var links=over.getElementsByTagName('A');
      var startLink=0;
      var i,j;

      if (window.lastPopupLinkSelected) {
        for (i=0; i<links.length; ++i) {
          if (links[i]==window.lastPopupLinkSelected) startLink=i;
        }
      }
      for (j=0; j<links.length; ++j) {
        i=(startLink + j + 1) % links.length;
        if (links[i].getAttribute('popupkey')==letter) {
          if (evt.preventDefault) evt.preventDefault();
          links[i].focus();
          window.lastPopupLinkSelected=links[i];
          break;
        }
      }
    };

    function addPopupShortcuts() {
      if (document.onkeypress==popupHandleKeypress) return;
      document.oldPopupOnkeypress=document.onkeypress;
      document.onkeypress=popupHandleKeypress;
    };

    function rmPopupShortcuts() {
      try {
        if (String(document.oldPopupOnkeypress)==String(popupHandleKeypress)) {
          // panic
          document.onkeypress=function () {};
          return;
        }
        document.onkeypress=document.oldPopupOnkeypress;
      } catch (nasties) { /* IE goes here */ }
    };

    // add CSS class to table

    function addPopupStylesheetClasses () {
      var tables=over.getElementsByTagName('table');
      tables[0].className='popupBorderTable';
      tables[1].className='popupTable';
      var fonts=over.getElementsByTagName('font');
      fonts[0].className='popupFont';
      fonts[0].id='overFontWrapper';
    };

    var alreadyRegisteredHooks=false;

    function registerHooks() {
      if (window.alreadyRegisteredHooks) return;
      window.alreadyRegisteredHooks=true;

      defaultize('popupMaxWidth');

      if (typeof popupMaxWidth == 'number') {
        window.setmaxwidth = function () {
          over.style.maxWidth = popupMaxWidth+'px';

          // hack for IE
          // see http://www.svendtofte.com/code/max_width_in_ie/
          // who knows if this will work? not me.
          // use setExpression as documented here on msdn: http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/setexpression.asp

          // this seems to be the source of that error.... grr.....
          if (over.style.setExpression) {
            over.style.setExpression('width',
                                     'document.body.clientWidth > '
                                     + popupMaxWidth + ' ? "'
                                     + popupMaxWidth + 'px": "auto"');
          }
        };
        registerHook("createPopup", window.setmaxwidth, FAFTER);
      }

      registerHook('createPopup', window.fillEmptySpans, FAFTER);

      if (getValueOf('popupShortcutKeys')) {
        registerHook("createPopup", window.addPopupShortcuts, FAFTER);
        registerHook("hideObject", window.rmPopupShortcuts, FAFTER);
      }

      if (getValueOf('popupDragging'))
        registerHook("createPopup", window.makeOverDraggable, FAFTER);

      registerHook("createPopup", window.addPopupStylesheetClasses, FAFTER);
    };

    function makeOverDraggable() {
      if (typeof over == undef || !over) return null;
      if (typeof over.draggable != undef && over.draggable) return null;
      Drag.originalEnd=Drag.end;
      Drag.end=function(e) { Drag.originalEnd(); olMouseMove(e); return false; }
      Drag.originalStart=Drag.start;
      Drag.start=function (e) { try { if (!e.shiftKey) return; }
                                catch (err) { return; }
                                Drag.originalStart.apply(this, [e]);
                                return false; }
      Drag.init(over);
    };

    function mouseOverWikiLink() {
      return mouseOverWikiLink2(this);
    };

    function mouseOverWikiLink2(a) {
      // FIXME: should not generate the HTML until the delay has elapsed,
      //        and then popup immediately. Can be a CPU hog otherwise.

      log('mouseOverWikiLink: a='+a+', window.currentLink='+window.currentLink);

      // try not to duplicate effort
      if (a==window.currentLink) return;
      window.currentLink=a;

      if (typeof over != undef && over != null
          && typeof over.dragging != undef && over.dragging) return;

      // increment global counter now
      popupIdNumber++;

      if (getValueOf('simplePopups') && window.popupStructure===null) {
        // reset *default value* of popupStructure
        log ('simplePopups is true and no popupStructure selected. Defaulting to "original"');
        newOption('popupStructure', "'original'");
      }

      var html = popupHTML(a);
      var article=articleFromAnchor(a);
      var oldid=oldidFromAnchor(a);

      if (popupImageTimer != null) {
        clearInterval(popupImageTimer);
        counter=0;
      }

      // keep this (or fix other refs)
      defaultize('popupImages');

      log('running overlib now');

      registerHooks();

      defaultize('popupInitialWidth');
      if (typeof popupInitialWidth == typeof 0) {
        overlib(html, STICKY, WIDTH, popupInitialWidth,
                CELLPAD, 5, OFFSETX, 2, OFFSETY, 2,
                DELAY, getValueOf('popupDelay')*1000);
      } else {
        overlib(html, STICKY, WRAP,
                CELLPAD, 5, OFFSETX, 2, OFFSETY, 2,
                DELAY, getValueOf('popupDelay')*1000);
      }

      if (typeof window.checkPopupPosition==typeof 1) clearInterval(window.checkPopupPosition);
      checkPopupPositionTimer=setInterval(checkPopupPosition, 600);

      if (getValueOf('popupLiveOptions')) {
        setPopupHTML(popupLiveOptionsHTML(), 'popupLiveOptions', popupIdNumber,
                     function () { popupToggleShowOptions(true); } );
      }

      if(getValueOf('simplePopups')) return;

      // dunno what this is doing here
      // FIXME: what is going on?
      // We're creating a closure with all our data in it because... we're lazy
      // this is a bad idea
      window.popupUnsimplify = function () {
        var previewImage=true;

        gImage=null;

        if (isImage(article) && ( getValueOf('imagePopupsForImages') || ! anchorContainsImage(a) )) {
          loadImages(article);
        }
        else if (!isImage(article) && previewImage) {
          redirCount=0;
          loadPreviewImage(article, oldid);
        }

        var s=document.getElementById('popupUnsimplify' + popupIdNumber);
        if (s && s.style) {
          s.style.display='none';
        }

      };

      if (getValueOf('popupUnsimplifyLink')) return;

      window.popupUnsimplify();

    }

    function loadPreviewImage(article, oldid) {return getWiki(article, insertPreviewImage, oldid);};

    function loadPreviewImageFromRedir(redirPage, redirMatch) {
      /* redirMatch is a regex match */
      log('loadPreviewImageFromRedir, redirCount='+redirCount);
      var target = redirMatch[1];
      var trailingRubbish=redirMatch[3];
      window.redirCount=window.redirCount+1;
      var warnRedir = redirLink(target);

      setPopupHTML(warnRedir, 'popupWarnRedir');

      if (!window.popups_isIE) target=myEncodeURI(target);
      return loadPreviewImage(target);
    };

    // header...!___ -> ...
    function extractChunk(str, header, breakChar) {
      if (str.indexOf(header) != 0) return null;
      if (!breakChar) return str.substring(header.length);
      var findChar=str.indexOf(breakChar);
      if (findChar==-1) return str.substring(header.length);
      return str.substring(header.length, findChar);
    };

    function urlToWikiPage (url) {
      log ('urlToWikiPage\nurl='+url);
      var urlFragment=null;
      if (!urlFragment) urlFragment=extractChunk(url, titlebase, '&');
      if (!urlFragment) urlFragment=extractChunk(url, wikibase, '?');
      if (!urlFragment) return null;
      return addressFragmentToWikiMarkup(urlFragment);
    };

    function makeFixDabs(wikiText, oldTarget)
    {
      if (getValueOf('popupFixDabs') && isDisambig(wikiText) &&
          location.href.indexOf(popSpecialNamespace+':') == -1 &&
          talkPage(window.currentArticle)
          )
        setPopupHTML(makeFixDab(wikiText, oldTarget), 'popupFixDab', popupIdNumber);
    }

    function insertPreviewImage(download) {
      log('insertPreviewImage, redirCount='+redirCount);
      if (download.id != popupIdNumber) {
        log ('insertPreviewImage: download.id='+download.id+' but popupIdNumber='+popupIdNumber+'. Bailing...');
        return;
      }
      var wikiText=download.data;
      var redirectRegex=RegExp('^[ \\n]*[#]redirect[:\\s]*\\[{2}([^\\|\\]]*)(|[^\\]]*)?\\]{2}\\s*(.*)', 'i');
      var redirMatch = redirectRegex.exec(wikiText);

      var art=window.currentArticle;

      if (redirCount==0 && redirMatch) {
        window.currentRedirectionSource=window.currentArticle;
        loadPreviewImageFromRedir(urlToWikiPage(download.url), redirMatch);
        return;
      }

      var redirSource=window.currentRedirectionSource||'';

      if (redirCount==0) makeFixDabs(wikiText); // not a redir, so we don't have to specify an oldTarget
      else makeFixDabs(wikiText, redirSource);

      window.currentRedirectionSource=null;
      redirCount=0;

      if (getValueOf('popupSummaryData')) {
        var pgInfo=getPageInfo(wikiText, download);
        setPopupTrailer('<br>' + pgInfo);
      }

      var imagePage=getValidImageFromWikiText(wikiText);
      if(imagePage) {
        // loadThisImage expects an "address fragment"
        imagePage = wikiMarkupToAddressFragment(imagePage);
        defaultize('popupLoadImagesSequentially');
        loadThisImage(imagePage);
      }

      if (getValueOf('popupPreviews')) {
        if (download && typeof download.data == typeof ''){
          if (isInNamespace(window.currentArticle, 'Template') && getValueOf('popupPreviewRawTemplates')) {
            var h='<hr><tt>'
              +download.data
              .split("&").join("&amp;")
              .split("<").join("&lt;")
              .split(">").join("&gt;")
              .split('\\n').join('<br>\\n')
              +'</tt>';
            setPopupHTML(h, 'popupPreview');
          }
          else {
            var p=new previewMaker(download.data.substring(0,10000));
            p.showPreview();
          }

        }
      }
    };

    var localTest=false;

    function previewMaker(wikiText) {this.data=wikiText;}
    previewMaker.prototype.killComments = function () {
      this.data=this.data.replace(RegExp('<!--(\\n|.)*?-->', 'g'), '');
    };
    previewMaker.prototype.killDivs=function () {
      // say goodbye, divs (can be nested, so use * not *?)
      this.data=this.data.replace(RegExp('< *div[^>]* *>[\\s\\S]*< */ *div *>',
                               'gi'), '');
    };
    previewMaker.prototype.killGalleries=function () {
      this.data=this.data.replace(RegExp('< *gallery[^>]* *>[\\s\\S]*?< */ *gallery *>',
                               'gi'), '');
    };
    previewMaker.prototype.killBoxTemplates=function () {
      // taxobox hack... in fact, there's a saudiprincebox_begin, so let's be more general
      this.data=this.data.replace(RegExp('[{][{][^}\\s|]*box[ _](begin|start)' +
                               '[\\s\\S]*?[^{\\s|]*box[ _](end|finish) *[}][}]', 'gi'), '');

      // infoboxes
      this.data=this.data.replace(RegExp('[{][{][^}\\s|]*infobox[ _][\\s\\S]*?[}][}]',
                                         'gi'), '');

      // also, have float_begin, ... float_end
      this.data=this.data.replace(RegExp('[{][{][^}\\s|]*float[ _]begin' +
                               '[\\s\\S]*?[^{\\s|]*float[ _]end.*?[}][}]',
                               'gi'), '');

      // from [[User:Zyxw/popups.js]]: kill frames too
      this.data=this.data.replace(RegExp('[{][{][^}\\s|]*[_ ]frame' +
                                         '[\\s\\S]*?[^{\\s|]*[_ ]?end[_ ]+frame[}][}]', 'gi'), '');
    };
    previewMaker.prototype.killTemplates = function () {
      this.data=this.data.replace(RegExp('[{][{]([{][{][^}]*[}][}]|[^{}])*[}][}]', 'g'), ' ');
    };
    previewMaker.prototype.killTables=function () {
      // tables are bad, too
      this.data=this.data.replace
      (RegExp('[{]\\|([{][|]([^\\|]|\\|[^}])*[|][}]|[^\\|]|\\|[^}])*\\|[}]', 'g')
       , '');
      // remove lines starting with a pipe
      this.data=this.data.replace(RegExp('^[|].*$', 'mg'), '');
    };
    previewMaker.prototype.killImages=function () {
      // images are a nono
      // who says regexes aren't fun?
      // i think we should match:
      // [[image: ...... ]] where ....... consists of repetitions of any of:
      // 1. not [ or ]
      // 2. [[ (not ])* ]]
      // 3. [ (not ])* ]
      var imagedetector =
      '[[][[]\\s*('+
        popImageNamespace + '|' + popCategoryNamespace+
      ')\\s*:([^\\[\\]]|\\[\\[[^\\]]*\\]\\]|\\[[^\\]]*\\])*\\]\\]';
      var crudeImageRegex = RegExp(imagedetector, 'gi');
      this.data=this.data.replace(crudeImageRegex, '');
    };
    previewMaker.prototype.killHTML=function () {
      // kill html tables // this doesn't cope with embedded tables
      // may this is good enough?
      this.data=this.data.replace(RegExp('<table.*?>(.|\\n.)*?\\n?</ *table *>\\n+', 'gi'), '');

      // let's also delete entire lines starting with <. it's worth a try.
      this.data=this.data.replace(RegExp('(^|\\n) *<.*', 'g'), '\n');

      // and those pesky html tags
      this.data=this.data.replace(RegExp('<.*?>','g'),'');
    };
    previewMaker.prototype.killChunks=function() { // heuristics alert
      // chunks of italic text? you crazy, man?
      var italicChunkRegex=new RegExp
        ("((^|\\n)\\s*:*\\s*''[^']([^']|'''|'[^']){20}(.|\\n[^\\n])*''[.!?\\s]*\\n)*", 'g');
      this.data=this.data.replace(italicChunkRegex, '');
    };
    previewMaker.prototype.mopup=function () {
      // we simply *can't* be doing with horizontal rules right now
      this.data=this.data.replace(RegExp('^-{4,}','mg'),'');

      // no indented lines
      this.data=this.data.replace(RegExp('(^|\\n) *:[^\\n]*','g'), '\n');

      // replace __TOC__, __NOTOC__ and whatever else there is
      // this'll probably do
      this.data=this.data.replace(RegExp('^__[A-Z_]*__ *$', 'gmi'),'');
    };
    newOption('popupPreviewFirstParOnly', true);
    previewMaker.prototype.firstBit=function () {
      // dont't be givin' me no subsequent paragraphs, you hear me?
      /// first we "normalize" section headings, removing whitespace after, adding before

      this.data=this.data.replace(RegExp('\\s*(==+[^=]*==+)\\s*', 'g'), '\n\n$1 ');

      /// then we want to get rid of paragraph breaks whose text ends badly
      this.data=this.data.replace(RegExp('([:;]) *\\n{2,}', 'g'), '$1\n');

      this.data=this.data.replace(RegExp('^[\\s\\n]*'), '');
      stuff=(RegExp('^([^\\n]|\\n[^\\n\\s])*')).exec(this.data);
      var d;
      if (stuff) d = stuff[0];
      if (!getValueOf('popupPreviewFirstParOnly')) d = this.data;

      /// now put \n\n after sections so that bullets and numbered lists work
      d=d.replace(RegExp('(==+[^=]*==+)\\s*', 'g'), '$1\n\n');

      // superfluous sentences are RIGHT OUT.
      // note: exactly 1 set of parens here needed to make the slice work
      d = d.parenSplit(RegExp('([!?.]+["'+"'"+']*\\s)','g'));
      // leading space is bad, mmkay?
      d[0]=d[0].replace(RegExp('^\\s*'), '');

      var notSentenceEnds=RegExp('([^.][a-z][.][a-z]|etc|sic|Dr|Mr|Mrs|Ms)$'
                                 + '|' +
                                 '\\[[^\\]]*$'
                                 , 'i');

      d = this.fixSentenceEnds(d, notSentenceEnds);

      defaultize('popupMaxPreviewSentences');
      defaultize('popupMaxPreviewCharacters');

      var n=getValueOf('popupMaxPreviewSentences');
      var dd;

      do {dd=this.firstSentences(d,n); --n; }
      while ( dd.length > popupMaxPreviewCharacters && n > 0 );

      this.data = dd;
    };
    previewMaker.prototype.fixSentenceEnds=function(strs, reg) {
      // take an array of strings, strs
      // join strs[i] to strs[i+1] & strs[i+2] if strs[i] matches regex reg

      for (var i=0; i<strs.length-2; ++i) {
        if (reg.test(strs[i])) {
          a=[];
          for (var j=0; j<strs.length; ++j) {
            if (j<i)   a[j]=strs[j];
            if (j==i)  a[i]=strs[i]+strs[i+1]+strs[i+2];
            if (j>i+2) a[j-2]=strs[j];
          }
          return this.fixSentenceEnds(a,reg);
        }
      }
      return strs;
    };
    previewMaker.prototype.firstSentences=function(strs, howmany) {
      var t=strs.slice(0, 2*howmany);
      return t.join('');
    };

    previewMaker.prototype.makePreview=function() {
      if (!isInNamespace(window.currentArticle, 'Template')) {
        this.killComments();
        this.killDivs();
        this.killGalleries();
        this.killBoxTemplates();
        if (getValueOf('popupPreviewKillTemplates')) this.killTemplates();
        else this.killMultilineTemplates();
        this.killTables();
        this.killImages();
        this.killHTML();
        this.killChunks();
        this.mopup();

        this.firstBit();
      }

      this.html=wiki2html(this.data); // needs livepreview
      this.fixHTML();
      this.stripLongTemplates();
    };

    previewMaker.prototype.fixHTML=function() {
      // work around quoting bug:
      // wiki2html('[[Foo\'s "bar"]]') gives <a href='Foo's "bar"'> which doesn't do very well
      // we change this into <a href="Foo's %22bar%22">
      if(!this.html) return;
      var splitted=this.html.parenSplit(/href='([^>]*)'/g);
      var ret='';
      for (var i=0; i<splitted.length; ++i) {
        if(i%2==0) { ret += splitted[i]; continue; }
        if(i%2==1) { ret += 'href="' + splitted[i].split('"').join('%22') + '"'; }
      }
      this.html=ret;
    }
    previewMaker.prototype.showPreview=function () {
      this.makePreview();
      if (typeof this.html != typeof '') return;
      if (RegExp('^\\s*$').test(this.html)) return;
      //if (getValueOf('popupNavLinks') || getValueOf('popupSummaryData'))
      setPopupHTML('<hr>'+this.html, 'popupPreview');
    };
    previewMaker.prototype.stripLongTemplates=function() {
      // operates on the HTML!
      this.html=this.html.replace(RegExp('^.{0,1000}[{][{][^}]*?(<(p|br)( /)?>\\s*){2,}([^{}]*?[}][}])?', 'gi'), '');
      this.html=this.html.split('\n').join(' '); // workaround for <pre> templates
      this.html=this.html.replace(RegExp('[{][{][^}]*<pre>[^}]*[}][}]','gi'), '');
      //this.html=this.html.replace(RegExp('[{][{]([^}]*|\\s){0,50}?<pre>[^{}]*?[}][}]', 'gi'), '');
      //window.h=this.html;
      //alert(this.html);
    }
    previewMaker.prototype.killMultilineTemplates=function() {
      this.data=this.data.replace(RegExp('\\s*[{][{][^{}]*\\n[^{}]*[}][}]', 'g'), ' ');
      //this.data=this.data.replace(RegExp('[{][{]([{][{][^}]*[}][}]|[^{}])*\\n([{][{][^}]*[}][}]|[^{}])*[}][}]', 'g'), ' ');
    }

    function fuzzyCursorOffMenus(fuzz) {
      if(!over) return null;
      var spans=over.getElementsByTagName('span');
      for (var i=0; i<spans.length; ++i) {
        if (typeof spans[i].className != undef && spans[i].className=='popup_menu') {
          if (!fuzzyCursorOffDiv(fuzz, spans[i])) return false;
        } // else {document.title+='.';}
      }
      return true;
    };

    function fuzzyCursorOffDiv(fuzz, div) {
      log('fuzzyCursorOffDiv: mouse (x,y)=('+o3_x+',' + o3_y+')');
      var left=findPosX(div)-fuzz;
      var top=findPosY(div) - fuzz;
      var right=left + div.offsetWidth + 2*fuzz;
      var height=0;
      for (var i=0; i<div.childNodes.length;++i) {
        log('adding child '+div.childNodes[i]+'.offsetHeight: '+div.childNodes[i].offsetHeight);
        if (typeof div.childNodes[i].offsetHeight==typeof 1)
          height+=div.childNodes[i].offsetHeight;
      }
      var bottom = top + height + 2*fuzz;
      log(left+'->'+right+' , '+top+'->'+bottom);
      //document.title+=' offsetHeight:'+div.offsetHeight;
      if (typeof left != 'number' || typeof right != 'number' || typeof top != 'number') return true;
      if (o3_x < left || o3_x > right || o3_y < top) // || o3_y > bottom) // FIXME: should check the bottom too
        return true;
      return false;
    };

    function checkPopupPosition () { // stop the popup running off the right of the screen
      if (typeof over == undef || !over) return null;
      var x=findPosX(over);
      var w=parseInt(over.offsetWidth);
      if ( (x+w) >= document.body.clientWidth ) {
        // for what I am about to do, may the Lord forgive me
        over.style.left=0;
        var ww=parseInt(over.offsetWidth);
        over.style.left=(document.body.clientWidth-ww-1)+'px';
      }
      /*
      var y=findPosY(over);
      var h=parseInt(over.offsetHeight);
      var winH=window.innerHeight + window.pageYOffset;
      document.title=[y,h,winH].join(',');
      if ( h < winH && (y+h) >= winH ) {
        over.style.top=0;
        var hh=parseInt(over.offsetHeight);
        document.title+=','+hh;
        over.style.top=(winH-hh-24)+'px';
      }
      */
      return true;
    };

    function findPosX(obj)
    {
    	var curleft = 0;
    	if (obj.offsetParent)
    	{
    		while (obj.offsetParent)
    		{
    			curleft += obj.offsetLeft
    			obj = obj.offsetParent;
    		}
    	}
    	else if (obj.x)
    		curleft += obj.x;
    	return curleft;
    }

    function findPosY(obj)
    {
    	var curtop = 0;
    	if (obj.offsetParent)
    	{
    		while (obj.offsetParent)
    		{
    			curtop += obj.offsetTop
    			obj = obj.offsetParent;
    		}
    	}
    	else if (obj.y)
    		curtop += obj.y;
    	return curtop;
    }

    function fuzzyCursorOffOver(fuzz) {
      if (!over) return null;
      var left = parseInt(over.style.left);
      var top = parseInt(over.style.top);
      var right = left +
        (over.offsetWidth >= parseInt(o3_width) ? over.offsetWidth : parseInt(o3_width));
      var bottom = top +
        (over.offsetHeight >= o3_aboveheight ? over.offsetHeight : o3_aboveheight);

      if (o3_x < left-fuzz || o3_x > right+fuzz || o3_y < top-fuzz || o3_y > bottom + fuzz)
       return true;
      return false;
    };

    window.fuzzyCursorOff=function(fuzz) {
      return fuzzyCursorOffOver(fuzz) && fuzzyCursorOffMenus(fuzz);
    }

    // seems that fuzzyCursorOff should precede mouseOutWikiLink in the source
    // or sometimes during page loads, errors are generated

    var stopPopupTimer=null;

    function mouseOutWikiLink () {
      if (typeof over != undef &&  over && over.dragging) return null;
      if (fuzzyCursorOff(5)) {
        if (window.stopPopupTimer) {
          clearInterval(window.stopPopupTimer);
          window.stopPopupTimer=null;
        }
        killPopup();
        return;
      }
      // at this point, we've left the link but remain within the popup
      // so we call this function again until we leave the popup.
      if (!window.stopPopupTimer)
        window.stopPopupTimer=setInterval(mouseOutWikiLink, 500);
    };

    function killPopup() {
      // o3_showingsticky should be defined in overlib.js
      //if ( typeof o3_showingsticky != "undefined" && o3_showingsticky == 0 ) {
      if (getValueOf('popupShortcutKeys')) rmPopupShortcuts();
      cClick();
      window.currentLink=null;
      abortAllDownloads();
      stopImagesDownloading();
      if (checkPopupPositionTimer != null) { clearInterval(checkPopupPositionTimer); checkPopupPositionTimer=null; }
      if (checkImagesTimer != null) { clearInterval(checkImagesTimer); checkImagesTimer=null; }
      if (popupImageTimer != null) { clearInterval(popupImageTimer); popupImageTimer=null; }
      return true; // preserve default action (eg from onclick)
    };

    ////////////////////////////////////////////////////////////////////
    // Run things
    ////////////////////////////////////////////////////////////////////

    if (window.addEventListener) {
      window.addEventListener("DOMContentLoaded",setupTooltips,false) || window.addEventListener("load", setupTooltips, false);
    }
    else if (window.attachEvent) {
      window.attachEvent("onload",setupTooltips);
    }
    else {
      window._old_popup_onload = window.onload;
      window.onload = function() {
        window._old_popup_onload();
        setupTooltips();
      }
    }

    /// Local Variables: ///
    /// mode:c ///
    /// End: ///
    // --FILE BOUNDARY-- // --FILE BOUNDARY-- // --FILE BOUNDARY--
    function getParamValue(paramName) {
      var cmdRe=RegExp('[&?]'+paramName+'=([^&]*)');
      var h=document.location;
      var m;
      if (m=cmdRe.exec(h)) {
        try {
          return decodeURI(m[1]);
        } catch (someError) {}
      }
      return null;
    };

    function substitute(data,cmdBody) {
      // alert('sub\nfrom: '+cmdBody.from+'\nto: '+cmdBody.to+'\nflags: '+cmdBody.flags);
      var fromRe=RegExp(cmdBody.from, cmdBody.flags);
      return data.replace(fromRe, cmdBody.to);
    };

    function execCmds(data, cmdList) {
      for (var i=0; i<cmdList.length; ++i) {
        data=cmdList[i].action(data, cmdList[i]);
      }
      return data;
    }

    function parseCmd(str) {
      // returns a list of commands
      if (!str.length) return [];
      var p=false;
      switch (str.charAt(0)) {
      case 's':
        p=parseSubstitute(str);
        break;
      case 'j':
        p=parseJavascript(str);
        break;
      default:
        return false;
      }
      if (p) return [p].concat(parseCmd(p.remainder));
      return false;
    };

    function unEscape(str, sep) {
      return str.split('\\\\').join('\\')
            .split('\\'+sep).join(sep)
            .split('\\n').join('\n');
    };

    function runJavascript(data, argWrapper) {
      // flags aren't used (yet)

      // from the user's viewpoint,
      // data is a special variable may appear inside code
      // and gets assigned the text in the edit box

      // alert('eval-ing '+argWrapper.code);

      return eval(argWrapper.code);
    };

    function parseJavascript(str) {
      // takes a string like j/code/;othercmds and parses it

      var tmp,code,flags;

      if (str.length<3) return false;
      var sep=str.charAt(1);
      str=str.substring(2);

      tmp=skipOver(str,sep);
      if (tmp) { code=tmp.segment.split('\n').join('\\n'); str=tmp.remainder; }
      else return false;

      flags='';
      if (str.length) {
        tmp=skipOver(str,';') || skipToEnd(str, ';');
        if (tmp) {flags=tmp.segment; str=tmp.remainder; }
      }

      return { action: runJavascript, code: code, flags: flags, remainder: str };
    };

    function parseSubstitute(str) {
      // takes a string like s/a/b/flags;othercmds and parses it

      var from,to,flags,tmp;

      if (str.length<4) return false;
      var sep=str.charAt(1);
      str=str.substring(2);

      tmp=skipOver(str,sep);
      if (tmp) { from=tmp.segment; str=tmp.remainder; }
      else return false;

      tmp=skipOver(str,sep);
      if (tmp) { to=tmp.segment; str=tmp.remainder; }
      else return false;

      flags='';
      if (str.length) {
        tmp=skipOver(str,';') || skipToEnd(str, ';');
        if (tmp) {flags=tmp.segment; str=tmp.remainder; }
      }

      return {action: substitute, from: from, to: to, flags: flags, remainder: str};

    };

    function skipOver(str,sep) {
      var endSegment=findNext(str,sep);
      if (endSegment<0) return false;
      var segment=unEscape(str.substring(0,endSegment), sep);
      return {segment: segment, remainder: str.substring(endSegment+1)};
    }

    function skipToEnd(str,sep) {
      return {segment: str, remainder: ''};
    }

    function findNext(str, ch) {
      for (var i=0; i<str.length; ++i) {
        if (str.charAt(i)=='\\') i+=2;
        if (str.charAt(i)==ch) return i;
      }
      return -1;
    };

    function runOnLoad(f) {
      if (window.addEventListener) {
        window.addEventListener("load",f,false);
      }
      else if (window.attachEvent) {
        window.attachEvent("onload",f);
      }
      else {
        window._old_popup_autoedit_onload = window.onload;
        window.onload = function() {
          window._old_popup_autoedit_onload();
          f();
        }
      }
    };

    window.autoEdit=function() {
      if (window.autoEdit.alreadyRan) return false;
      window.autoEdit.alreadyRan=true;
      var cmdString=getParamValue('autoedit');
      if (cmdString) {
        try {
          var editbox=document.editform.wpTextbox1;
        } catch (dang) { return; }
        var cmdList=parseCmd(cmdString);
        var input=editbox.value;
        var output=execCmds(input, cmdList);
        editbox.value=output;
      }

      var summary=getParamValue('autosummary');
      if (summary) document.editform.wpSummary.value=summary;

      var minor=getParamValue('autominor');
      if (minor) {
        switch (minor) {
        case '1':
        case 'yes':
        case 'true':
          document.editform.wpMinoredit.checked=true;
          break;
        case '0':
        case 'no':
        case 'false':
          document.editform.wpMinoredit.checked=false;
        }
      }

      var btn=getParamValue('autoclick');
      if (btn) {
        if (document.editform && eval('document.editform.'+btn)) {
          var headings=document.getElementsByTagName('h1');
          if (headings) {
            var div=document.createElement('div');
            var button=eval('document.editform.'+btn);
            div.innerHTML='<font size=+5><b>"' + button.value +
              '"' + popupString('autoClicked') + '</b></font>';
            document.title='('+document.title+')';
            headings[0].parentNode.insertBefore(div, headings[0]);
            button.click();
          }
        } else {
          alert('autoedit.js\n\nautoclick: could not find button "'+ btn +'".');
        }
      }
    };

    runOnLoad(autoEdit);
    // --FILE BOUNDARY-- // --FILE BOUNDARY-- // --FILE BOUNDARY--
    // Last update: 21:51, 15 Feb 2005 (UTC)

    // Script to embed Live Preview in MediaWiki's edit page
    function LivePreviewInstall()
    {
     copywarn = document.getElementById('editpage-copywarn');
     if (copywarn != null) {
      var cleaner = "<br style=\\'clear:both;\\' />";
      LivePreviewHTML = '<input type="button" value="Live Preview" onclick="document.getElementById(\'PreviewBox\').innerHTML = wiki2html(editform.wpTextbox1.value) + \'' + cleaner + '\';" />';
      //LivePreviewHTML = '<input type="button" value="Live Preview" onclick="document.getElementById(\'PreviewBox\').innerHTML = wiki2html(editform.wpTextbox1.value);" />';
      LivePreviewHTML += '<div style="margin-top: 5px; margin-bottom: 5px; padding: 5px; border: 3px double orange;" id="PreviewBox"></div>';
      copywarn.innerHTML = LivePreviewHTML + copywarn.innerHTML;
     }
    }

    // User options
    var wpUserName=wpUserName||'Wikipedian';
    var wpUserSignature=wpUserSignature||wpUserName;
    var wpShowImages=wpShowImages||true;

    // System options
    var wpLanguageCode=wpLanguageCode||'en';
    var wpInterwikiCodes=wpInterwikiCodes||'aa|ab|af|ak|als|am|an|ang|ar|arc|as|ast|av|ay|az|ba|be|ber|bg|bh|bi|bm|bn|bdf|bo|br|bs|ca|ce|ceb|ch|cho|chr|chy|co|cr|cs|csb|cu|cv|cy|da|de|dv|dz|el|en|eo|es|et|eu|fa|ff|fi|fiu-vro|fj|fo|fr|fur|fy|ga|gd|gil|gl|gn|got|gu|gv|ha|haw|he|hi|ho|hr|ht|hu|hy|hz|ia|id|ie|ig|ii|ik|io|is|it|iu|ja|jbo|jv|ka|kg|ki|kj|kk|kl|km|kn|ko|kr|ks|ku|kv|kw|ky|la|lad|lan|lb|lg|li|ln|lo|lt|lu|lv|mg|mh|mi|mk|ml|mn|mo|mr|ms|mt|mus|my|na|nah|nap|nb|nd|nds|ne|ng|nl|nn|no|nr|nv|ny|oc|oj|om|or|os|pa|pam|pi|pl|ps|pt|qu|rm|rn|ro|roa-rup|ru|rw|sa|sc|scn|sco|sd|se|sg|sh|si|sk|sl|sm|smg|sn|so|sq|sr|ss|st|su|sv|sw|ta|te|tg|th|ti|tk|tl|tlh|tn|to|tpi|tr|ts|tt|tum|tw|ty|ug|uk|ur|uz|ve|vi|vk|vo|wa|war|wen|wo|xh|yi|yo|za|zh|zh-min-nan|zh-yue|zu';
    var wpBaseArticlePath=wpBaseArticlePath||'/wiki/';
    var wpMathBasePath=wpMathBasePath||'/math/';
    var wpImageBasePath=wpImageBasePath||'http://upload.wikimedia.org/wikipedia/'+wpLanguageCode+'/';
    var wpImageFallbackPath=wpImageFallbackPath||'http://upload.wikimedia.org/wikipedia/commons/';
    var wpDefaultThumbWidth=wpDefaultThumbWidth||180;
    var wpSkinMagnifyClip=wpSkinMagnifyClip||'/skins/common/images/magnify-clip.png';
    var wpUserNamespace=wpUserNamespace||'User';
    var wpImageNamespace=wpImageNamespace||'Image';
    var wpCategoryNamespace=wpCategoryNamespace||'Category';

    // Packed code (DO NOT MODIFY)
    function wiki2html(str)
    {str=strip_cr(str);var w=new WikiCode();w.lines=str.split(/\n/);w.parse();return w.html;};var wpSignature='[['+wpUserNamespace+':'+wpUserName+'|'+wpUserSignature+']]';var wpBlockImage=new RegExp('^\\[\\['+wpImageNamespace+':.*?\\|.*?(?:frame|thumbnail|thumb|none|right|left|center)','i');function WikiCode()
    {this.lines=new Array;this.html=new String;this._endline=function(str)
    {this.html+=str;this.lines.shift();};this.parse=function()
    {var p=false;do{if(h_match=this.lines[0].match(/^(={1,6})(.*)\1(.*)$/)){p=false;this._endline('<h'+h_match[1].length+'>'+_parse_inline_nowiki(h_match[2])+'</h'+h_match[1].length+'>'+h_match[3]);}else if(this.lines[0].match(/^[*#:;]/)){p=false;this._parse_list();}else if(this.lines[0].charAt(0)==' '){p=false;this._parse_pre();}else if(this.lines[0].substr(0,2)=='{|'){p=false;this._parse_table();}else if(this.lines[0].match(/^----+$/)){p=false;this._endline('<hr/>');}else if(this.lines[0].match(wpBlockImage)){p=false;this._parse_block_image();}else{if(this.lines[0]==''){if(p=(this.lines.length>1&&this.lines[1]=='')){this._endline('<p><br />');}}else{if(!p){this.html+='<p>';p=true;}
    this.html+=_parse_inline_nowiki(this.lines[0])+' ';}
    this.lines.shift();}}while(this.lines.length);};this._parse_list=function(){var prev=new String;var l_match,imatch,dt_match;while(this.lines.length&&(l_match=this.lines[0].match(/^([*#:;]+)(.*)$/))){this.lines.shift();imatch=str_imatch(prev,l_match[1]);for(var i=prev.length-1;i>=imatch;i--){if(prev.charAt(i)=='*'){this.html+='</ul>';}else if(prev.charAt(i)=='#'){this.html+='</ol>'}else{this.html+='</d'+((prev.charAt(i)==';')?'t':'d')+'>';switch(l_match[1].charAt(i)){case'':case'*':case'#':this.html+='</dl>';}}}
    for(var i=imatch;i<l_match[1].length;i++){if(l_match[1].charAt(i)=='*'){this.html+='<ul>';}else if(l_match[1].charAt(i)=='#'){this.html+='<ol>';}else{switch(prev.charAt(i)){case'':case'*':case'#':this.html+='<dl>';}
    this.html+='<d'+((l_match[1].charAt(i)==';')?'t':'d')+'>';}}
    switch(l_match[1].charAt(l_match[1].length-1)){case'*':case'#':this.html+='<li>'+_parse_inline_nowiki(l_match[2]);break;case';':if(dt_match=l_match[2].match(/(.*?) (:.*?)$/)){this.html+=_parse_inline_nowiki(dt_match[1]);this.lines.unshift(dt_match[2]);break;}
    case':':this.html+=_parse_inline_nowiki(l_match[2]);}
    prev=l_match[1];}
    for(i=prev.length-1;i>=0;i--){if(prev.charAt(i)=='*'){this.html+='</ul>';}else if(prev.charAt(i)=='#'){this.html+='</ol>';}else{this.html+='</d'+((prev.charAt(i)==';')?'t':'d')+'></dl>';}}};this._parse_table=function()
    {var table_match;if(table_match=this.lines[0].match(/^\{\|( .*)$/)){this._endline('<table'+table_match[1]+'>');}else this._endline('<table>');do{if(this.lines[0].charAt(0)=='|'){switch(this.lines[0].charAt(1)){case'}':this._endline('</table>');return;case'-':this._endline('<tr '+this.lines[0].match(/\|-*(.*)/)[1]+'>');break;default:this._parse_table_data();}}else if(this.lines[0].charAt(0)=='!'){this._parse_table_data();}else{this.lines.shift();}}while(this.lines.length)};this._parse_table_data=function()
    {var td_match,td_line;td_match=this.lines.shift().match(/^(\|\+|\||!)((?:([^[|]*?)\|(?!\|))?(.*))$/);if(td_match[1]=='|+'){this.html+='<caption';}else{this.html+='<t'+((td_match[1]=='|')?'d':'h');}
    if(typeof td_match[3]!='undefined'){this.html+=' '+td_match[3];td_line=td_match[4].split('||');}else{td_line=td_match[2].split('||');}
    this.html+='>';while(td_line.length>1){this.lines.unshift(td_match[1]+td_line.pop());}
    this.html+=_parse_inline_nowiki(td_line[0]);var td=new WikiCode;var table_count=0;while(this.lines.length){if(this.lines[0].charAt(0)=='|'){if(table_count==0)break;else if(this.lines[0].charAt(1)=='}')table_count--;}else if(this.lines[0].charAt(0)=='!'&&table_count==0){break;}else if(this.lines[0].substr(0,2)=='{|')table_count++;td.lines.push(this.lines.shift());}
    if(td.lines.length){td.parse();}
    this.html+=td.html;};this._parse_pre=function()
    {this.html+='<pre>';do{this._endline(_parse_inline_nowiki(this.lines[0].substring(1,this.lines[0].length))+"\n");}while(this.lines.length&&this.lines[0].charAt(0)==' ');this.html+='</pre>';};this._parse_block_image=function()
    {this.html+=_parse_image(this.lines.shift());};};function _parse_image(str)
    {var attr=str.substring(wpImageNamespace.length+3,str.length-2).split(/\s*\|\s*/);var filename=attr[0];var caption=attr[attr.length-1];var width,w_match;var thumb=false;var frame=false;var center=false;var align='';var html='';do{if(w_match=attr[0].match(/^(\d*)px$/)){width=w_match[1];}else switch(attr[0]){case'thumb':case'thumbnail':thumb=true;case'frame':frame=true;break;case'none':case'right':case'left':center=false;align=attr[0];break;case'center':center=true;align='none';}
    attr.shift();}while(attr.length);if(frame){if(align=='')align='right';html+="<div class='thumb t"+align+"'>";if(thumb){if(!width)width=wpDefaultThumbWidth;html+="<div style='width:"+(2+parseInt(width))+"px;'>";html+=_make_image(filename,caption,width);html+="<div class='thumbcaption'><div class='magnify' style='float:right'><a href='"+wpBaseArticlePath+wpImageNamespace+':'+filename+"' class='internal' title='Enlarge'><img src='"+wpSkinMagnifyClip+"' /></a></div>"+_parse_inline_nowiki(caption)+"</div>";}else{html+='<div>';html+=_make_image(filename,caption);html+="<div class='thumbcaption'>"+_parse_inline_nowiki(caption)+"</div>";}
    html+='</div></div>';}else if(align!=''){html+="<div class='float"+align+"'><span>"+_make_image(filename,caption,width)+"</span></div>";}else{return _make_image(filename,caption,width);}
    if(center){return"<div class='center'>"+html+'</div>';}else{return html;}};this._parse_inline_nowiki=function(str)
    {var start,lastend=0
    var substart=0,nestlev=0,open,close,subloop;var html='';while(-1!=(start=str.indexOf('<'+'nowiki>',substart))){html+=_parse_inline_wiki(str.substring(lastend,start));start+=8;substart=start;subloop=true;do{open=str.indexOf('<'+'nowiki>',substart);close=str.indexOf('</nowiki>',substart);if(close<=open||open==-1){if(close==-1){return html+html_entities(str.substr(start));}
    substart=close+9;if(nestlev){nestlev--;}else{lastend=substart;html+=html_entities(str.substring(start,lastend-9));subloop=false;}}else{substart=open+8;nestlev++;}}while(subloop);}
    return html+_parse_inline_wiki(str.substr(lastend));};function _make_image(filename,caption,width)
    {filename=filename.charAt(0).toUpperCase()+filename.substr(1);filename=filename.replace(/ /g,'_');var md5=hex_md5(filename);var source=md5.charAt(0)+'/'+md5.substr(0,2)+'/'+filename;var img;if(wpShowImages){if(width){width="width='"+width+"px'";}
    img="<img onerror='this.onerror=null;this.src=\""+wpImageFallbackPath+source+"\";' src='"+wpImageBasePath+source+"' alt='"+caption+"' "+width+"/>";}else{img=wpImageNamespace+':'+filename+" <em style='color:red;'>(images disabled)</em>";}
    caption=_strip_inline_wiki(caption);return"<a class='image' title='"+caption+"' href='"+wpBaseArticlePath+wpImageNamespace+':'+filename+"'>"+img+"</a>";};function _parse_inline_images(str)
    {var start,substart=0,nestlev=0;var loop,close,open,wiki,html;while(-1!=(start=str.indexOf('[[',substart))){if(str.substr(start+2).match(RegExp('^'+wpImageNamespace+':','i'))){loop=true;substart=start;do{substart+=2;close=str.indexOf(']]',substart);open=str.indexOf('[[',substart);if(close<=open||open==-1){if(close==-1)return str;substart=close;if(nestlev){nestlev--;}else{wiki=str.substring(start,close+2);html=_parse_image(wiki);str=str.replace(wiki,html);substart=start+html.length;loop=false;}}else{substart=open;nestlev++;}}while(loop);}else{break;}}
    return str;};function _parse_inline_wiki(str)
    {var aux_match,math_md5;str=_parse_inline_images(str);while(aux_match=str.match(/<(?:)math>(.*?)<\/math>/i)){math_md5=hex_md5(aux_match[1]);str=str.replace(aux_match[0],"<img src='"+wpMathBasePath+math_md5+'.png'+"' />");}
    return str.replace(/'''''(.*?)''(.*?)'''/g,'<strong><em>$1</em>$2</strong>').replace(/'''''(.*?)'''(.*?)''/g,'<em><strong>$1</strong>$2</em>').replace(/'''(.*?)''(.*?)'''''/g,'<strong>$1<em>$2</em></strong>').replace(/'''(.*?)'''/g,'<strong>$1</strong>').replace(/''(.*?)''/g,'<em>$1</em>').replace(/~{5}(?!~)/g,Date()).replace(/~{4}(?!~)/g,wpSignature+' '+Date()).replace(/~{3}(?!~)/g,wpSignature).replace(RegExp('\\[\\[:((?:'+wpCategoryNamespace+'|'+wpInterwikiCodes+'):.*?)\\]\\]','gi'),"<a href='"+wpBaseArticlePath+"$1'>$1</a>").replace(RegExp('\\[\\[(?:'+wpCategoryNamespace+'|'+wpInterwikiCodes+'):.*?\\]\\]','gi'),'').replace(/\[\[([^|]*?)\]\](\w*)/g,"<a href='"+wpBaseArticlePath+"$1'>$1$2</a>").replace(/\[\[(.*?)\|([^\]]+?)\]\](\w*)/g,"<a href='"+wpBaseArticlePath+"$1'>$2$3</a>").replace(/\[\[([^\]]*?:)?(.*?)( *\(.*?\))?\|\]\]/g,"<a href='"+wpBaseArticlePath+"$1$2$3'>$2</a>").replace(/\[(http|news|ftp|mailto|gopher|irc):(\/*)([^\]]*?) (.*?)\]/g,"<a href='$1:$2$3'>$4</a>").replace(/\[http:\/\/(.*?)\]/g,"<a href='http://$1'>[#]</a>").replace(/\[(news|ftp|mailto|gopher|irc):(\/*)(.*?)\]/g,"<a href='$1:$2$3'>$1:$2$3</a>").replace(/(^| )(http|news|ftp|mailto|gopher|irc):(\/*)([^ $]*)/g,"$1<a href='$2:$3$4'>$2:$3$4</a>").replace('__NOTOC__','').replace('__NOEDITSECTION__','');};function _strip_inline_wiki(str)
    {return str.replace(/\[\[[^\]]*\|(.*?)\]\]/g,'$1').replace(/\[\[(.*?)\]\]/g,'$1').replace(/''(.*?)''/g,'$1');};function max(a,b)
    {if(a>b)return a;else return b;};function min(a,b)
    {if(a<b)return a;else return b;};function str_imatch(str_a,str_b)
    {var lim=min(str_a.length,str_b.length);for(var i=0;i<lim;i++){if(str_a.charAt(i)!=str_b.charAt(i))return i;}
    return i;};function strip_cr(str)
    {return str.replace(/\n\r/g,"\n").replace(/\r/g,'');};function html_entities(str)
    {return str.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");};var chrsz=8;var hex_tab="0123456789abcdef";function hex_md5(s){return binl2hex(core_md5(str2binl(s),s.length*chrsz));};function core_md5(x,len)
    {x[len>>5]|=0x80<<((len)%32);x[(((len+64)>>>9)<<4)+14]=len;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;for(var i=0;i<x.length;i+=16)
    {var olda=a;var oldb=b;var oldc=c;var oldd=d;a=md5_ff(a,b,c,d,x[i+0],7,-680876936);d=md5_ff(d,a,b,c,x[i+1],12,-389564586);c=md5_ff(c,d,a,b,x[i+2],17,606105819);b=md5_ff(b,c,d,a,x[i+3],22,-1044525330);a=md5_ff(a,b,c,d,x[i+4],7,-176418897);d=md5_ff(d,a,b,c,x[i+5],12,1200080426);c=md5_ff(c,d,a,b,x[i+6],17,-1473231341);b=md5_ff(b,c,d,a,x[i+7],22,-45705983);a=md5_ff(a,b,c,d,x[i+8],7,1770035416);d=md5_ff(d,a,b,c,x[i+9],12,-1958414417);c=md5_ff(c,d,a,b,x[i+10],17,-42063);b=md5_ff(b,c,d,a,x[i+11],22,-1990404162);a=md5_ff(a,b,c,d,x[i+12],7,1804603682);d=md5_ff(d,a,b,c,x[i+13],12,-40341101);c=md5_ff(c,d,a,b,x[i+14],17,-1502002290);b=md5_ff(b,c,d,a,x[i+15],22,1236535329);a=md5_gg(a,b,c,d,x[i+1],5,-165796510);d=md5_gg(d,a,b,c,x[i+6],9,-1069501632);c=md5_gg(c,d,a,b,x[i+11],14,643717713);b=md5_gg(b,c,d,a,x[i+0],20,-373897302);a=md5_gg(a,b,c,d,x[i+5],5,-701558691);d=md5_gg(d,a,b,c,x[i+10],9,38016083);c=md5_gg(c,d,a,b,x[i+15],14,-660478335);b=md5_gg(b,c,d,a,x[i+4],20,-405537848);a=md5_gg(a,b,c,d,x[i+9],5,568446438);d=md5_gg(d,a,b,c,x[i+14],9,-1019803690);c=md5_gg(c,d,a,b,x[i+3],14,-187363961);b=md5_gg(b,c,d,a,x[i+8],20,1163531501);a=md5_gg(a,b,c,d,x[i+13],5,-1444681467);d=md5_gg(d,a,b,c,x[i+2],9,-51403784);c=md5_gg(c,d,a,b,x[i+7],14,1735328473);b=md5_gg(b,c,d,a,x[i+12],20,-1926607734);a=md5_hh(a,b,c,d,x[i+5],4,-378558);d=md5_hh(d,a,b,c,x[i+8],11,-2022574463);c=md5_hh(c,d,a,b,x[i+11],16,1839030562);b=md5_hh(b,c,d,a,x[i+14],23,-35309556);a=md5_hh(a,b,c,d,x[i+1],4,-1530992060);d=md5_hh(d,a,b,c,x[i+4],11,1272893353);c=md5_hh(c,d,a,b,x[i+7],16,-155497632);b=md5_hh(b,c,d,a,x[i+10],23,-1094730640);a=md5_hh(a,b,c,d,x[i+13],4,681279174);d=md5_hh(d,a,b,c,x[i+0],11,-358537222);c=md5_hh(c,d,a,b,x[i+3],16,-722521979);b=md5_hh(b,c,d,a,x[i+6],23,76029189);a=md5_hh(a,b,c,d,x[i+9],4,-640364487);d=md5_hh(d,a,b,c,x[i+12],11,-421815835);c=md5_hh(c,d,a,b,x[i+15],16,530742520);b=md5_hh(b,c,d,a,x[i+2],23,-995338651);a=md5_ii(a,b,c,d,x[i+0],6,-198630844);d=md5_ii(d,a,b,c,x[i+7],10,1126891415);c=md5_ii(c,d,a,b,x[i+14],15,-1416354905);b=md5_ii(b,c,d,a,x[i+5],21,-57434055);a=md5_ii(a,b,c,d,x[i+12],6,1700485571);d=md5_ii(d,a,b,c,x[i+3],10,-1894986606);c=md5_ii(c,d,a,b,x[i+10],15,-1051523);b=md5_ii(b,c,d,a,x[i+1],21,-2054922799);a=md5_ii(a,b,c,d,x[i+8],6,1873313359);d=md5_ii(d,a,b,c,x[i+15],10,-30611744);c=md5_ii(c,d,a,b,x[i+6],15,-1560198380);b=md5_ii(b,c,d,a,x[i+13],21,1309151649);a=md5_ii(a,b,c,d,x[i+4],6,-145523070);d=md5_ii(d,a,b,c,x[i+11],10,-1120210379);c=md5_ii(c,d,a,b,x[i+2],15,718787259);b=md5_ii(b,c,d,a,x[i+9],21,-343485551);a=safe_add(a,olda);b=safe_add(b,oldb);c=safe_add(c,oldc);d=safe_add(d,oldd);}
    return Array(a,b,c,d);};function md5_cmn(q,a,b,x,s,t)
    {return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b);};function md5_ff(a,b,c,d,x,s,t)
    {return md5_cmn((b&c)|((~b)&d),a,b,x,s,t);};function md5_gg(a,b,c,d,x,s,t)
    {return md5_cmn((b&d)|(c&(~d)),a,b,x,s,t);};function md5_hh(a,b,c,d,x,s,t)
    {return md5_cmn(b^c^d,a,b,x,s,t);};function md5_ii(a,b,c,d,x,s,t)
    {return md5_cmn(c^(b|(~d)),a,b,x,s,t);};function safe_add(x,y)
    {var lsw=(x&0xFFFF)+(y&0xFFFF);var msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&0xFFFF);};function bit_rol(num,cnt)
    {return(num<<cnt)|(num>>>(32-cnt));};function str2binl(str)
    {var bin=Array();var mask=(1<<chrsz)-1;for(var i=0;i<str.length*chrsz;i+=chrsz)
    bin[i>>5]|=(str.charCodeAt(i/chrsz)&mask)<<(i%32);return bin;};function binl2hex(binarray)
    {var str='';for(var i=0;i<binarray.length*4;i++)
    {str+=hex_tab.charAt((binarray[i>>2]>>((i%4)*8+4))&0xF)+
    hex_tab.charAt((binarray[i>>2]>>((i%4)*8))&0xF);}
    return str;}; // </math>// --FILE BOUNDARY-- // --FILE BOUNDARY-- // --FILE BOUNDARY--
    /*
     * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
     * Digest Algorithm, as defined in RFC 1321.
     * Version 2.2-alpha Copyright (C) Paul Johnston 1999 - 2005
     * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
     * Distributed under the BSD License
     * See http://pajhome.org.uk/crypt/md5 for more info.
     */

    /*
     * Configurable variables. You may need to tweak these to be compatible with
     * the server-side, but the defaults work in most cases.
     */
    var hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
    var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */

    /*
     * These are the functions you'll usually want to call
     * They take string arguments and return either hex or base-64 encoded strings
     */
    function hex_md5(s)    { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
    function b64_md5(s)    { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
    function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
    function hex_hmac_md5(k, d)
      { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
    function b64_hmac_md5(k, d)
      { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
    function any_hmac_md5(k, d, e)
      { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }

    /*
     * Perform a simple self-test to see if the VM is working
     */
    function md5_vm_test()
    {
      return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
    }

    /*
     * Calculate the MD5 of a raw string
     */
    function rstr_md5(s)
    {
      return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
    }

    /*
     * Calculate the HMAC-MD5, of a key and some data (raw strings)
     */
    function rstr_hmac_md5(key, data)
    {
      var bkey = rstr2binl(key);
      if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);

      var ipad = Array(16), opad = Array(16);
      for(var i = 0; i < 16; i++)
      {
        ipad[i] = bkey[i] ^ 0x36363636;
        opad[i] = bkey[i] ^ 0x5C5C5C5C;
      }

      var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
      return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
    }

    /*
     * Convert a raw string to a hex string
     */
    function rstr2hex(input)
    {
      var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
      var output = "";
      var x;
      for(var i = 0; i < input.length; i++)
      {
        x = input.charCodeAt(i);
        output += hex_tab.charAt((x >>> 4) & 0x0F)
               +  hex_tab.charAt( x        & 0x0F);
      }
      return output;
    }

    /*
     * Convert a raw string to a base-64 string
     */
    function rstr2b64(input)
    {
      var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      var output = "";
      var len = input.length;
      for(var i = 0; i < len; i += 3)
      {
        var triplet = (input.charCodeAt(i) << 16)
                    | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
                    | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
        for(var j = 0; j < 4; j++)
        {
          if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
        }
      }
      return output;
    }

    /*
     * Convert a raw string to an arbitrary string encoding
     */
    function rstr2any(input, encoding)
    {
      var divisor = encoding.length;
      var remainders = Array();
      var i, q, x, quotient;

      /* Convert to an array of 16-bit big-endian values, forming the dividend */
      var dividend = Array(input.length / 2);
      for(i = 0; i < dividend.length; i++)
      {
        dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
      }

      /*
       * Repeatedly perform a long division. The binary array forms the dividend,
       * the length of the encoding is the divisor. Once computed, the quotient
       * forms the dividend for the next step. We stop when the dividend is zero.
       * All remainders are stored for later use.
       */
      while(dividend.length > 0)
      {
        quotient = Array();
        x = 0;
        for(i = 0; i < dividend.length; i++)
        {
          x = (x << 16) + dividend[i];
          q = Math.floor(x / divisor);
          x -= q * divisor;
          if(quotient.length > 0 || q > 0)
            quotient[quotient.length] = q;
        }
        remainders[remainders.length] = x;
        dividend = quotient;
      }

      /* Convert the remainders to the output string */
      var output = "";
      for(i = remainders.length - 1; i >= 0; i--)
        output += encoding.charAt(remainders[i]);

      return output;
    }

    /*
     * Encode a string as utf-8.
     * For efficiency, this assumes the input is valid utf-16.
     */
    function str2rstr_utf8(input)
    {
      var output = "";
      var i = -1;
      var x, y;

      while(++i < input.length)
      {
        /* Decode utf-16 surrogate pairs */
        x = input.charCodeAt(i);
        y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
        if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
        {
          x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          i++;
        }

        /* Encode output as utf-8 */
        if(x <= 0x7F)
          output += String.fromCharCode(x);
        else if(x <= 0x7FF)
          output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
                                        0x80 | ( x         & 0x3F));
        else if(x <= 0xFFFF)
          output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
                                        0x80 | ((x >>> 6 ) & 0x3F),
                                        0x80 | ( x         & 0x3F));
        else if(x <= 0x1FFFFF)
          output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
                                        0x80 | ((x >>> 12) & 0x3F),
                                        0x80 | ((x >>> 6 ) & 0x3F),
                                        0x80 | ( x         & 0x3F));
      }
      return output;
    }

    /*
     * Encode a string as utf-16
     */
    function str2rstr_utf16le(input)
    {
      var output = "";
      for(var i = 0; i < input.length; i++)
        output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
                                      (input.charCodeAt(i) >>> 8) & 0xFF);
      return output;
    }

    function str2rstr_utf16be(input)
    {
      var output = "";
      for(var i = 0; i < input.length; i++)
        output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
                                       input.charCodeAt(i)        & 0xFF);
      return output;
    }

    /*
     * Convert a raw string to an array of little-endian words
     * Characters >255 have their high-byte silently ignored.
     */
    function rstr2binl(input)
    {
      var output = Array(input.length >> 2);
      for(var i = 0; i < output.length; i++)
        output[i] = 0;
      for(var i = 0; i < input.length * 8; i += 8)
        output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
      return output;
    }

    /*
     * Convert an array of little-endian words to a string
     */
    function binl2rstr(input)
    {
      var output = "";
      for(var i = 0; i < input.length * 32; i += 8)
        output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
      return output;
    }

    /*
     * Calculate the MD5 of an array of little-endian words, and a bit length.
     */
    function binl_md5(x, len)
    {
      /* append padding */
      x[len >> 5] |= 0x80 << ((len) % 32);
      x[(((len + 64) >>> 9) << 4) + 14] = len;

      var a =  1732584193;
      var b = -271733879;
      var c = -1732584194;
      var d =  271733878;

      for(var i = 0; i < x.length; i += 16)
      {
        var olda = a;
        var oldb = b;
        var oldc = c;
        var oldd = d;

        a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
        d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
        c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
        b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
        a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
        d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
        c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
        b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
        a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
        d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
        c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
        b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
        a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
        d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
        c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
        b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

        a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
        d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
        c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
        b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
        a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
        d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
        c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
        b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
        a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
        d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
        c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
        b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
        a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
        d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
        c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
        b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

        a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
        d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
        c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
        b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
        a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
        d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
        c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
        b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
        a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
        d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
        c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
        b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
        a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
        d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
        c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
        b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

        a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
        d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
        c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
        b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
        a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
        d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
        c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
        b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
        a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
        d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
        c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
        b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
        a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
        d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
        c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
        b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

        a = safe_add(a, olda);
        b = safe_add(b, oldb);
        c = safe_add(c, oldc);
        d = safe_add(d, oldd);
      }
      return Array(a, b, c, d);
    }

    /*
     * These functions implement the four basic operations the algorithm uses.
     */
    function md5_cmn(q, a, b, x, s, t)
    {
      return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
    }
    function md5_ff(a, b, c, d, x, s, t)
    {
      return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
    }
    function md5_gg(a, b, c, d, x, s, t)
    {
      return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
    }
    function md5_hh(a, b, c, d, x, s, t)
    {
      return md5_cmn(b ^ c ^ d, a, b, x, s, t);
    }
    function md5_ii(a, b, c, d, x, s, t)
    {
      return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
    }

    /*
     * Add integers, wrapping at 2^32. This uses 16-bit operations internally
     * to work around bugs in some JS interpreters.
     */
    function safe_add(x, y)
    {
      var lsw = (x & 0xFFFF) + (y & 0xFFFF);
      var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
      return (msw << 16) | (lsw & 0xFFFF);
    }

    /*
     * Bitwise rotate a 32-bit number to the left.
     */
    function bit_rol(num, cnt)
    {
      return (num << cnt) | (num >>> (32 - cnt));
    }// --FILE BOUNDARY-- // --FILE BOUNDARY-- // --FILE BOUNDARY--
    //\/////
    //\  overLIB 4.21 - You may not remove or change this notice.
    //\  Copyright Erik Bosrup 1998-2004. All rights reserved.
    //\
    //\  Contributors are listed on the homepage.
    //\  This file might be old, always check for the latest version at:
    //\  http://www.bosrup.com/web/overlib/
    //\
    //\  Please read the license agreement (available through the link above)
    //\  before using overLIB. Direct any licensing questions to erik@bosrup.com.
    //\
    //\  Do not sell this as your own work or remove this copyright notice.
    //\  For full details on copying or changing this script please read the
    //\  license agreement at the link above. Please give credit on sites that
    //\  use overLIB and submit changes of the script so other people can use
    //\  them as well.
    //\/////
    //\  THIS IS A VERY MODIFIED VERSION. DO NOT EDIT OR PUBLISH. GET THE ORIGINAL!
    var olLoaded=0,pmStart=10000000,pmUpper=10001000,pmCount=pmStart+1,pmt='',pms=new Array(),olInfo=new Info('4.21',1),FREPLACE=0,FBEFORE=1,FAFTER=2,FALTERNATE=3,FCHAIN=4,olHideForm=0,olHautoFlag=0,olVautoFlag=0,hookPts=new Array(),postParse=new Array(),cmdLine=new Array(),runTime=new Array();
    registerCommands('donothing,inarray,caparray,sticky,background,noclose,caption,left,right,center,offsetx,offsety,fgcolor,bgcolor,textcolor,capcolor,closecolor,width,border,cellpad,status,autostatus,autostatuscap,height,closetext,snapx,snapy,fixx,fixy,relx,rely,fgbackground,bgbackground,padx,pady,fullhtml,above,below,capicon,textfont,captionfont,closefont,textsize,captionsize,closesize,timeout,function,delay,hauto,vauto,closeclick,wrap,followmouse,mouseoff,closetitle,cssoff,compatmode,cssclass,fgclass,bgclass,textfontclass,captionfontclass,closefontclass');
    if(typeof ol_fgcolor=='undefined')var ol_fgcolor="#CCCCFF";if(typeof ol_bgcolor=='undefined')var ol_bgcolor="#333399";if(typeof ol_textcolor=='undefined')var ol_textcolor="#000000";if(typeof ol_capcolor=='undefined')var ol_capcolor="#FFFFFF";if(typeof ol_closecolor=='undefined')var ol_closecolor="#9999FF";if(typeof ol_textfont=='undefined')var ol_textfont="Verdana,Arial,Helvetica";if(typeof ol_captionfont=='undefined')var ol_captionfont="Verdana,Arial,Helvetica";if(typeof ol_closefont=='undefined')var ol_closefont="Verdana,Arial,Helvetica";if(typeof ol_textsize=='undefined')var ol_textsize="1";if(typeof ol_captionsize=='undefined')var ol_captionsize="1";if(typeof ol_closesize=='undefined')var ol_closesize="1";if(typeof ol_width=='undefined')var ol_width="200";if(typeof ol_border=='undefined')var ol_border="1";if(typeof ol_cellpad=='undefined')var ol_cellpad=2;if(typeof ol_offsetx=='undefined')var ol_offsetx=10;if(typeof ol_offsety=='undefined')var ol_offsety=10;if(typeof ol_text=='undefined')var ol_text="Default Text";if(typeof ol_cap=='undefined')var ol_cap="";if(typeof ol_sticky=='undefined')var ol_sticky=0;if(typeof ol_background=='undefined')var ol_background="";if(typeof ol_close=='undefined')var ol_close="Close";if(typeof ol_hpos=='undefined')var ol_hpos=RIGHT;if(typeof ol_status=='undefined')var ol_status="";if(typeof ol_autostatus=='undefined')var ol_autostatus=0;if(typeof ol_height=='undefined')var ol_height=-1;if(typeof ol_snapx=='undefined')var ol_snapx=0;if(typeof ol_snapy=='undefined')var ol_snapy=0;if(typeof ol_fixx=='undefined')var ol_fixx=-1;if(typeof ol_fixy=='undefined')var ol_fixy=-1;if(typeof ol_relx=='undefined')var ol_relx=null;if(typeof ol_rely=='undefined')var ol_rely=null;if(typeof ol_fgbackground=='undefined')var ol_fgbackground="";if(typeof ol_bgbackground=='undefined')var ol_bgbackground="";if(typeof ol_padxl=='undefined')var ol_padxl=1;if(typeof ol_padxr=='undefined')var ol_padxr=1;if(typeof ol_padyt=='undefined')var ol_padyt=1;if(typeof ol_padyb=='undefined')var ol_padyb=1;if(typeof ol_fullhtml=='undefined')var ol_fullhtml=0;if(typeof ol_vpos=='undefined')var ol_vpos=BELOW;if(typeof ol_aboveheight=='undefined')var ol_aboveheight=0;if(typeof ol_capicon=='undefined')var ol_capicon="";if(typeof ol_frame=='undefined')var ol_frame=self;if(typeof ol_timeout=='undefined')var ol_timeout=0;if(typeof ol_function=='undefined')var ol_function=null;if(typeof ol_delay=='undefined')var ol_delay=0;if(typeof ol_hauto=='undefined')var ol_hauto=0;if(typeof ol_vauto=='undefined')var ol_vauto=0;if(typeof ol_closeclick=='undefined')var ol_closeclick=0;if(typeof ol_wrap=='undefined')var ol_wrap=0;if(typeof ol_followmouse=='undefined')var ol_followmouse=1;if(typeof ol_mouseoff=='undefined')var ol_mouseoff=0;if(typeof ol_closetitle=='undefined')var ol_closetitle='Close';if(typeof ol_compatmode=='undefined')var ol_compatmode=0;if(typeof ol_css=='undefined')var ol_css=CSSOFF;if(typeof ol_fgclass=='undefined')var ol_fgclass="";if(typeof ol_bgclass=='undefined')var ol_bgclass="";if(typeof ol_textfontclass=='undefined')var ol_textfontclass="";if(typeof ol_captionfontclass=='undefined')var ol_captionfontclass="";if(typeof ol_closefontclass=='undefined')var ol_closefontclass="";
    if(typeof ol_texts=='undefined')var ol_texts=new Array("Text 0","Text 1");if(typeof ol_caps=='undefined')var ol_caps=new Array("Caption 0","Caption 1");
    var o3_text="",o3_cap="",o3_sticky=0,o3_background="",o3_close="Close",o3_hpos=RIGHT,o3_offsetx=2,o3_offsety=2,o3_fgcolor="",o3_bgcolor="",o3_textcolor="",o3_capcolor="",o3_closecolor="",o3_width=100,o3_border=1,o3_cellpad=2,o3_status="",o3_autostatus=0,o3_height=-1,o3_snapx=0,o3_snapy=0,o3_fixx=-1,o3_fixy=-1,o3_relx=null,o3_rely=null,o3_fgbackground="",o3_bgbackground="",o3_padxl=0,o3_padxr=0,o3_padyt=0,o3_padyb=0,o3_fullhtml=0,o3_vpos=BELOW,o3_aboveheight=0,o3_capicon="",o3_textfont="Verdana,Arial,Helvetica",o3_captionfont="Verdana,Arial,Helvetica",o3_closefont="Verdana,Arial,Helvetica",o3_textsize="1",o3_captionsize="1",o3_closesize="1",o3_frame=self,o3_timeout=0,o3_timerid=0,o3_allowmove=0,o3_function=null,o3_delay=0,o3_delayid=0,o3_hauto=0,o3_vauto=0,o3_closeclick=0,o3_wrap=0,o3_followmouse=1,o3_mouseoff=0,o3_closetitle='',o3_compatmode=0,o3_css=CSSOFF,o3_fgclass="",o3_bgclass="",o3_textfontclass="",o3_captionfontclass="",o3_closefontclass="";
    var o3_x=0,o3_y=0,o3_showingsticky=0,o3_removecounter=0;
    var over=null,fnRef,hoveringSwitch=false,olHideDelay;
    var isMac=(navigator.userAgent.indexOf("Mac")!=-1),olOp=(navigator.userAgent.toLowerCase().indexOf('opera')>-1&&document.createTextNode),olNs4=(navigator.appName=='Netscape'&&parseInt(navigator.appVersion)==4),olNs6=(document.getElementById)?true:false,olKq=(olNs6&&/konqueror/i.test(navigator.userAgent)),olIe4=(document.all)?true:false,olIe5=false,olIe55=false,docRoot='document.body';
    if(olNs4){var oW=window.innerWidth;var oH=window.innerHeight;window.onresize=function(){if(oW!=window.innerWidth||oH!=window.innerHeight)location.reload();}}
    if(olIe4){var agent=navigator.userAgent;if(/MSIE/.test(agent)){var versNum=parseFloat(agent.match(/MSIE[ ](\d\.\d+)\.*/i)[1]);if(versNum>=5){olIe5=true;olIe55=(versNum>=5.5&&!olOp)?true:false;if(olNs6)olNs6=false;}}
    if(olNs6)olIe4=false;}
    if(document.compatMode&&document.compatMode=='CSS1Compat'){docRoot=((olIe4&&!olOp)?'document.documentElement':docRoot);}
    if(window.addEventListener)window.addEventListener("load",OLonLoad_handler,false);else if(window.attachEvent)window.attachEvent("onload",OLonLoad_handler);
    var capExtent;
    function overlib(){if(!olLoaded||isExclusive(overlib.arguments))return true;if(olCheckMouseCapture)olMouseCapture();if(over){over=(typeof over.id!='string')?o3_frame.document.all['overDiv']:over;cClick();}
    olHideDelay=0;o3_text=ol_text;o3_cap=ol_cap;o3_sticky=ol_sticky;o3_background=ol_background;o3_close=ol_close;o3_hpos=ol_hpos;o3_offsetx=ol_offsetx;o3_offsety=ol_offsety;o3_fgcolor=ol_fgcolor;o3_bgcolor=ol_bgcolor;o3_textcolor=ol_textcolor;o3_capcolor=ol_capcolor;o3_closecolor=ol_closecolor;o3_width=ol_width;o3_border=ol_border;o3_cellpad=ol_cellpad;o3_status=ol_status;o3_autostatus=ol_autostatus;o3_height=ol_height;o3_snapx=ol_snapx;o3_snapy=ol_snapy;o3_fixx=ol_fixx;o3_fixy=ol_fixy;o3_relx=ol_relx;o3_rely=ol_rely;o3_fgbackground=ol_fgbackground;o3_bgbackground=ol_bgbackground;o3_padxl=ol_padxl;o3_padxr=ol_padxr;o3_padyt=ol_padyt;o3_padyb=ol_padyb;o3_fullhtml=ol_fullhtml;o3_vpos=ol_vpos;o3_aboveheight=ol_aboveheight;o3_capicon=ol_capicon;o3_textfont=ol_textfont;o3_captionfont=ol_captionfont;o3_closefont=ol_closefont;o3_textsize=ol_textsize;o3_captionsize=ol_captionsize;o3_closesize=ol_closesize;o3_timeout=ol_timeout;o3_function=ol_function;o3_delay=ol_delay;o3_hauto=ol_hauto;o3_vauto=ol_vauto;o3_closeclick=ol_closeclick;o3_wrap=ol_wrap;o3_followmouse=ol_followmouse;o3_mouseoff=ol_mouseoff;o3_closetitle=ol_closetitle;o3_css=ol_css;o3_compatmode=ol_compatmode;o3_fgclass=ol_fgclass;o3_bgclass=ol_bgclass;o3_textfontclass=ol_textfontclass;o3_captionfontclass=ol_captionfontclass;o3_closefontclass=ol_closefontclass;
    setRunTimeVariables();
    fnRef='';
    o3_frame=ol_frame;
    if(!(over=createDivContainer()))return false;
    parseTokens('o3_',overlib.arguments);if(!postParseChecks())return false;
    if(o3_delay==0){return runHook("olMain",FREPLACE);}else{o3_delayid=setTimeout("runHook('olMain',FREPLACE)",o3_delay);return false;}}
    function nd(time){if(olLoaded&&!isExclusive()){hideDelay(time);
    if(o3_removecounter>=1){o3_showingsticky=0 };
    if(o3_showingsticky==0){o3_allowmove=0;if(over!=null&&o3_timerid==0)runHook("hideObject",FREPLACE,over);}else{o3_removecounter++;}}
    return true;}
    function cClick(){if(olLoaded){runHook("hideObject",FREPLACE,over);o3_showingsticky=0;}
    return false;}
    function overlib_pagedefaults(){parseTokens('ol_',overlib_pagedefaults.arguments);}
    function olMain(){var layerhtml,styleType;runHook("olMain",FBEFORE);
    if(o3_background!=""||o3_fullhtml){
    layerhtml=runHook('ol_content_background',FALTERNATE,o3_css,o3_text,o3_background,o3_fullhtml);}else{
    styleType=(pms[o3_css-1-pmStart]=="cssoff"||pms[o3_css-1-pmStart]=="cssclass");
    if(o3_fgbackground!="")o3_fgbackground="background=\""+o3_fgbackground+"\"";if(o3_bgbackground!="")o3_bgbackground=(styleType?"background=\""+o3_bgbackground+"\"":o3_bgbackground);
    if(o3_fgcolor!="")o3_fgcolor=(styleType?"bgcolor=\""+o3_fgcolor+"\"":o3_fgcolor);if(o3_bgcolor!="")o3_bgcolor=(styleType?"bgcolor=\""+o3_bgcolor+"\"":o3_bgcolor);
    if(o3_height>0)o3_height=(styleType?"height=\""+o3_height+"\"":o3_height);else o3_height="";
    if(o3_cap==""){
    layerhtml=runHook('ol_content_simple',FALTERNATE,o3_css,o3_text);}else{
    if(o3_sticky){
    layerhtml=runHook('ol_content_caption',FALTERNATE,o3_css,o3_text,o3_cap,o3_close);}else{
    layerhtml=runHook('ol_content_caption',FALTERNATE,o3_css,o3_text,o3_cap,"");}}}
    if(o3_sticky){if(o3_timerid>0){clearTimeout(o3_timerid);o3_timerid=0;}
    o3_showingsticky=1;o3_removecounter=0;}
    if(!runHook("createPopup",FREPLACE,layerhtml))return false;
    if(o3_autostatus>0){o3_status=o3_text;if(o3_autostatus>1)o3_status=o3_cap;}
    o3_allowmove=0;
    if(o3_timeout>0){if(o3_timerid>0)clearTimeout(o3_timerid);o3_timerid=setTimeout("cClick()",o3_timeout);}
    runHook("disp",FREPLACE,o3_status);runHook("olMain",FAFTER);
    return(olOp&&event&&event.type=='mouseover'&&!o3_status)?'':(o3_status!='');}
    function ol_content_simple(text){var cpIsMultiple=/,/.test(o3_cellpad);var txt='<table width="'+o3_width+'" border="0" cellpadding="'+o3_border+'" cellspacing="0" '+(o3_bgclass?'class="'+o3_bgclass+'"':o3_bgcolor+' '+o3_height)+'><tr><td><table width="100%" border="0" '+((olNs4||!cpIsMultiple)?'cellpadding="'+o3_cellpad+'" ':'')+'cellspacing="0" '+(o3_fgclass?'class="'+o3_fgclass+'"':o3_fgcolor+' '+o3_fgbackground+' '+o3_height)+'><tr><td valign="TOP"'+(o3_textfontclass?' class="'+o3_textfontclass+'">':((!olNs4&&cpIsMultiple)?' style="'+setCellPadStr(o3_cellpad)+'">':'>'))+(o3_textfontclass?'':wrapStr(0,o3_textsize,'text'))+text+(o3_textfontclass?'':wrapStr(1,o3_textsize))+'</td></tr></table></td></tr></table>';
    set_background("");return txt;}
    function ol_content_caption(text,title,close){var nameId,txt,cpIsMultiple=/,/.test(o3_cellpad);var closing,closeevent;
    closing="";closeevent="onmouseover";if(o3_closeclick==1)closeevent=(o3_closetitle?"title='"+o3_closetitle+"'":"")+" onclick";if(o3_capicon!=""){nameId=' hspace=\"5\"'+' align=\"middle\" alt=\"\"';if(typeof o3_dragimg!='undefined'&&o3_dragimg)nameId=' hspace=\"5\"'+' name=\"'+o3_dragimg+'\" id=\"'+o3_dragimg+'\" align=\"middle\" alt=\"Drag Enabled\" title=\"Drag Enabled\"';o3_capicon='<img src=\"'+o3_capicon+'\"'+nameId+' />';}
    if(close!="")
    closing='<td '+(!o3_compatmode&&o3_closefontclass?'class="'+o3_closefontclass:'align="RIGHT')+'"><a href="javascript:return '+fnRef+'cClick();"'+((o3_compatmode&&o3_closefontclass)?' class="'+o3_closefontclass+'" ':' ')+closeevent+'="return '+fnRef+'cClick();">'+(o3_closefontclass?'':wrapStr(0,o3_closesize,'close'))+close+(o3_closefontclass?'':wrapStr(1,o3_closesize,'close'))+'</a></td>';txt='<table width="'+o3_width+'" border="0" cellpadding="'+o3_border+'" cellspacing="0" '+(o3_bgclass?'class="'+o3_bgclass+'"':o3_bgcolor+' '+o3_bgbackground+' '+o3_height)+'><tr><td><table width="100%" border="0" cellpadding="2" cellspacing="0"><tr><td'+(o3_captionfontclass?' class="'+o3_captionfontclass+'">':'>')+(o3_captionfontclass?'':'<b>'+wrapStr(0,o3_captionsize,'caption'))+o3_capicon+title+(o3_captionfontclass?'':wrapStr(1,o3_captionsize)+'</b>')+'</td>'+closing+'</tr></table><table width="100%" border="0" '+((olNs4||!cpIsMultiple)?'cellpadding="'+o3_cellpad+'" ':'')+'cellspacing="0" '+(o3_fgclass?'class="'+o3_fgclass+'"':o3_fgcolor+' '+o3_fgbackground+' '+o3_height)+'><tr><td valign="TOP"'+(o3_textfontclass?' class="'+o3_textfontclass+'">' :((!olNs4&&cpIsMultiple)?' style="'+setCellPadStr(o3_cellpad)+'">':'>'))+(o3_textfontclass?'':wrapStr(0,o3_textsize,'text'))+text+(o3_textfontclass?'':wrapStr(1,o3_textsize))+'</td></tr></table></td></tr></table>';
    set_background("");return txt;}
    function ol_content_background(text,picture,hasfullhtml){if(hasfullhtml){txt=text;}else{txt='<table width="'+o3_width+'" border="0" cellpadding="0" cellspacing="0" height="'+o3_height+'"><tr><td colspan="3" height="'+o3_padyt+'"></td></tr><tr><td width="'+o3_padxl+'"></td><td valign="TOP" width="'+(o3_width-o3_padxl-o3_padxr)+(o3_textfontclass?'" class="'+o3_textfontclass:'')+'">'+(o3_textfontclass?'':wrapStr(0,o3_textsize,'text'))+text+(o3_textfontclass?'':wrapStr(1,o3_textsize))+'</td><td width="'+o3_padxr+'"></td></tr><tr><td colspan="3" height="'+o3_padyb+'"></td></tr></table>';}
    set_background(picture);return txt;}
    function set_background(pic){if(pic==""){if(olNs4){over.background.src=null;}else if(over.style){over.style.backgroundImage="none";}
    }else{if(olNs4){over.background.src=pic;}else if(over.style){over.style.width=o3_width+'px';over.style.backgroundImage="url("+pic+")";}}}
    var olShowId=-1;
    function disp(statustext){runHook("disp",FBEFORE);
    if(o3_allowmove==0){runHook("placeLayer",FREPLACE);(olNs6&&olShowId<0)?olShowId=setTimeout("runHook('showObject',FREPLACE,over)",1):runHook("showObject",FREPLACE,over);o3_allowmove=(o3_sticky||o3_followmouse==0)?0:1;}
    runHook("disp",FAFTER);
    if(statustext!="")self.status=statustext;}
    function createPopup(lyrContent){runHook("createPopup",FBEFORE);
    if(o3_wrap){var wd,ww,theObj=(olNs4?over:over.style);theObj.top=theObj.left=((olIe4&&!olOp)?0:-10000)+(!olNs4?'px':0);layerWrite(lyrContent);wd=(olNs4?over.clip.width:over.offsetWidth);if(wd>(ww=windowWidth())){lyrContent=lyrContent.replace(/\&nbsp;/g,' ');o3_width=ww;o3_wrap=0;}}
    layerWrite(lyrContent);
    if(o3_wrap)o3_width=(olNs4?over.clip.width:over.offsetWidth);
    runHook("createPopup",FAFTER,lyrContent);
    return true;}
    function placeLayer(){var placeX,placeY,widthFix=0;
    if(o3_frame.innerWidth)widthFix=18;iwidth=windowWidth();
    winoffset=(olIe4)?eval('o3_frame.'+docRoot+'.scrollLeft'):o3_frame.pageXOffset;
    placeX=runHook('horizontalPlacement',FCHAIN,iwidth,winoffset,widthFix);
    if(o3_frame.innerHeight){iheight=o3_frame.innerHeight;}else if(eval('o3_frame.'+docRoot)&&eval("typeof o3_frame."+docRoot+".clientHeight=='number'")&&eval('o3_frame.'+docRoot+'.clientHeight')){iheight=eval('o3_frame.'+docRoot+'.clientHeight');}
    scrolloffset=(olIe4)?eval('o3_frame.'+docRoot+'.scrollTop'):o3_frame.pageYOffset;placeY=runHook('verticalPlacement',FCHAIN,iheight,scrolloffset);
    repositionTo(over,placeX,placeY);}
    function olMouseMove(e){var e=(e)?e:event;
    if(e.pageX){o3_x=e.pageX;o3_y=e.pageY;}else if(e.clientX){o3_x=eval('e.clientX+o3_frame.'+docRoot+'.scrollLeft');o3_y=eval('e.clientY+o3_frame.'+docRoot+'.scrollTop');}
    if(o3_allowmove==1)runHook("placeLayer",FREPLACE);
    if(hoveringSwitch&&!olNs4&&runHook("cursorOff",FREPLACE)){(olHideDelay?hideDelay(olHideDelay):cClick());hoveringSwitch=!hoveringSwitch;}}
    function no_overlib(){return ver3fix;}
    function olMouseCapture(){capExtent=document;var fN,str='',l,k,f,wMv,sS,mseHandler=olMouseMove;var re=/function[ ]*(\w*)\(/;
    wMv=(!olIe4&&window.onmousemove);if(document.onmousemove||wMv){if(wMv)capExtent=window;f=capExtent.onmousemove.toString();fN=f.match(re);if(fN==null){str=f+'(e);';}else if(fN[1]=='anonymous'||fN[1]=='olMouseMove'||(wMv&&fN[1]=='onmousemove')){if(!olOp&&wMv){l=f.indexOf('{')+1;k=f.lastIndexOf('}');sS=f.substring(l,k);if((l=sS.indexOf('('))!=-1){sS=sS.substring(0,l).replace(/^\s+/,'').replace(/\s+$/,'');if(eval("typeof "+sS+"=='undefined'"))window.onmousemove=null;else str=sS+'(e);';}}
    if(!str){olCheckMouseCapture=false;return;}
    }else{if(fN[1])str=fN[1]+'(e);';else{l=f.indexOf('{')+1;k=f.lastIndexOf('}');str=f.substring(l,k)+'\n';}}
    str+='olMouseMove(e);';mseHandler=new Function('e',str);}
    capExtent.onmousemove=mseHandler;if(olNs4)capExtent.captureEvents(Event.MOUSEMOVE);}
    function parseTokens(pf,ar){
    var v,i,mode=-1,par=(pf!='ol_'),fnMark=(par&&!ar.length?1:0);
    for(i=0;i<ar.length;i++){if(mode<0){
    if(typeof ar[i]=='number'&&ar[i]>pmStart&&ar[i]<pmUpper){fnMark=(par?1:0);i--;}else{switch(pf){case 'ol_':
    ol_text=ar[i].toString();break;default:
    o3_text=ar[i].toString();}}
    mode=0;}else{
    if(ar[i]>=pmCount||ar[i]==DONOTHING){continue;}
    if(ar[i]==INARRAY){fnMark=0;eval(pf+'text=ol_texts['+ar[++i]+'].toString()');continue;}
    if(ar[i]==CAPARRAY){eval(pf+'cap=ol_caps['+ar[++i]+'].toString()');continue;}
    if(ar[i]==STICKY){if(pf!='ol_')eval(pf+'sticky=1');continue;}
    if(ar[i]==BACKGROUND){eval(pf+'background="'+ar[++i]+'"');continue;}
    if(ar[i]==NOCLOSE){if(pf!='ol_')opt_NOCLOSE();continue;}
    if(ar[i]==CAPTION){eval(pf+"cap='"+escSglQuote(ar[++i])+"'");continue;}
    if(ar[i]==CENTER||ar[i]==LEFT||ar[i]==RIGHT){eval(pf+'hpos='+ar[i]);if(pf!='ol_')olHautoFlag=1;continue;}
    if(ar[i]==OFFSETX){eval(pf+'offsetx='+ar[++i]);continue;}
    if(ar[i]==OFFSETY){eval(pf+'offsety='+ar[++i]);continue;}
    if(ar[i]==FGCOLOR){eval(pf+'fgcolor="'+ar[++i]+'"');continue;}
    if(ar[i]==BGCOLOR){eval(pf+'bgcolor="'+ar[++i]+'"');continue;}
    if(ar[i]==TEXTCOLOR){eval(pf+'textcolor="'+ar[++i]+'"');continue;}
    if(ar[i]==CAPCOLOR){eval(pf+'capcolor="'+ar[++i]+'"');continue;}
    if(ar[i]==CLOSECOLOR){eval(pf+'closecolor="'+ar[++i]+'"');continue;}
    if(ar[i]==WIDTH){eval(pf+'width='+ar[++i]);continue;}
    if(ar[i]==BORDER){eval(pf+'border='+ar[++i]);continue;}
    if(ar[i]==CELLPAD){i=opt_MULTIPLEARGS(++i,ar,(pf+'cellpad'));continue;}
    if(ar[i]==STATUS){eval(pf+"status='"+escSglQuote(ar[++i])+"'");continue;}
    if(ar[i]==AUTOSTATUS){eval(pf+'autostatus=('+pf+'autostatus==1)?0:1');continue;}
    if(ar[i]==AUTOSTATUSCAP){eval(pf+'autostatus=('+pf+'autostatus==2)?0:2');continue;}
    if(ar[i]==HEIGHT){eval(pf+'height='+pf+'aboveheight='+ar[++i]);continue;}
    if(ar[i]==CLOSETEXT){eval(pf+"close='"+escSglQuote(ar[++i])+"'");continue;}
    if(ar[i]==SNAPX){eval(pf+'snapx='+ar[++i]);continue;}
    if(ar[i]==SNAPY){eval(pf+'snapy='+ar[++i]);continue;}
    if(ar[i]==FIXX){eval(pf+'fixx='+ar[++i]);continue;}
    if(ar[i]==FIXY){eval(pf+'fixy='+ar[++i]);continue;}
    if(ar[i]==RELX){eval(pf+'relx='+ar[++i]);continue;}
    if(ar[i]==RELY){eval(pf+'rely='+ar[++i]);continue;}
    if(ar[i]==FGBACKGROUND){eval(pf+'fgbackground="'+ar[++i]+'"');continue;}
    if(ar[i]==BGBACKGROUND){eval(pf+'bgbackground="'+ar[++i]+'"');continue;}
    if(ar[i]==PADX){eval(pf+'padxl='+ar[++i]);eval(pf+'padxr='+ar[++i]);continue;}
    if(ar[i]==PADY){eval(pf+'padyt='+ar[++i]);eval(pf+'padyb='+ar[++i]);continue;}
    if(ar[i]==FULLHTML){if(pf!='ol_')eval(pf+'fullhtml=1');continue;}
    if(ar[i]==BELOW||ar[i]==ABOVE){eval(pf+'vpos='+ar[i]);if(pf!='ol_')olVautoFlag=1;continue;}
    if(ar[i]==CAPICON){eval(pf+'capicon="'+ar[++i]+'"');continue;}
    if(ar[i]==TEXTFONT){eval(pf+"textfont='"+escSglQuote(ar[++i])+"'");continue;}
    if(ar[i]==CAPTIONFONT){eval(pf+"captionfont='"+escSglQuote(ar[++i])+"'");continue;}
    if(ar[i]==CLOSEFONT){eval(pf+"closefont='"+escSglQuote(ar[++i])+"'");continue;}
    if(ar[i]==TEXTSIZE){eval(pf+'textsize="'+ar[++i]+'"');continue;}
    if(ar[i]==CAPTIONSIZE){eval(pf+'captionsize="'+ar[++i]+'"');continue;}
    if(ar[i]==CLOSESIZE){eval(pf+'closesize="'+ar[++i]+'"');continue;}
    if(ar[i]==TIMEOUT){eval(pf+'timeout='+ar[++i]);continue;}
    if(ar[i]==FUNCTION){if(pf=='ol_'){if(typeof ar[i+1]!='number'){v=ar[++i];ol_function=(typeof v=='function'?v:null);}}else{fnMark=0;v=null;if(typeof ar[i+1]!='number')v=ar[++i]; opt_FUNCTION(v);} continue;}
    if(ar[i]==DELAY){eval(pf+'delay='+ar[++i]);continue;}
    if(ar[i]==HAUTO){eval(pf+'hauto=('+pf+'hauto==0)?1:0');continue;}
    if(ar[i]==VAUTO){eval(pf+'vauto=('+pf+'vauto==0)?1:0');continue;}
    if(ar[i]==CLOSECLICK){eval(pf+'closeclick=('+pf+'closeclick==0)?1:0');continue;}
    if(ar[i]==WRAP){eval(pf+'wrap=('+pf+'wrap==0)?1:0');continue;}
    if(ar[i]==FOLLOWMOUSE){eval(pf+'followmouse=('+pf+'followmouse==1)?0:1');continue;}
    if(ar[i]==MOUSEOFF){eval(pf+'mouseoff=('+pf+'mouseoff==0)?1:0');v=ar[i+1];if(pf!='ol_'&&eval(pf+'mouseoff')&&typeof v=='number'&&(v<pmStart||v>pmUpper))olHideDelay=ar[++i];continue;}
    if(ar[i]==CLOSETITLE){eval(pf+"closetitle='"+escSglQuote(ar[++i])+"'");continue;}
    if(ar[i]==CSSOFF||ar[i]==CSSCLASS){eval(pf+'css='+ar[i]);continue;}
    if(ar[i]==COMPATMODE){eval(pf+'compatmode=('+pf+'compatmode==0)?1:0');continue;}
    if(ar[i]==FGCLASS){eval(pf+'fgclass="'+ar[++i]+'"');continue;}
    if(ar[i]==BGCLASS){eval(pf+'bgclass="'+ar[++i]+'"');continue;}
    if(ar[i]==TEXTFONTCLASS){eval(pf+'textfontclass="'+ar[++i]+'"');continue;}
    if(ar[i]==CAPTIONFONTCLASS){eval(pf+'captionfontclass="'+ar[++i]+'"');continue;}
    if(ar[i]==CLOSEFONTCLASS){eval(pf+'closefontclass="'+ar[++i]+'"');continue;}
    i=parseCmdLine(pf,i,ar);}}
    if(fnMark&&o3_function)o3_text=o3_function();
    if((pf=='o3_')&&o3_wrap){o3_width=0;
    var tReg=/<.*\n*>/ig;if(!tReg.test(o3_text))o3_text=o3_text.replace(/[ ]+/g,'&nbsp;');if(!tReg.test(o3_cap))o3_cap=o3_cap.replace(/[ ]+/g,'&nbsp;');}
    if((pf=='o3_')&&o3_sticky){if(!o3_close&&(o3_frame!=ol_frame))o3_close=ol_close;if(o3_mouseoff&&(o3_frame==ol_frame))opt_NOCLOSE(' ');}}
    function layerWrite(txt){txt+="\n";if(olNs4){var lyr=o3_frame.document.layers['overDiv'].document
    lyr.write(txt)
    lyr.close()
    }else if(typeof over.innerHTML!='undefined'){if(olIe5&&isMac)over.innerHTML='';over.innerHTML=txt;}else{range=o3_frame.document.createRange();range.setStartAfter(over);domfrag=range.createContextualFragment(txt);
    while(over.hasChildNodes()){over.removeChild(over.lastChild);}
    over.appendChild(domfrag);}}
    function showObject(obj){runHook("showObject",FBEFORE);
    var theObj=(olNs4?obj:obj.style);theObj.visibility='visible';
    runHook("showObject",FAFTER);}
    function hideObject(obj){runHook("hideObject",FBEFORE);
    var theObj=(olNs4?obj:obj.style);if(olNs6&&olShowId>0){clearTimeout(olShowId);olShowId=0;}
    theObj.visibility='hidden';theObj.top=theObj.left=((olIe4&&!olOp)?0:-10000)+(!olNs4?'px':0);
    if(o3_timerid>0)clearTimeout(o3_timerid);if(o3_delayid>0)clearTimeout(o3_delayid);
    o3_timerid=0;o3_delayid=0;self.status="";
    if(obj.onmouseout||obj.onmouseover){if(olNs4)obj.releaseEvents(Event.MOUSEOUT||Event.MOUSEOVER);obj.onmouseout=obj.onmouseover=null;}
    runHook("hideObject",FAFTER);}
    function repositionTo(obj,xL,yL){var theObj=(olNs4?obj:obj.style);theObj.left=xL+(!olNs4?'px':0);theObj.top=yL+(!olNs4?'px':0);}
    function cursorOff(){var left=parseInt(over.style.left);var top=parseInt(over.style.top);var right=left+(over.offsetWidth>=parseInt(o3_width)?over.offsetWidth:parseInt(o3_width));var bottom=top+(over.offsetHeight>=o3_aboveheight?over.offsetHeight:o3_aboveheight);
    if(o3_x<left||o3_x>right||o3_y<top||o3_y>bottom)return true;
    return false;}
    function opt_FUNCTION(callme){o3_text=(callme?(typeof callme=='string'?(/.+\(.*\)/.test(callme)?eval(callme):callme):callme()):(o3_function?o3_function():'No Function'));
    return 0;}
    function opt_NOCLOSE(unused){if(!unused)o3_close="";
    if(olNs4){over.captureEvents(Event.MOUSEOUT||Event.MOUSEOVER);over.onmouseover=function(){if(o3_timerid>0){clearTimeout(o3_timerid);o3_timerid=0;} }
    over.onmouseout=function(e){if(olHideDelay)hideDelay(olHideDelay);else cClick(e);}
    }else{over.onmouseover=function(){hoveringSwitch=true;if(o3_timerid>0){clearTimeout(o3_timerid);o3_timerid=0;} }}
    return 0;}
    function opt_MULTIPLEARGS(i,args,parameter){var k=i,re,pV,str='';
    for(k=i;k<args.length;k++){if(typeof args[k]=='number'&&args[k]>pmStart)break;str+=args[k]+',';}
    if(str)str=str.substring(0,--str.length);
    k--;pV=(olNs4&&/cellpad/i.test(parameter))?str.split(',')[0]:str;eval(parameter+'="'+pV+'"');
    return k;}
    function nbspCleanup(){if(o3_wrap){o3_text=o3_text.replace(/\&nbsp;/g,' ');o3_cap=o3_cap.replace(/\&nbsp;/g,' ');}}
    function escSglQuote(str){return str.toString().replace(/'/g,"\\'");}
    function OLonLoad_handler(e){var re=/\w+\(.*\)[;\s]+/g,olre=/overlib\(|nd\(|cClick\(/,fn,l,i;
    if(!olLoaded)olLoaded=1;
    if(window.removeEventListener&&e.eventPhase==3)window.removeEventListener("load",OLonLoad_handler,false);else if(window.detachEvent){window.detachEvent("onload",OLonLoad_handler);var fN=document.body.getAttribute('onload');if(fN){fN=fN.toString().match(re);if(fN&&fN.length){for(i=0;i<fN.length;i++){if(/anonymous/.test(fN[i]))continue;while((l=fN[i].search(/\)[;\s]+/))!=-1){fn=fN[i].substring(0,l+1);fN[i]=fN[i].substring(l+2);if(olre.test(fn))eval(fn);}}}}}}
    function wrapStr(endWrap,fontSizeStr,whichString){var fontStr,fontColor,isClose=((whichString=='close')?1:0),hasDims=/[%\-a-z]+$/.test(fontSizeStr);fontSizeStr=(olNs4)?(!hasDims?fontSizeStr:'1'):fontSizeStr;if(endWrap)return(hasDims&&!olNs4)?(isClose?'</span>':'</div>'):'</font>';else{fontStr='o3_'+whichString+'font';fontColor='o3_'+((whichString=='caption')? 'cap':whichString)+'color';return(hasDims&&!olNs4)?(isClose?'<span style="font-family: '+quoteMultiNameFonts(eval(fontStr))+';color: '+eval(fontColor)+';font-size: '+fontSizeStr+';">':'<div style="font-family: '+quoteMultiNameFonts(eval(fontStr))+';color: '+eval(fontColor)+';font-size: '+fontSizeStr+';">'):'<font face="'+eval(fontStr)+'" color="'+eval(fontColor)+'" size="'+(parseInt(fontSizeStr)>7?'7':fontSizeStr)+'">';}}
    function quoteMultiNameFonts(theFont){var v,pM=theFont.split(',');for(var i=0;i<pM.length;i++){v=pM[i];v=v.replace(/^\s+/,'').replace(/\s+$/,'');if(/\s/.test(v)&&!/['"]/.test(v)){v="\'"+v+"\'";pM[i]=v;}}
    return pM.join();}
    function isExclusive(args){return false;}
    function setCellPadStr(parameter){var Str='',j=0,ary=new Array(),top,bottom,left,right;
    Str+='padding: ';ary=parameter.replace(/\s+/g,'').split(',');
    switch(ary.length){case 2:
    top=bottom=ary[j];left=right=ary[++j];break;case 3:
    top=ary[j];left=right=ary[++j];bottom=ary[++j];break;case 4:
    top=ary[j];right=ary[++j];bottom=ary[++j];left=ary[++j];break;}
    Str+=((ary.length==1)?ary[0]+'px;':top+'px '+right+'px '+bottom+'px '+left+'px;');
    return Str;}
    function hideDelay(time){if(time&&!o3_delay){if(o3_timerid>0)clearTimeout(o3_timerid);
    o3_timerid=setTimeout("cClick()",(o3_timeout=time));}}
    function horizontalPlacement(browserWidth,horizontalScrollAmount,widthFix){var placeX,iwidth=browserWidth,winoffset=horizontalScrollAmount;var parsedWidth=parseInt(o3_width);
    if(o3_fixx>-1||o3_relx!=null){
    placeX=(o3_relx!=null?( o3_relx<0?winoffset+o3_relx+iwidth-parsedWidth-widthFix:winoffset+o3_relx):o3_fixx);}else{
    if(o3_hauto==1){if((o3_x-winoffset)>(iwidth/2)){o3_hpos=LEFT;}else{o3_hpos=RIGHT;}}
    if(o3_hpos==CENTER){placeX=o3_x+o3_offsetx-(parsedWidth/2);
    if(placeX<winoffset)placeX=winoffset;}
    if(o3_hpos==RIGHT){placeX=o3_x+o3_offsetx;
    if((placeX+parsedWidth)>(winoffset+iwidth-widthFix)){placeX=iwidth+winoffset-parsedWidth-widthFix;if(placeX<0)placeX=0;}}
    if(o3_hpos==LEFT){placeX=o3_x-o3_offsetx-parsedWidth;if(placeX<winoffset)placeX=winoffset;}
    if(o3_snapx>1){var snapping=placeX % o3_snapx;
    if(o3_hpos==LEFT){placeX=placeX-(o3_snapx+snapping);}else{
    placeX=placeX+(o3_snapx-snapping);}
    if(placeX<winoffset)placeX=winoffset;}}
    return placeX;}
    function verticalPlacement(browserHeight,verticalScrollAmount){var placeY,iheight=browserHeight,scrolloffset=verticalScrollAmount;var parsedHeight=(o3_aboveheight?parseInt(o3_aboveheight):(olNs4?over.clip.height:over.offsetHeight));
    if(o3_fixy>-1||o3_rely!=null){
    placeY=(o3_rely!=null?(o3_rely<0?scrolloffset+o3_rely+iheight-parsedHeight:scrolloffset+o3_rely):o3_fixy);}else{
    if(o3_vauto==1){if((o3_y-scrolloffset)>(iheight/2)&&o3_vpos==BELOW&&(o3_y+parsedHeight+o3_offsety-(scrolloffset+iheight)>0)){o3_vpos=ABOVE;}else if(o3_vpos==ABOVE&&(o3_y-(parsedHeight+o3_offsety)-scrolloffset<0)){o3_vpos=BELOW;}}
    if(o3_vpos==ABOVE){if(o3_aboveheight==0)o3_aboveheight=parsedHeight;
    placeY=o3_y-(o3_aboveheight+o3_offsety);if(placeY<scrolloffset)placeY=scrolloffset;}else{
    placeY=o3_y+o3_offsety;}
    if(o3_snapy>1){var snapping=placeY % o3_snapy;
    if(o3_aboveheight>0&&o3_vpos==ABOVE){placeY=placeY-(o3_snapy+snapping);}else{placeY=placeY+(o3_snapy-snapping);}
    if(placeY<scrolloffset)placeY=scrolloffset;}}
    return placeY;}
    function checkPositionFlags(){if(olHautoFlag)olHautoFlag=o3_hauto=0;if(olVautoFlag)olVautoFlag=o3_vauto=0;return true;}
    function windowWidth(){var w;if(o3_frame.innerWidth)w=o3_frame.innerWidth;else if(eval('o3_frame.'+docRoot)&&eval("typeof o3_frame."+docRoot+".clientWidth=='number'")&&eval('o3_frame.'+docRoot+'.clientWidth'))
    w=eval('o3_frame.'+docRoot+'.clientWidth');return w;}
    function createDivContainer(id,frm,zValue){id=(id||'overDiv'),frm=(frm||o3_frame),zValue=(zValue||1000);var objRef,divContainer=layerReference(id);
    if(divContainer==null){if(olNs4){divContainer=frm.document.layers[id]=new Layer(window.innerWidth,frm);objRef=divContainer;}else{var body=(olIe4?frm.document.all.tags('BODY')[0]:frm.document.getElementsByTagName("BODY")[0]);if(olIe4&&!document.getElementById){body.insertAdjacentHTML("beforeEnd",'<div id="'+id+'"></div>');divContainer=layerReference(id);}else{divContainer=frm.document.createElement("DIV");divContainer.id=id;body.appendChild(divContainer);}
    objRef=divContainer.style;}
    objRef.position='absolute';objRef.visibility='hidden';objRef.zIndex=zValue;if(olIe4&&!olOp)objRef.left=objRef.top='0px';else objRef.left=objRef.top=-10000+(!olNs4?'px':0);}
    return divContainer;}
    function layerReference(id){return(olNs4?o3_frame.document.layers[id]:(document.all?o3_frame.document.all[id]:o3_frame.document.getElementById(id)));}
    function isFunction(fnRef){var rtn=true;
    if(typeof fnRef=='object'){for(var i=0;i<fnRef.length;i++){if(typeof fnRef[i]=='function')continue;rtn=false;break;}
    }else if(typeof fnRef!='function'){rtn=false;}
    return rtn;}
    function argToString(array,strtInd,argName){var jS=strtInd,aS='',ar=array;argName=(argName?argName:'ar');
    if(ar.length>jS){for(var k=jS;k<ar.length;k++)aS+=argName+'['+k+'], ';aS=aS.substring(0,aS.length-2);}
    return aS;}
    function reOrder(hookPt,fnRef,order){var newPt=new Array(),match,i,j;
    if(!order||typeof order=='undefined'||typeof order=='number')return hookPt;
    if(typeof order=='function'){if(typeof fnRef=='object'){newPt=newPt.concat(fnRef);}else{newPt[newPt.length++]=fnRef;}
    for(i=0;i<hookPt.length;i++){match=false;if(typeof fnRef=='function'&&hookPt[i]==fnRef){continue;}else{for(j=0;j<fnRef.length;j++)if(hookPt[i]==fnRef[j]){match=true;break;}}
    if(!match)newPt[newPt.length++]=hookPt[i];}
    newPt[newPt.length++]=order;
    }else if(typeof order=='object'){if(typeof fnRef=='object'){newPt=newPt.concat(fnRef);}else{newPt[newPt.length++]=fnRef;}
    for(j=0;j<hookPt.length;j++){match=false;if(typeof fnRef=='function'&&hookPt[j]==fnRef){continue;}else{for(i=0;i<fnRef.length;i++)if(hookPt[j]==fnRef[i]){match=true;break;}}
    if(!match)newPt[newPt.length++]=hookPt[j];}
    for(i=0;i<newPt.length;i++)hookPt[i]=newPt[i];newPt.length=0;
    for(j=0;j<hookPt.length;j++){match=false;for(i=0;i<order.length;i++){if(hookPt[j]==order[i]){match=true;break;}}
    if(!match)newPt[newPt.length++]=hookPt[j];}
    newPt=newPt.concat(order);}
    hookPt=newPt;
    return hookPt;}
    function setRunTimeVariables(){if(typeof runTime!='undefined'&&runTime.length){for(var k=0;k<runTime.length;k++){runTime[k]();}}}
    function parseCmdLine(pf,i,args){if(typeof cmdLine!='undefined'&&cmdLine.length){for(var k=0;k<cmdLine.length;k++){var j=cmdLine[k](pf,i,args);if(j >-1){i=j;break;}}}
    return i;}
    function postParseChecks(pf,args){if(typeof postParse!='undefined'&&postParse.length){for(var k=0;k<postParse.length;k++){if(postParse[k](pf,args))continue;return false;}}
    return true;}
    function registerCommands(cmdStr){if(typeof cmdStr!='string')return;
    var pM=cmdStr.split(',');pms=pms.concat(pM);
    for(var i=0;i< pM.length;i++){eval(pM[i].toUpperCase()+'='+pmCount++);}}
    function registerNoParameterCommands(cmdStr){if(!cmdStr&&typeof cmdStr!='string')return;pmt=(!pmt)?cmdStr:pmt+','+cmdStr;}
    function registerHook(fnHookTo,fnRef,hookType,optPm){var hookPt,last=typeof optPm;
    if(fnHookTo=='plgIn'||fnHookTo=='postParse')return;if(typeof hookPts[fnHookTo]=='undefined')hookPts[fnHookTo]=new FunctionReference();
    hookPt=hookPts[fnHookTo];
    if(hookType!=null){if(hookType==FREPLACE){hookPt.ovload=fnRef;if(fnHookTo.indexOf('ol_content_')>-1)hookPt.alt[pms[CSSOFF-1-pmStart]]=fnRef;
    }else if(hookType==FBEFORE||hookType==FAFTER){var hookPt=(hookType==1?hookPt.before:hookPt.after);
    if(typeof fnRef=='object'){hookPt=hookPt.concat(fnRef);}else{hookPt[hookPt.length++]=fnRef;}
    if(optPm)hookPt=reOrder(hookPt,fnRef,optPm);
    }else if(hookType==FALTERNATE){if(last=='number')hookPt.alt[pms[optPm-1-pmStart]]=fnRef;}else if(hookType==FCHAIN){hookPt=hookPt.chain;if(typeof fnRef=='object')hookPt=hookPt.concat(fnRef);else hookPt[hookPt.length++]=fnRef;}
    return;}}
    function registerRunTimeFunction(fn){if(isFunction(fn)){if(typeof fn=='object'){runTime=runTime.concat(fn);}else{runTime[runTime.length++]=fn;}}}
    function registerCmdLineFunction(fn){if(isFunction(fn)){if(typeof fn=='object'){cmdLine=cmdLine.concat(fn);}else{cmdLine[cmdLine.length++]=fn;}}}
    function registerPostParseFunction(fn){if(isFunction(fn)){if(typeof fn=='object'){postParse=postParse.concat(fn);}else{postParse[postParse.length++]=fn;}}}
    function runHook(fnHookTo,hookType){var l=hookPts[fnHookTo],k,rtnVal=null,optPm,arS,ar=runHook.arguments;
    if(hookType==FREPLACE){arS=argToString(ar,2);
    if(typeof l=='undefined'||!(l=l.ovload))rtnVal=eval(fnHookTo+'('+arS+')');else rtnVal=eval('l('+arS+')');
    }else if(hookType==FBEFORE||hookType==FAFTER){if(typeof l!='undefined'){l=(hookType==1?l.before:l.after);
    if(l.length){arS=argToString(ar,2);for(var k=0;k<l.length;k++)eval('l[k]('+arS+')');}}
    }else if(hookType==FALTERNATE){optPm=ar[2];arS=argToString(ar,3);
    if(typeof l=='undefined'||(l=l.alt[pms[optPm-1-pmStart]])=='undefined'){rtnVal=eval(fnHookTo+'('+arS+')');}else{rtnVal=eval('l('+arS+')');}
    }else if(hookType==FCHAIN){arS=argToString(ar,2);l=l.chain;
    for(k=l.length;k>0;k--)if((rtnVal=eval('l[k-1]('+arS+')'))!=void(0))break;}
    return rtnVal;}
    function FunctionReference(){this.ovload=null;this.before=new Array();this.after=new Array();this.alt=new Array();this.chain=new Array();}
    function Info(version,prerelease){this.version=version;this.prerelease=prerelease;
    this.simpleversion=Math.round(this.version*100);this.major=parseInt(this.simpleversion/100);this.minor=parseInt(this.simpleversion/10)-this.major * 10;this.revision=parseInt(this.simpleversion)-this.major * 100-this.minor * 10;this.meets=meets;}
    function meets(reqdVersion){return(!reqdVersion)?false:this.simpleversion>=Math.round(100*parseFloat(reqdVersion));}
    registerHook("ol_content_simple",ol_content_simple,FALTERNATE,CSSOFF);registerHook("ol_content_caption",ol_content_caption,FALTERNATE,CSSOFF);registerHook("ol_content_background",ol_content_background,FALTERNATE,CSSOFF);registerHook("ol_content_simple",ol_content_simple,FALTERNATE,CSSCLASS);registerHook("ol_content_caption",ol_content_caption,FALTERNATE,CSSCLASS);registerHook("ol_content_background",ol_content_background,FALTERNATE,CSSCLASS);registerPostParseFunction(checkPositionFlags);registerHook("hideObject",nbspCleanup,FAFTER);registerHook("horizontalPlacement",horizontalPlacement,FCHAIN);registerHook("verticalPlacement",verticalPlacement,FCHAIN);if(olNs4||(olIe5&&isMac)||olKq)olLoaded=1;registerNoParameterCommands('sticky,autostatus,autostatuscap,fullhtml,hauto,vauto,closeclick,wrap,followmouse,mouseoff,compatmode');
    var olCheckMouseCapture=true;if((olNs4||olNs6||olIe4)){olMouseCapture();}else{overlib=no_overlib;nd=no_overlib;ver3fix=true;}// --FILE BOUNDARY-- // --FILE BOUNDARY-- // --FILE BOUNDARY--
    /**************************************************
     * dom-drag.js
     * 09.25.2001
     * www.youngpup.net
     **************************************************
     * 10.28.2001 - fixed minor bug where events
     * sometimes fired off the handle, not the root.
     **************************************************/

    // Minor modifications by [[User:Lupin]]

    var Drag = {

        obj : null,

        init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
        {
            o.onmousedown    = Drag.start;
            o.dragging       = false;
            o.draggable      = true;
            o.hmode          = bSwapHorzRef ? false : true ;
            o.vmode          = bSwapVertRef ? false : true ;

            o.root = oRoot && oRoot != null ? oRoot : o ;

            if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
            if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
            if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
            if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";

            o.minX    = typeof minX != 'undefined' ? minX : null;
            o.minY    = typeof minY != 'undefined' ? minY : null;
            o.maxX    = typeof maxX != 'undefined' ? maxX : null;
            o.maxY    = typeof maxY != 'undefined' ? maxY : null;

            o.xMapper = fXMapper ? fXMapper : null;
            o.yMapper = fYMapper ? fYMapper : null;

            o.root.onDragStart    = new Function();
            o.root.onDragEnd    = new Function();
            o.root.onDrag        = new Function();
        },

        start : function(e)
        {
            var o = Drag.obj = this;
            e = Drag.fixE(e);
            var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
            var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
            o.root.onDragStart(x, y);

            o.lastMouseX    = e.clientX;
            o.lastMouseY    = e.clientY;

            if (o.hmode) {
                if (o.minX != null)    o.minMouseX    = e.clientX - x + o.minX;
                if (o.maxX != null)    o.maxMouseX    = o.minMouseX + o.maxX - o.minX;
            } else {
                if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
                if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
            }

            if (o.vmode) {
                if (o.minY != null)    o.minMouseY    = e.clientY - y + o.minY;
                if (o.maxY != null)    o.maxMouseY    = o.minMouseY + o.maxY - o.minY;
            } else {
                if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
                if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
            }

            o.onmousemoveDefault    = document.onmousemove;
            o.dragging              = true;
            document.onmousemove    = Drag.drag;
            document.onmouseup      = Drag.end;

            return false;
        },

        drag : function(e)
        {
            e = Drag.fixE(e);
            var o = Drag.obj;

            var ey    = e.clientY;
            var ex    = e.clientX;
            var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
            var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
            var nx, ny;

            if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
            if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
            if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
            if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

            nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
            ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

            if (o.xMapper)        nx = o.xMapper(y)
            else if (o.yMapper)    ny = o.yMapper(x)

            Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
            Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
            Drag.obj.lastMouseX    = ex;
            Drag.obj.lastMouseY    = ey;

            Drag.obj.root.onDrag(nx, ny);
            return false;
        },

        end : function()
        {
            //Document.onmousemove = null;
            document.onmousemove=Drag.obj.onmousemoveDefault;
            document.onmouseup   = null;
            Drag.obj.dragging    = false;
            Drag.obj.root.onDragEnd(    parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]),
                                        parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
            Drag.obj = null;
        },

        fixE : function(e)
        {
            if (typeof e == 'undefined') e = window.event;
            if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
            if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
            return e;
        }
    };

    // Copyright Aaron Boodman. Saying stupid things daily since March 2001.

由 "http://zh-yue.wikipedia.org../../../j/a/s/User%7EJasonzhuocn_popups.js_fe52.html" 接收

##### Views

- 用戶頁
- 討論
- 家下嘅版本

##### 交流

- 關於維基百科
- 社區大堂
- 城市論壇
- 詢問處
- 聯絡我哋
- 慷慨解囊
- 幫手

##### 搵嘢