--- /dev/null
+#! /usr/bin/perl
+use strict;
+use warnings;
+no warnings qw(once);
+use CGI;
+use CGI::Carp qw( fatalsToBrowser );
+use DBI;
+use Encode;
+use POSIX;
+use HTML::Entities;
+use utf8;
+use locale;
+require '../config.pm';
+
+my $dbh = DBI->connect($config::local_connstr, $config::local_username, $config::local_password)
+ or die "connect: " . $DBI::errstr;
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+
+binmode STDOUT, ':utf8';
+
+# Find auxillary parameters.
+my %params = ();
+my $q = $dbh->prepare('SELECT * FROM ratings WHERE id < 0');
+$q->execute;
+while (my $ref = $q->fetchrow_hashref) {
+ $params{$ref->{'id'}} = $ref->{'rating'};
+}
+my $match_stddev = $params{-2} * sqrt(2.0);
+
+print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'now');
+POSIX::setlocale(&POSIX::LC_ALL, 'nb_NO.UTF-8');
+
+printf <<"EOF", $params{-3}, $match_stddev;
+<html>
+ <head>
+ <title>WLoH-rating</title>
+ <style type="text/css">
+body {
+ color: black;
+ background: white;
+ font-family: sans-serif;
+}
+table {
+ border-collapse: collapse;
+ border: 1px solid black;
+}
+td, th {
+ border: 1px solid black;
+ padding: 5px;
+}
+td.num {
+ text-align: right;
+}
+.even {
+ background-color: #ddd;
+}
+ </style>
+ </head>
+ <body>
+ <h1>WLoH-rating</h1>
+
+ <p>Ratingen er basert på spilledata fra WLoH (takk til Lobotommy
+ for tilgang!), og oppdateres
+ hver hele time. Den er fullstendig uoffisiell, og har ingen innflytelse
+ på WLoH, men brukes for å estimere vinnersannsynligheter i
+ <a href="/">sannsynlighetsberegningen</a>.</p>
+
+ <p>Vær obs på at det
+ er betydelig usikkerhetsmargin, spesielt for spillere som ikke
+ har spilt spesielt mange kamper.</p>
+
+ <p>Modellen kan endre seg når som helst når jeg føler for det :-)
+ Ikke ta ratingen alt for alvorlig, selv om den er basert på
+ relativt fornuftige matematiske modeller. Husk at all statistikk
+ sier mer om fortiden enn om framtiden.</p>
+
+ <h2>Modellparametre</h2>
+
+ <p>For de som vet litt om slikt. Mer utførlig forklaring for begynnere kommer seinere.</p>
+
+ <ul>
+ <li>MLE-basert modell med én skalar (styrke) per spiller og to globale skalarer (begge standardavvik, se under), løst med syklisk MM (minorization-maximization). Antall iterasjoner før konvergens: $params{-1}.</li>
+ <li>Rimelighetfunksjon, prior: Normalfordeling med µ=1500, σ=%.1f (est.)</li>
+ <li>Rimelighetfunksjon, per kamp: Normalfordeling med µ=(score1 - score2), σ=%.1f (est.)</li>
+ <li>Vekting: Inneværende sesong samt de tre siste vektes fullt ut
+ (likt med prior). Deretter eksponentielt synkende vekting, med
+ halveringstid på tre sesonger.</li>
+ </ul>
+
+ <h2>Rankingliste</h2>
+
+ <table>
+ <tr>
+ <th></th>
+ <th>Nick</th>
+ <th>Ranking</th>
+ <th>Sist sett</th>
+ </tr>
+EOF
+
+$q = $dbh->prepare('
+SELECT *
+FROM ratings
+ NATURAL JOIN kanonisk_navn
+ NATURAL JOIN siste_divisjon
+ORDER BY rating DESC');
+$q->execute;
+
+my $i = 0;
+while (my $ref = $q->fetchrow_hashref) {
+ if (++$i % 2 == 0) {
+ print " <tr class=\"odd\">\n";
+ } else {
+ print " <tr class=\"even\">\n";
+ }
+ printf " <th>%d.</th>\n", $i;
+ printf " <td><a href=\"http://wordfeud.aasmul.net/bruker-%d\">%s</a></td>\n", $ref->{'id'}, HTML::Entities::encode_entities(Encode::decode_utf8($ref->{'navn'}));
+ printf " <td class=\"num\">%.1f</td>\n", $ref->{'rating'};
+ printf " <td><a href=\"http://wordfeud.aasmul.net/serie-%d\">%s</a></td>\n", $ref->{'serie_id'}, $ref->{'serie_navn'};
+ print " </tr>\n";
+}
+
+print <<"EOF";
+ </table>
+ </body>
+</html>
+EOF
+
+$match_stddev = $params{-2} * sqrt(2.0);
+
+$dbh->rollback;