├── tool-labs ├── content │ ├── favicon.ico │ ├── sidebar-bg.gif │ ├── dataTables │ │ ├── asc.gif │ │ ├── bg.gif │ │ ├── desc.gif │ │ └── jquery.dataTables.plain.css │ ├── tablesorter │ │ ├── bg.gif │ │ ├── asc.gif │ │ ├── desc.gif │ │ └── style.css │ ├── main.js │ ├── regex │ │ └── jsresyntaxhighlighter.css │ └── jquery.multiselect │ │ └── jquery.multiselect.css ├── pgkbot │ ├── pgkbot_1.1.zip │ ├── pgkbot_1.2.zip │ ├── pgkbot_1.3.zip │ ├── pgkbot_1.4.zip │ ├── pgkbot_1.5.zip │ ├── pgkbot_1.6.zip │ ├── pgkbot_1.7.zip │ ├── stylesheet.css │ └── index.php ├── magicredirect │ └── stylesheet.css ├── backend │ ├── notice.php │ ├── modules │ │ ├── external │ │ │ ├── README.md │ │ │ └── mediawiki-globalfunctions.php │ │ ├── Logger.php │ │ ├── Form.php │ │ ├── Base.php │ │ ├── Profiler.php │ │ ├── __config__.php │ │ ├── Wikimedia.php │ │ └── IPAddress.php │ └── models │ │ ├── GlobalUser.php │ │ ├── LocalUser.php │ │ └── Wiki.php ├── globalgroups │ ├── stylesheet.css │ └── framework │ │ └── GlobalGroupsEngine.php ├── userpages │ ├── stylesheet.css │ ├── scripts.js │ └── index.php ├── .lighttpd.legacy-crossactivity.conf ├── stewardry │ ├── scripts.js │ ├── index.php │ └── framework │ │ └── StewardryEngine.php ├── accounteligibility │ ├── framework │ │ ├── localRules │ │ │ ├── NotBotRule.php │ │ │ ├── LocalRule.php │ │ │ ├── CustomRule.php │ │ │ ├── DateRegisteredRule.php │ │ │ ├── HasGroupRule.php │ │ │ ├── NotBlockedRule.php │ │ │ └── AccountAgeRule.php │ │ ├── constants │ │ │ ├── Workflow.php │ │ │ └── Result.php │ │ ├── globalRules │ │ │ ├── GlobalRule.php │ │ │ ├── HasGlobalAccountRule.php │ │ │ ├── NotGloballyLockedRule.php │ │ │ └── NotGloballyBlockedRule.php │ │ ├── GlobalRuleManager.php │ │ ├── models │ │ │ ├── ResultInfo.php │ │ │ ├── LocalRuleEntry.php │ │ │ ├── DateWrapper.php │ │ │ └── Event.php │ │ └── LocalRuleManager.php │ └── stylesheet.css ├── stalktoy │ ├── framework │ │ └── models │ │ │ ├── GlobalIP.php │ │ │ ├── Block.php │ │ │ ├── GlobalAccountStats.php │ │ │ ├── GlobalAccount.php │ │ │ └── LocalAccount.php │ ├── stylesheet.css │ └── scripts.js ├── gusersearch │ ├── javascript.js │ └── stylesheet.css ├── iso639db │ ├── scripts.js │ ├── stylesheet.css │ ├── index.php │ └── framework │ │ └── Iso639dbEngine.php ├── catanalysis │ ├── stylesheet.css │ └── framework │ │ └── models │ │ ├── UserData.php │ │ ├── PageData.php │ │ ├── Metrics.php │ │ └── MonthMetrics.php ├── .lighttpd.meta3.conf ├── .lighttpd.meta2.conf ├── .lighttpd.meta.conf ├── crossactivity │ ├── framework │ │ └── CrossactivityEngine.php │ └── index.php └── toolinfo.json ├── .gitignore ├── user-scripts ├── .jshintrc ├── pathoschild.ajaxsysop.css ├── dependencies │ ├── regex-colorizer.css │ └── WebConsole.js ├── i18n │ ├── zh-hans.js │ ├── ja.js │ ├── sr-ec.js │ ├── sr-el.js │ ├── ur.js │ ├── ru.js │ ├── es.js │ ├── th.js │ ├── bn.js │ ├── ca.js │ ├── de.js │ ├── fr.js │ ├── it.js │ ├── pt.js │ └── en.js ├── pathoschild.forceltr.js ├── toolinfo.json ├── templates │ └── pathoschild.templatescript.settings.htm ├── pathoschild.usejs.js ├── pathoschild.regexeditor.css └── pathoschild.ajaxtransclusiontable.js └── LICENSE.txt /tool-labs/content/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/favicon.ico -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.cs 2 | *.csproj 3 | *.phpproj 4 | *.sln 5 | *.suo 6 | *.user 7 | bin/ 8 | obj/ 9 | .data/ 10 | .idea/ 11 | -------------------------------------------------------------------------------- /tool-labs/pgkbot/pgkbot_1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/pgkbot/pgkbot_1.1.zip -------------------------------------------------------------------------------- /tool-labs/pgkbot/pgkbot_1.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/pgkbot/pgkbot_1.2.zip -------------------------------------------------------------------------------- /tool-labs/pgkbot/pgkbot_1.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/pgkbot/pgkbot_1.3.zip -------------------------------------------------------------------------------- /tool-labs/pgkbot/pgkbot_1.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/pgkbot/pgkbot_1.4.zip -------------------------------------------------------------------------------- /tool-labs/pgkbot/pgkbot_1.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/pgkbot/pgkbot_1.5.zip -------------------------------------------------------------------------------- /tool-labs/pgkbot/pgkbot_1.6.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/pgkbot/pgkbot_1.6.zip -------------------------------------------------------------------------------- /tool-labs/pgkbot/pgkbot_1.7.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/pgkbot/pgkbot_1.7.zip -------------------------------------------------------------------------------- /tool-labs/content/sidebar-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/sidebar-bg.gif -------------------------------------------------------------------------------- /tool-labs/content/dataTables/asc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/dataTables/asc.gif -------------------------------------------------------------------------------- /tool-labs/content/dataTables/bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/dataTables/bg.gif -------------------------------------------------------------------------------- /tool-labs/content/tablesorter/bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/tablesorter/bg.gif -------------------------------------------------------------------------------- /tool-labs/content/dataTables/desc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/dataTables/desc.gif -------------------------------------------------------------------------------- /tool-labs/content/tablesorter/asc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/tablesorter/asc.gif -------------------------------------------------------------------------------- /tool-labs/content/tablesorter/desc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pathoschild/Wikimedia-contrib/HEAD/tool-labs/content/tablesorter/desc.gif -------------------------------------------------------------------------------- /tool-labs/magicredirect/stylesheet.css: -------------------------------------------------------------------------------- 1 | #token-documentation { 2 | color: gray; 3 | font-size: small; 4 | padding-left: 1em; 5 | } 6 | -------------------------------------------------------------------------------- /tool-labs/pgkbot/stylesheet.css: -------------------------------------------------------------------------------- 1 | #editor { 2 | width: 100%; 3 | height: 30em; 4 | } 5 | 6 | #tsre { 7 | border: none !important; 8 | } 9 | 10 | #tsre h3, #tsre p { 11 | display: none; 12 | } 13 | -------------------------------------------------------------------------------- /tool-labs/backend/notice.php: -------------------------------------------------------------------------------- 1 | ', $message, ''; 11 | } -------------------------------------------------------------------------------- /tool-labs/globalgroups/stylesheet.css: -------------------------------------------------------------------------------- 1 | .group { 2 | margin-left: 2em; 3 | margin-bottom: 1em; 4 | } 5 | 6 | ul { 7 | margin-top: 0; 8 | } 9 | 10 | .group-rights { 11 | margin-left: 1em; 12 | } 13 | 14 | .group-rights-name, 15 | .group-rights-blurb { 16 | font-size: 0.9em; 17 | } 18 | 19 | .group-rights-name { 20 | color: gray; 21 | font-size: 0.9em; 22 | } 23 | 24 | table tr { 25 | border: 0 !important; 26 | } 27 | -------------------------------------------------------------------------------- /tool-labs/userpages/stylesheet.css: -------------------------------------------------------------------------------- 1 | li[data-redirect="1"], li[data-redirect="1"] a { 2 | font-style: italic; 3 | color: gray; 4 | } 5 | 6 | .filter { 7 | background: #EEE; 8 | border: 1px solid #CCC; 9 | border-radius: 5px; 10 | padding: 3px 5px; 11 | color: #CCC; 12 | text-decoration: none; 13 | } 14 | 15 | .filter.selected { 16 | background: #CFC; 17 | border-color: #0C0; 18 | color: #000; 19 | } 20 | -------------------------------------------------------------------------------- /tool-labs/.lighttpd.legacy-crossactivity.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This Lighttpd config is used for the deprecated `crossactivity` account. 3 | # 4 | 5 | # redirect to the main account 6 | url.redirect += ( 7 | "^(?:/crossactivity)?(.*)$" => "https://meta.toolforge.org/crossactivity$1" 8 | ) 9 | 10 | # enable status pages 11 | server.modules += ("mod_auth", "mod_status") 12 | status.status-url = "/server-status" 13 | status.statistics-url = "/server-statistics" 14 | -------------------------------------------------------------------------------- /tool-labs/stewardry/scripts.js: -------------------------------------------------------------------------------- 1 | /*jshint bitwise:true, eqeqeq:true, forin:false, immed:true, latedef:true, loopfunc:true, noarg:true, noempty:true, nonew:false, smarttabs:true, strict:true, trailing:true, undef:true*/ 2 | /*global $:true, google: true*/ 3 | var pathoschild = pathoschild || {}; 4 | (function () { 5 | "use strict"; 6 | 7 | $(function () { 8 | $(".sortable").tablesorter({sortList: [[1, 1], [2, 1]]}); 9 | }); 10 | }()); 11 | -------------------------------------------------------------------------------- /user-scripts/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "eqeqeq": true, 4 | "forin": false, 5 | "immed": true, 6 | "latedef": true, 7 | "noarg": true, 8 | "noempty": true, 9 | "nonew": true, 10 | "strict": true, 11 | "trailing": true, 12 | "undef": true, 13 | "unused": true, 14 | "quotmark": "single", 15 | 16 | "browser": true, 17 | "loopfunc": true, 18 | "laxbreak": true, 19 | "smarttabs": true, 20 | 21 | "predef": [ 22 | "mw", 23 | "$", 24 | "prompt" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tool-labs/accounteligibility/framework/localRules/NotBotRule.php: -------------------------------------------------------------------------------- 1 | negate = true; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tool-labs/stalktoy/framework/models/GlobalIP.php: -------------------------------------------------------------------------------- 1 | isLocked 21 | ? new ResultInfo(Result::FAIL, "globally locked.") 22 | : new ResultInfo(Result::PASS, "not globally locked."); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tool-labs/catanalysis/framework/models/MonthMetrics.php: -------------------------------------------------------------------------------- 1 | "https://meta.toolforge.org/$1$2", 9 | "^/(crossactivity)(.*)$" => "https://meta2.toolforge.org/$1$2", 10 | #"^/(stalktoy)(.*)$" => "https://meta3.toolforge.org/$1$2", 11 | 12 | # redirect root 13 | "^/?$" => "/stalktoy/", 14 | 15 | # prettify generated tool URLs that have a route version 16 | "^/stalktoy(?:/index.php|/)?\?target=([^&]+)$" => "/stalktoy/$1" 17 | ) 18 | 19 | # rewrite pretty URLs (e.g. /tool/a/b/c => /tool/index.php?@path=/a/b/c) 20 | url.rewrite-if-not-file += ( 21 | "^/stalktoy(/[^\?]+)(?:\?(.*))?$" => "/stalktoy/index.php?@path=$1&$2" 22 | ) 23 | 24 | # enable status pages 25 | server.modules += ("mod_auth", "mod_status") 26 | status.status-url = "/server-status" 27 | status.statistics-url = "/server-statistics" 28 | -------------------------------------------------------------------------------- /tool-labs/.lighttpd.meta2.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This Lighttpd config is used when deploying to the 'meta2' account, which only has Crossactivity 3 | # by default. See the README.md for usage. 4 | # 5 | 6 | url.redirect += ( 7 | # redirect to other tool accounts 8 | "^/(accounteligibility|catanalysis|globalgroups|gusersearch|iso639db|magicredirect|pgkbot|scripts|stewardry|userpages)(.*)$" => "https://meta.toolforge.org/$1$2", 9 | #"^/(crossactivity)(.*)$" => "https://meta2.toolforge.org/$1$2", 10 | "^/(stalktoy)(.*)$" => "https://meta3.toolforge.org/$1$2", 11 | 12 | # redirect root 13 | "^/?$" => "/crossactivity/", 14 | 15 | # prettify generated tool URLs that have a route version 16 | "^/crossactivity(?:/index.php|/)?\?user=([^&]+)$" => "/crossactivity/$1" 17 | ) 18 | 19 | # rewrite pretty URLs (e.g. /tool/a/b/c => /tool/index.php?@path=/a/b/c) 20 | url.rewrite-if-not-file += ( 21 | "^/crossactivity(/[^\?]*+)(?:\?(.*))?$" => "/crossactivity/index.php?@path=$1&$2" 22 | ) 23 | 24 | # enable status pages 25 | server.modules += ("mod_auth", "mod_status") 26 | status.status-url = "/server-status" 27 | status.statistics-url = "/server-statistics" 28 | -------------------------------------------------------------------------------- /user-scripts/dependencies/regex-colorizer.css: -------------------------------------------------------------------------------- 1 | /* 2 | Regex Colorizer RegexPal theme 3 | 4 | This CSS has been modified for Pathoschild's regex editor. The text colour has been changed 5 | to always match the background color, because the syntax-highlighted text is shown behind 6 | a transparent textbox containing the user's text. If the text isn't hidden, that causes 7 | the text to appear blurred. 8 | */ 9 | 10 | .regex {/*color: #000;*/ font-family: Consolas, "Source Code Pro", Monospace; white-space: pre-wrap; word-break: break-all; overflow-wrap: anywhere;} 11 | .regex b {font-weight: normal;} 12 | .regex i {font-style: normal;} 13 | .regex u {text-decoration: none;} 14 | 15 | /* metasequence */ 16 | .regex b {background: #aad1f7;} 17 | /* error */ 18 | .regex b.err {background: #ff4300;} 19 | 20 | /* char class */ 21 | .regex i {background: #f9ca69;} 22 | /* char class: metasequence */ 23 | .regex i b {background: #f7a700;} 24 | /* char class: range-hyphen */ 25 | .regex i u {background: #efba4a;} 26 | 27 | /* group: depth */ 28 | .regex b.g1 {background: #d2f854;} 29 | .regex b.g2 {background: #9ec70c;} 30 | .regex b.g3 {background: #ecc9f7;} 31 | .regex b.g4 {background: #54b70b;} 32 | .regex b.g5 {background: #b688cf;} -------------------------------------------------------------------------------- /tool-labs/stalktoy/framework/models/Block.php: -------------------------------------------------------------------------------- 1 | 56 | */ 57 | public array $wikiHash = []; 58 | } 59 | -------------------------------------------------------------------------------- /tool-labs/accounteligibility/framework/localRules/CustomRule.php: -------------------------------------------------------------------------------- 1 | accumulator = $accumulator; 29 | } 30 | 31 | /** 32 | * Collect information from a wiki and return whether the rule has been met. 33 | * @param Toolserver $db The database wrapper. 34 | * @param Wiki $wiki The current wiki. 35 | * @param LocalUser $user The local user account. 36 | * @return ResultInfo|null The eligibility check result, or null if the rule doesn't apply to this wiki. 37 | */ 38 | public function accumulate(Toolserver $db, Wiki $wiki, LocalUser $user): ?ResultInfo 39 | { 40 | return ($this->accumulator)($db, $wiki, $user); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tool-labs/globalgroups/framework/GlobalGroupsEngine.php: -------------------------------------------------------------------------------- 1 | $a The left group. 15 | * @param array<'members'|'rights'|'name', mixed> $b The right group. 16 | * @param 'members'|'name'|'permissions' $sortBy The field to sort by. 17 | */ 18 | function groupSort(array $a, array $b, string $sortBy): int 19 | { 20 | global $sort; 21 | switch ($sort) { 22 | case 'members': 23 | $countA = $a['members']; 24 | $countB = $b['members']; 25 | if ($countA == $countB) 26 | return 0; 27 | if ($countA < $countB) 28 | return 1; 29 | return -1; 30 | 31 | case 'permissions': 32 | $countA = count($a['rights']); 33 | $countB = count($b['rights']); 34 | if ($countA == $countB) 35 | return 0; 36 | if ($countA < $countB) 37 | return 1; 38 | return -1; 39 | 40 | default: 41 | return strcasecmp($a['name'], $b['name']); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tool-labs/accounteligibility/framework/globalRules/NotGloballyBlockedRule.php: -------------------------------------------------------------------------------- 1 | isGloballyBlocked($db, $user) 21 | ? new ResultInfo(Result::FAIL, "globally blocked.") 22 | : new ResultInfo(Result::PASS, "not globally blocked."); 23 | } 24 | 25 | 26 | ########## 27 | ## Private methods 28 | ########## 29 | /** 30 | * Get whether the user is globally blocked. 31 | * @param Toolserver $db The database wrapper. 32 | * @param GlobalUser $user The global user account. 33 | */ 34 | private function isGloballyBlocked(Toolserver $db, GlobalUser $user): bool 35 | { 36 | $db->query('SELECT 1 FROM centralauth_p.globalblocks WHERE gb_target_central_id = ? LIMIT 1', [$user->id]); 37 | return boolval($db->fetchColumn()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tool-labs/backend/modules/Logger.php: -------------------------------------------------------------------------------- 1 | key = $key; 37 | $this->logger = $enabled 38 | ? new KLogger($path, KLogger::DEBUG) 39 | : null; 40 | } 41 | 42 | /** 43 | * Write a message to the log. 44 | * @param string $message The message to log. 45 | */ 46 | public function log(string $message): void 47 | { 48 | if ($this->logger != null) { 49 | $message = "[{$this->key}] $message"; 50 | $this->logger->logInfo($message); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tool-labs/.lighttpd.meta.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This Lighttpd config is used when deploying to the 'meta' account, which has all tools except 3 | # Crossactivity by default. See the README.md for usage. 4 | # 5 | 6 | url.redirect += ( 7 | # redirect to other tool accounts 8 | #"^/(accounteligibility|catanalysis|globalgroups|gusersearch|iso639db|magicredirect|pgkbot|scripts|stewardry|userpages)(.*)$" => "https://meta.toolforge.org/$1$2", 9 | "^/(crossactivity)(.*)$" => "https://meta2.toolforge.org/$1$2", 10 | "^/(stalktoy)(.*)$" => "https://meta3.toolforge.org/$1$2", 11 | 12 | # redirect root 13 | "^/?$" => "/accounteligibility/", 14 | 15 | # prettify generated tool URLs that have a route version 16 | "^/accounteligibility(?:/index.php|/)?\?user=([^&]+)&(?:(wiki=[^&]+)|wiki=)&event=(\d+)$" => "/accounteligibility/$3/$1?$2", 17 | "^/stewardry(?:/index.php|/)?\?wiki=([^&]+)&?(.*)$" => "/stewardry/$1?$2", 18 | "^/userpages(?:/index.php|/)?\?user=([^&]+)$" => "/userpages/$1", 19 | 20 | # scripts to static server 21 | "^/scripts/(.*)$" => "https://tools-static.wmflabs.org/meta/scripts/$1" 22 | ) 23 | 24 | # convert route value into query string 25 | url.rewrite-if-not-file += ( 26 | "^/(accounteligibility|gusersearch|stewardry|userpages)(/[^\?]+)(?:\?(.*))?$" => "/$1/index.php?@path=$2&$3" 27 | ) 28 | 29 | # enable status pages 30 | server.modules += ("mod_auth", "mod_status") 31 | status.status-url = "/server-status" 32 | status.statistics-url = "/server-statistics" 33 | -------------------------------------------------------------------------------- /tool-labs/stalktoy/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Generic */ 2 | table { 3 | font-size: 0.8em; 4 | } 5 | 6 | th { 7 | font-size: 1.2em; 8 | } 9 | 10 | th a { 11 | text-decoration: none; 12 | color: #000; 13 | } 14 | 15 | span.bad, span.good { 16 | padding: 0 3px; 17 | background: #FCC; 18 | } 19 | 20 | span.good { 21 | background: #CFC; 22 | } 23 | 24 | /* wiki data */ 25 | tr[data-open="0"] { 26 | color: #666; 27 | } 28 | 29 | tr[data-open="0"] .wiki:after { 30 | content: ' (closed)'; 31 | } 32 | 33 | /* user data */ 34 | .account-id { 35 | color: gray; 36 | } 37 | 38 | tr[data-exists="0"], 39 | tr[data-groups="0"] td.groups, 40 | tr[data-global-groups="0"] td.global-groups, 41 | tr[data-blocked="0"] td.blocks { 42 | background: #CCC; 43 | color: #666; 44 | } 45 | 46 | tr[data-groups="1"] td.groups, 47 | tr[data-global-groups="1"] td.global-groups, 48 | tr[data-unified="1"] td.unification { 49 | background: #CFC; 50 | } 51 | 52 | tr[data-unified="0"] td.unification, 53 | tr[data-blocked="1"] td.blocks { 54 | background: #FCC; 55 | } 56 | 57 | tr[data-unified="0"][data-unifiable="0"] td.unification { 58 | background: #CFC; 59 | } 60 | 61 | td.edit-count { 62 | text-align: right; 63 | } 64 | 65 | td.edit-count span { 66 | color: #FFF; 67 | font-size: 1px; 68 | } 69 | 70 | /* visualizations */ 71 | #account-visualizations { 72 | margin: 1em 1em 1em 2em; 73 | } 74 | 75 | #account-visualizations .viz-chart { 76 | float: left; 77 | margin-right: 2em; 78 | } 79 | -------------------------------------------------------------------------------- /tool-labs/stalktoy/framework/models/LocalAccount.php: -------------------------------------------------------------------------------- 1 | pgk that processes and filters IRC change feeds for wiki installations (see the onwiki documentation).') 6 | ->link('/pgkbot/stylesheet.css') 7 | ->header(); 8 | 9 | echo " 10 |
The pgkbot package is obsolete and no longer actively maintained. This mirror is maintained for historical interest.
11 |TemplateScript adds custom one-click templates and scripts to your sidebar when editing pages (or other forms). You can import libraries of scripts maintained by other users, or write your own scripts if you're feeling adventurous. See m:TemplateScript for more information.
2 | 3 |These libraries have been imported for you (probably via your common.js or a gadget). You can choose which scripts will be shown. Your settings will be saved permanently to your user preferences; you can return to this page anytime to edit them. Changes are saved immediately.
22 | 23 | {{#if libraries.length}} 24 | {{#each libraries}} 25 |{{{this.description}}}
27 |(You haven't imported any libraries.)
42 | {{/if}} 43 | -------------------------------------------------------------------------------- /user-scripts/i18n/pt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a translation file for these scripts. See https://meta.wikimedia.org/wiki/TemplateScript#Translation 3 | * for instructions on using translation files. 4 | */ 5 | 6 | var pathoschild = pathoschild || {}; 7 | pathoschild.i18n = { 8 | templatescript: { 9 | defaultHeaderText: "TemplateScript", // the sidebar header text label for the default group 10 | regexEditor: "Editor de regex" // the default 'regex editor' script 11 | }, 12 | regexeditor: { 13 | header: "Editor de expressões regulares (regex)", // the header text shown in the form 14 | search: "Localizar", // the search input label 15 | replace: "Substituir", // the replace input label 16 | nameSession: "Forneça um nome para esta sessão", // the prompt shown when saving the session 17 | loadSession: 'Carregar a sessão "{name}"', // tooltip shown for a saved session, where {name} is replaced with the session name 18 | deleteSession: 'Apagar a sessão "{name}"', // tooltip shown for the delete icon on a saved session, where {name} is replaced with the session name 19 | closeEditor: "Fechar o editor de expressões regulares", // tooltip shown for the close-editor icon 20 | addPatterns: "incluir padrões", // button text 21 | addPatternsTooltip: "Incluir caixas de localizar e substituir", // button tooltip 22 | apply: "aplicar", // button text 23 | applyTooltip: "Executar os padrões acima", // button tooltip 24 | undo: "desfazer a última aplicação", // button text 25 | undoTooltip: "Desfazer a última aplicação", // button tooltip 26 | save: "salvar", // button text 27 | saveTooltip: "Salvar esta sessão para uso posterior", // button tooltip 28 | instructions: 'Insira qualquer número de expressõres regulares a serem executadas. O padrão de busca pode ser como "{code|text=padrão de busca}" ou "{code|text=/padrão/modificadores}", e o padrão de substituição pode conter grupos de referência como "{code|text=$1}" (ver {helplink|text=um tutorial|title=Tutorial sobre expressões regulares em JavaScript|url=https://www.regular-expressions.info/javascript.html}).' 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /tool-labs/accounteligibility/framework/models/ResultInfo.php: -------------------------------------------------------------------------------- 1 | result = $result; 52 | $this->message = $message; 53 | $this->isFinal = $isFinal; 54 | } 55 | 56 | /** 57 | * Get whether the eligibility check passed. 58 | */ 59 | public function isPass(): bool 60 | { 61 | return $this->result == Result::PASS; 62 | } 63 | 64 | /** 65 | * Get whether the eligibility check passed, but we should still check other wikis. 66 | */ 67 | public function isSoftPass(): bool 68 | { 69 | return $this->result == Result::SOFT_PASS; 70 | } 71 | 72 | /** 73 | * Get whether the eligibility check failed. 74 | */ 75 | public function isFail(): bool 76 | { 77 | return $this->result == Result::FAIL; 78 | } 79 | 80 | /** 81 | * Add a warning message for this result. 82 | * @param string $message The warning message. 83 | */ 84 | public function addWarning(string $message): void 85 | { 86 | array_push($this->warnings, $message); 87 | } 88 | 89 | /** 90 | * Add a note about this result. 91 | * @param string $message The note message. 92 | */ 93 | public function addNote(string $message): void 94 | { 95 | array_push($this->notes, $message); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /user-scripts/i18n/en.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a sample translation file for these scripts. See https://meta.wikimedia.org/wiki/TemplateScript#Translation 3 | * for instructions on using translation files. 4 | * 5 | * To translate these scripts: 6 | * 1. Copy this to a *new* file named with your language code. 7 | * 2. Translate the text inside 'quotes'. Be careful with the special tokens that look like 8 | * {variable}; these are placeholders. Only translate the text right of the '=' symbol. For example, 9 | * only "reset the form" should be translated for the "{resetForm|text=reset the form}" token. 10 | * 3. Submit a pull request to the Git repository, or simply post it to https://meta.wikimedia.org/wiki/User_talk:Pathoschild 11 | * and I'll do the rest. 12 | */ 13 | 14 | var pathoschild = pathoschild || {}; 15 | pathoschild.i18n = { 16 | templatescript: { 17 | defaultHeaderText: "TemplateScript", // the sidebar header text label for the default group 18 | regexEditor: "Regex editor" // the default 'regex editor' script 19 | }, 20 | regexeditor: { 21 | header: "Regex editor", // the header text shown in the form 22 | search: "Search", // the search input label 23 | replace: "Replace", // the replace input label 24 | nameSession: "Enter a name for this session", // the prompt shown when saving the session 25 | loadSession: 'Load session "{name}"', // tooltip shown for a saved session, where {name} is replaced with the session name 26 | deleteSession: 'Delete session "{name}"', // tooltip shown for the delete icon on a saved session, where {name} is replaced with the session name 27 | closeEditor: "Close the regex editor", // tooltip shown for the close-editor icon 28 | addPatterns: "add patterns", // button text 29 | addPatternsTooltip: "Add search & replace boxes", // button tooltip 30 | apply: "apply", // button text 31 | applyTooltip: "Perform the above patterns", // button tooltip 32 | undo: "undo the last apply", // button text 33 | undoTooltip: "Undo the last apply", // button tooltip 34 | save: "save", // button text 35 | saveTooltip: "Save this session for later use", // button tooltip 36 | instructions: 'Enter any number of regular expressions to execute. The search pattern can be like "{code|text=search pattern}" or "{code|text=/pattern/modifiers}", and the replace pattern can contain reference groups like "{code|text=$1}" (see {helplink|text=tutorial|title=JavaScript regex tutorial|url=https://www.regular-expressions.info/javascript.html}).' 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /tool-labs/userpages/scripts.js: -------------------------------------------------------------------------------- 1 | var pathoschild = pathoschild || {}; 2 | pathoschild.PageFilters = function () { 3 | /** 4 | * Filters the user page list to only show pages matching the selected filters. 5 | */ 6 | 7 | var filters = $(".filter"); 8 | this.apply = function () { 9 | /** 10 | * Reapply the selected filters. 11 | */ 12 | // reset filters 13 | $(".result-box").find("ul, li, h2").filter(":hidden").show(); 14 | 15 | // apply filters 16 | var items = $(".result-box li"); 17 | $("[data-filters]").each(function () { 18 | var toggle = $(this); 19 | if (!toggle.hasClass("selected")) 20 | items.filter(toggle.data("filters")).hide(); 21 | }); 22 | 23 | // hide wikis with no pages shown 24 | $(".result-box ul:not(:has(li:visible))").hide(); 25 | $(".result-box ul:not(:visible)").prev("h2").hide(); 26 | }; 27 | 28 | this.getToggle = function (key) { 29 | /** 30 | * Get the toggle element for a filter. 31 | * @param key {string} The unique key for the filter. 32 | */ 33 | return filters.filter('[data-filter-key="' + key + '"]'); 34 | } 35 | 36 | this.isEnabled = function (key) { 37 | /** 38 | * Get whether the specified filter is enabled. 39 | * @param key {string} The unique key for the filter. 40 | */ 41 | return this.getToggle(key).hasClass("selected"); 42 | }; 43 | 44 | this.toggle = function (key) { 45 | /** 46 | * Toggle a filter in the UI and URL. 47 | * @param key {string} The unique key for the filter. 48 | */ 49 | this.getToggle(key).toggleClass("selected"); 50 | location.hash = "#" + $("[data-filters].selected").map(function () { 51 | return $(this).attr("data-filter-key"); 52 | }).get().join(); 53 | this.apply(); 54 | } 55 | 56 | this.readHash = function () { 57 | /** 58 | * Update the filters based on the URL's hash. 59 | */ 60 | // read hash from URL 61 | var selected = location.hash.replace(/^#/, ""); 62 | if (!selected.length) 63 | return; 64 | selected = decodeURIComponent(selected.replace(/\./g, "%")); // reverse MediaWiki link munging 65 | 66 | // apply 67 | selected = selected.split(","); 68 | if (selected.length) { 69 | $("[data-filters]").removeClass("selected"); 70 | for (var i = 0, len = selected.length; i < len; i++) 71 | this.getToggle(selected[i]).addClass("selected"); 72 | this.apply(); 73 | } 74 | }; 75 | 76 | return this; 77 | }; 78 | 79 | $(function () { 80 | var filters = pathoschild.PageFilters(); 81 | $(".filter").click(function (event) { 82 | filters.toggle($(this).attr("data-filter-key")); 83 | event.preventDefault(); 84 | }); 85 | filters.readHash(); 86 | }); 87 | -------------------------------------------------------------------------------- /user-scripts/pathoschild.usejs.js: -------------------------------------------------------------------------------- 1 | var pathoschild = pathoschild || {}; 2 | 3 | /** 4 | * Usejs imports JavaScript for the current page when the URL contains a parameter like &usejs=MediaWiki:Common.js. It only accepts scripts in the protected MediaWiki: namespace (so these are all equivalent: &usejs=MediaWiki:Common.js, &usejs=Common.js, &usejs=common). 5 | * @see https://github.com/Pathoschild/Wikimedia-contrib#user-scripts 6 | * @update-token [[File:Pathoschild/usejs.js]] 7 | */ 8 | pathoschild.usejs = function() { 9 | /********* 10 | ** Public methods 11 | *********/ 12 | /** 13 | * Initialise the script and load the script if requested. 14 | */ 15 | this.initialise = function() { 16 | var self = this; 17 | 18 | // get script info 19 | var scriptName = self.getScriptName(); 20 | if (!scriptName) 21 | return; 22 | var scriptUrl = self.getScriptUrl(scriptName); 23 | var scriptLink = '' + scriptName + ""; 24 | // load script 25 | self.notify("↻ loading " + scriptName + "..."); 26 | $.getScript(scriptUrl) 27 | .done(function(data) { 28 | if (!data) 29 | self.notify("Couldn't load " + scriptLink + " because it doesn't exist.", "error"); 30 | else 31 | self.notify("Loaded " + scriptLink + "!"); 32 | }) 33 | .fail(function(xhr, settings, err) { 34 | self.notify("Couldn't load " + scriptLink + ": " + err, "error"); 35 | }); 36 | }; 37 | 38 | /********* 39 | ** Private methods 40 | *********/ 41 | /** 42 | * Get the normalised name of the script to load (like 'MediaWiki:Common.js'). 43 | */ 44 | this.getScriptName = function() { 45 | var script = mw.util.getParamValue("usejs"); 46 | return script && "MediaWiki:" + script.replace(/^MediaWiki:|\.js$/ig, "") + ".js"; 47 | }; 48 | 49 | /** 50 | * Get the executable relative script URL. 51 | * @param name The page name of the script to load (like 'MediaWiki:Common.js'). 52 | */ 53 | this.getScriptUrl = function(name) { 54 | return mw.config.get("wgScript") + "?title=" + name + "&action=raw&ctype=text/javascript"; 55 | }; 56 | 57 | /** 58 | * Show a notification message to the user. 59 | * @param content the text or jQuery element to show to the user. 60 | * @param cssClass a CSS class with which to wrap the content (default is 'warning'). 61 | */ 62 | this.notify = function(content, cssClass) { 63 | var message = '' + content + ""; 64 | var infoBlurb = 'You see this because usejs is enabled and the URL has &usejs.'; 65 | mw.notify($(message + "