1
0

AoC single + prism + better additional css/js handling

This commit is contained in:
Mike Schwörer 2019-11-03 15:33:23 +01:00
parent 65f75c26ef
commit bdda2001e3
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
27 changed files with 565 additions and 108 deletions

View File

@ -1221,6 +1221,40 @@ html, body {
font-weight: normal; font-weight: normal;
} }
.bc_aoc_description {
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
background-color: #333;
color: #DDD;
padding: 1ch;
max-width: 82ch;
}
.bc_aoc_input {
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
border: 1px solid #000;
padding: 1em;
max-height: 150px;
overflow-y: scroll;
background: #F8F8F8;
}
.bc_aoc_solution_parent {
border: 1px solid #000;
}
.bc_aoc_solution_code {
padding: 0;
}
.bc_aoc_solution_code pre {
margin: 0;
border: none;
}
.bc_aoc_solution_value {
background: #AAA;
}
/* 400px */ /* 400px */
.prgl_parent { .prgl_parent {
display: flex; display: flex;

View File

@ -232,6 +232,12 @@ html,body{margin:0;padding:0;height:100%}
.aoc_calendar_field.aoc_enabled{background:#165b33;color:#bb2528;border:1px solid #fff;text-shadow:0 0 .2em #222;font-weight:bold} .aoc_calendar_field.aoc_enabled{background:#165b33;color:#bb2528;border:1px solid #fff;text-shadow:0 0 .2em #222;font-weight:bold}
.aoc_calendar_field.aoc_enabled:hover{background:#165b00;color:#bb2528;border:1px solid #bb2528;text-shadow:0 0 0 #000} .aoc_calendar_field.aoc_enabled:hover{background:#165b00;color:#bb2528;border:1px solid #bb2528;text-shadow:0 0 0 #000}
.aoc_calendar_field.aoc_disabled{background:#444;color:#888;border:1px solid #888;cursor:default;font-weight:normal} .aoc_calendar_field.aoc_disabled{background:#444;color:#888;border:1px solid #888;cursor:default;font-weight:normal}
.bc_aoc_description{font-family:Consolas,Monaco,"Courier New",Menlo,monospace;background-color:#333;color:#DDD;padding:1ch;max-width:82ch}
.bc_aoc_input{font-family:Consolas,Monaco,"Courier New",Menlo,monospace;border:1px solid #000;padding:1em;max-height:150px;overflow-y:scroll;background:#f8f8f8}
.bc_aoc_solution_parent{border:1px solid #000}
.bc_aoc_solution_code{padding:0}
.bc_aoc_solution_code pre{margin:0;border:0}
.bc_aoc_solution_value{background:#AAA}
.prgl_parent{display:flex;flex-direction:column} .prgl_parent{display:flex;flex-direction:column}
@media(max-width:850px){.prgl_parent{align-items:center}} @media(max-width:850px){.prgl_parent{align-items:center}}
.prgl_elem{display:flex;flex-direction:row;text-decoration:none;background:#BBB;border:solid 1px #444;margin:5px 0} .prgl_elem{display:flex;flex-direction:row;text-decoration:none;background:#BBB;border:solid 1px #444;margin:5px 0}

View File

@ -118,3 +118,37 @@ $COL_CHRISTMAS_RED: #BB2528;
} }
// ==================== AdventOfCode Blog - Single Day View ==================== // // ==================== AdventOfCode Blog - Single Day View ==================== //
.bc_aoc_description {
font-family: $FONT_CODE;
background-color: #333;
color: #DDD;
padding: 1ch;
max-width: 82ch;
}
.bc_aoc_input {
font-family: $FONT_CODE;
border: 1px solid #000;
padding: 1em;
max-height: 150px;
overflow-y: scroll;
background: #F8F8F8;
}
.bc_aoc_solution_parent {
border: 1px solid #000;
}
.bc_aoc_solution_code {
padding: 0;
}
.bc_aoc_solution_code pre {
margin: 0;
border: none;
}
.bc_aoc_solution_value {
background: #AAA;
}

File diff suppressed because one or more lines are too long

184
www/data/rawcss/prism.css Normal file
View File

@ -0,0 +1,184 @@
/* PrismJS 1.17.1
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+csharp+bash+basic+batch+brainfuck+cpp+aspnet+ruby+diff+markup-templating+go+graphql+less+ini+java+php+markdown+json+kotlin+makefile+typescript+nim+objectivec+pascal+perl+sql+scss+python+rust+sass+swift+toml+visual-basic+regex+vbnet&plugins=line-numbers */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
pre[class*="language-"].line-numbers {
position: relative;
padding-left: 3.8em;
counter-reset: linenumber;
}
pre[class*="language-"].line-numbers > code {
position: relative;
white-space: inherit;
}
.line-numbers .line-numbers-rows {
position: absolute;
pointer-events: none;
top: 0;
font-size: 100%;
left: -3.8em;
width: 3em; /* works for line-numbers below 1000 lines */
letter-spacing: -1px;
border-right: 1px solid #999;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.line-numbers-rows > span {
pointer-events: none;
display: block;
counter-increment: linenumber;
}
.line-numbers-rows > span:before {
content: counter(linenumber);
color: #999;
display: block;
padding-right: 0.8em;
text-align: right;
}

View File

@ -5,11 +5,6 @@ require_once (__DIR__ . '/../internals/adventofcode.php');
$year = $post['extras']['aoc:year']; $year = $post['extras']['aoc:year'];
$assocdays = AdventOfCode::listSingleYearAssociative($year);
$prev_year = AdventOfCode::getPrevYear($year);
$next_year = AdventOfCode::getNextYear($year);
?> ?>
<div class="boxedcontent blogcontent_plain"> <div class="boxedcontent blogcontent_plain">
@ -26,37 +21,14 @@ $next_year = AdventOfCode::getNextYear($year);
<div class="bc_data"> <div class="bc_data">
<?php echo nl2br(Blog::getPostFragment($post)); ?> <?php echo nl2br(htmlspecialchars(Blog::getPostFragment($post))); ?>
<div class="aoc_calendar_parent">
<div class="aoc_calendar">
<div class="aoc_calendar_header">
<?php
if ($prev_year !== null) echo '<a href="' . AdventOfCode::getURLForYear($prev_year) . '" class="aoc_calendar_header_link aoc_prev" >&lt;</a>';
else echo '<a href="#" class="aoc_calendar_header_link aoc_prev aoc_link_hidden" >&lt;</a>';
echo '<span class="aoc_calendar_header_title">'.$year.'</span>';
if ($next_year !== null) echo '<a href="' . AdventOfCode::getURLForYear($next_year) . '" class="aoc_calendar_header_link aoc_next" >&gt;</a>';
else echo '<a href="" class="aoc_calendar_header_link aoc_next aoc_link_hidden" >&gt;</a>';
?>
</div>
<?php <?php
for ($i=0; $i<5; $i++) global $PARAM_AOCCALENDAR;
{ $PARAM_AOCCALENDAR = ['year' => $year];
echo '<div class="aoc_calendar_row">'."\n"; require (__DIR__ . '/../fragments/panel_aoc_calendar.php')
for ($j=0; $j<5; $j++)
{
$day = $assocdays[$i*5+$j];
if ($day === null) echo '<span class="aoc_calendar_field aoc_disabled">'.($i*5+$j+1).'</span>'."\n";
else echo '<a href="'.$day['url'].'" class="aoc_calendar_field aoc_enabled" >'.($i*5+$j+1).'</a>'."\n";
}
echo '</div>'."\n";
}
?> ?>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,67 @@
<?php
require_once (__DIR__ . '/../internals/base.php');
require_once (__DIR__ . '/../internals/blog.php');
require_once (__DIR__ . '/../internals/adventofcode.php');
require_once (__DIR__ . '/../internals/ParsedownCustom.php');
$year = $post['extras']['aoc:year'];
$subview = $OPTIONS['subview'];
$day = AdventOfCode::getDayFromStrIdent($year, $subview);
if ($day === NULL) httpError(404, 'AdventOfCode entry not found');
$pd = new ParsedownCustom();
?>
<div class="boxedcontent base_markdown">
<div style="position: relative;">
<a href="<?php echo AdventOfCode::getGithubLink($year); ?>" style="position: absolute; top: 0; right: 0; border: 0;">
<img src="/data/images/blog/github_band.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png">
</a>
</div>
<div class="bc_header">
<?php echo $day['date']; ?>
</div>
<div class="bc_data">
<div class="bce_header"><h1><a href="<?php echo $day['url_aoc']; ?>">Day <?php echo $day['day-padded']; ?></a>: <?php echo htmlspecialchars($day['title']); ?></h1></div>
<b>Description:</b>
<div class="bc_aoc_description"><?php echo nl2br(htmlspecialchars(file_get_contents($day['file_challenge']))); ?></div>
<br/>
<b>Input:</b>
<div class="bc_aoc_input"><?php echo nl2br(htmlspecialchars(file_get_contents($day['file_input']))); ?></div>
<br/>
<?php for ($i=1; $i<=$day['parts']; $i++): ?>
<b>Part <?php echo $i; ?>:</b>
<div class="bc_aoc_solution_parent">
<div class="bc_aoc_solution_code">
<pre><code class="<?php echo AdventOfCode::getLanguageCSS($day) ?>"><?php echo htmlspecialchars(AdventOfCode::getSolutionCode($day, $i-1)); ?></code></pre>
</div>
<div class="bc_aoc_solution_value"><b>Result:</b> <?php echo $day['solutions'][$i-1]; ?></div>
</div>
<br/>
<?php endfor; ?>
<?php includeAdditionalScript("/data/javascript/prism.js", 'defer'); ?>
<?php includeAdditionalStylesheet("/data/rawcss/prism.css"); ?>
<br />
<br />
<?php
global $PARAM_AOCCALENDAR;
$PARAM_AOCCALENDAR = ['year' => $year];
require (__DIR__ . '/../fragments/panel_aoc_calendar.php')
?>
</div>
</div>

View File

@ -10,7 +10,7 @@ require_once (__DIR__ . '/../internals/blog.php');
</div> </div>
<div class="bc_data"> <div class="bc_data">
<?php echo nl2br(Blog::getPostFragment($post)); ?> <?php echo nl2br(htmlspecialchars(Blog::getPostFragment($post))); ?>
</div> </div>
</div> </div>

View File

@ -0,0 +1,41 @@
<?php
global $PARAM_AOCCALENDAR;
$year = $PARAM_AOCCALENDAR['year'];
$assocdays = AdventOfCode::listSingleYearAssociative($year);
$prev_year = AdventOfCode::getPrevYear($year);
$next_year = AdventOfCode::getNextYear($year);
?>
<div class="aoc_calendar_parent">
<div class="aoc_calendar">
<div class="aoc_calendar_header">
<?php
if ($prev_year !== null) echo '<a href="' . AdventOfCode::getURLForYear($prev_year) . '" class="aoc_calendar_header_link aoc_prev" >&lt;</a>';
else echo '<a href="#" class="aoc_calendar_header_link aoc_prev aoc_link_hidden" >&lt;</a>';
echo '<span class="aoc_calendar_header_title">'.$year.'</span>';
if ($next_year !== null) echo '<a href="' . AdventOfCode::getURLForYear($next_year) . '" class="aoc_calendar_header_link aoc_next" >&gt;</a>';
else echo '<a href="" class="aoc_calendar_header_link aoc_next aoc_link_hidden" >&gt;</a>';
?>
</div>
<?php
for ($i=0; $i<5; $i++)
{
echo '<div class="aoc_calendar_row">'."\n";
for ($j=0; $j<5; $j++)
{
$day = $assocdays[$i*5+$j];
if ($day === null) echo '<span class="aoc_calendar_field aoc_disabled">'.($i*5+$j+1).'</span>'."\n";
else echo '<a href="'.$day['url'].'" class="aoc_calendar_field aoc_enabled" >'.($i*5+$j+1).'</a>'."\n";
}
echo '</div>'."\n";
}
?>
</div>
</div>

View File

@ -58,7 +58,7 @@ if ($interactive) {
$result .= ' </div>' . "\n"; $result .= ' </div>' . "\n";
$result .= '</div>' . "\n"; $result .= '</div>' . "\n";
$result .= includeScriptOnce("/data/javascript/blogpost_bef93runner.js", false, '') . "\n"; includeAdditionalScript("/data/javascript/blogpost_bef93runner.js");
} }
else else
{ {

View File

@ -35,6 +35,6 @@ $result .= '</div>' . "\n";
$result .= '' . "\n"; $result .= '' . "\n";
$result .= includeScriptOnce("/data/javascript/blogpost_BFJoustBot_script.js", false, '') . "\n"; includeAdditionalScript("/data/javascript/blogpost_BFJoustBot_script.js");
return $result; return $result;

View File

@ -77,14 +77,13 @@ class AdventOfCode
$a['file_challenge'] = (__DIR__ . '/../statics/aoc/'.$year.'/'.$n2p.'_challenge.txt'); $a['file_challenge'] = (__DIR__ . '/../statics/aoc/'.$year.'/'.$n2p.'_challenge.txt');
$a['file_input'] = (__DIR__ . '/../statics/aoc/'.$year.'/'.$n2p.'_input.txt'); $a['file_input'] = (__DIR__ . '/../statics/aoc/'.$year.'/'.$n2p.'_input.txt');
$a['date'] = $year . '-' . 12 . '-' . $n2p;
$solutionfiles = []; $solutionfiles = [];
foreach ($a['languages'] as $language)
{
for ($i=1; $i <= $a['parts']; $i++) for ($i=1; $i <= $a['parts']; $i++)
{ {
$solutionfiles []= (__DIR__ . '/../statics/aoc/' . $year . '/' . $n2p . '-' . $i . '.' . self::LANGUAGES[$language]['ext']); $solutionfiles []= (__DIR__ . '/../statics/aoc/' . $year . '/' . $n2p . '-' . $i . '.' . self::LANGUAGES[$a['language']]['ext']);
}
} }
$a['file_solutions'] = $solutionfiles; $a['file_solutions'] = $solutionfiles;
@ -143,6 +142,27 @@ class AdventOfCode
return null; return null;
} }
public static function getLanguageCSS($data)
{
return self::LANGUAGES[$data['language']]['css'];
}
public static function getSolutionCode($data, $i)
{
$raw = file_get_contents($data['file_solutions'][$i]);
if ($data['language'] === 'cs')
{
$raw = trim($raw);
if (startsWith($raw, '<Query Kind="Program" />')) $raw = substr($raw, strlen('<Query Kind="Program" />'));
if (startsWith($raw, '<Query Kind="Expression" />')) $raw = substr($raw, strlen('<Query Kind="Expression" />'));
if (startsWith($raw, '<Query Kind="Statements" />')) $raw = substr($raw, strlen('<Query Kind="Statements" />'));
$raw = trim($raw);
}
return $raw;
}
public static function checkConsistency() public static function checkConsistency()
{ {
$warn = null; $warn = null;
@ -175,10 +195,7 @@ class AdventOfCode
if (!file_exists($sfile)) return ['result'=>'err', 'message' => 'file_solution[?] not found ' . $sfile]; if (!file_exists($sfile)) return ['result'=>'err', 'message' => 'file_solution[?] not found ' . $sfile];
} }
foreach ($aocdata['languages'] as $lang) if (!array_key_exists($aocdata['language'], self::LANGUAGES)) return ['result'=>'err', 'message' => 'Unknown language ' . $aocdata['language']];
{
if (!array_key_exists($lang, self::LANGUAGES)) return ['result'=>'err', 'message' => 'Unknown language ' . $lang];
}
} }
} }

View File

@ -6,8 +6,10 @@ $CONFIG = require 'config.php';
global $CSS_BASE; global $CSS_BASE;
$CSS_BASE = ($CONFIG['prod']) ? ('/data/css/styles.min.css') : ('/data/css/styles.css'); $CSS_BASE = ($CONFIG['prod']) ? ('/data/css/styles.min.css') : ('/data/css/styles.css');
global $REGISTERED_SCRIPTS; global $ADDITIONAL_SCRIPTS;
$REGISTERED_SCRIPTS = []; global $ADDITIONAL_STYLESHEETS;
$ADDITIONAL_SCRIPTS = [];
$ADDITIONAL_STYLESHEETS = [];
function InitPHP() { function InitPHP() {
@ -89,28 +91,59 @@ function formatMilliseconds($millis)
} }
} }
function includeScriptOnce($script, $echo = true, $attr=false) function includeAdditionalScript($script, $attr='', $printImmediately = false) {
{ global $ADDITIONAL_SCRIPTS;
global $REGISTERED_SCRIPTS;
if ($echo) if (in_array($script, $ADDITIONAL_SCRIPTS)) return false;
{
if (in_array($script, $REGISTERED_SCRIPTS)) return false; if ($printImmediately) {
$REGISTERED_SCRIPTS []= $script; $ADDITIONAL_SCRIPTS[$script] = ['src' => $script, 'attr' => $attr, 'consumed' => true];
echo "<script src=\"$script\" type=\"text/javascript\" $attr></script>"; echo '<script src="'.$script.'" type="text/javascript" '.$attr.'></script>';
return true;
} else {
$ADDITIONAL_SCRIPTS[$script] = ['src' => $script, 'attr' => $attr, 'consumed' => false];
return true; return true;
}
else
{
if (in_array($script, $REGISTERED_SCRIPTS)) return '';
$REGISTERED_SCRIPTS []= $script;
return "<script src=\"$script\" type=\"text/javascript\" $attr></script>";
} }
} }
function printCSS() { function includeAdditionalStylesheet($sheet, $attr='', $printImmediately = false) {
global $ADDITIONAL_STYLESHEETS;
if (in_array($sheet, $ADDITIONAL_STYLESHEETS)) return false;
if ($printImmediately) {
$ADDITIONAL_STYLESHEETS[$sheet] = ['src' => $sheet, 'attr' => $attr, 'consumed' => true];
echo '<link rel="stylesheet" href="' . $sheet . '" '.$attr.'/>';
return true;
} else {
$ADDITIONAL_STYLESHEETS[$sheet] = ['src' => $sheet, 'attr' => $attr, 'consumed' => false];
return true;
}
}
function printHeaderCSS() {
global $CSS_BASE; global $CSS_BASE;
echo '<link rel="stylesheet" href="' . $CSS_BASE . '"/>'; includeAdditionalStylesheet($CSS_BASE, '', true);
}
function printAdditionalScripts() {
global $ADDITIONAL_SCRIPTS;
foreach ($ADDITIONAL_SCRIPTS as $d) {
if ($d['consumed']) continue;
echo '<script src="' . $d['src'] . '" type="text/javascript" ' . $d['attr'] . '></script>';
$d['consumed'] = true;
}
}
function printAdditionalStylesheets() {
global $ADDITIONAL_STYLESHEETS;
foreach ($ADDITIONAL_STYLESHEETS as $d) {
if ($d['consumed']) continue;
echo '<link rel="stylesheet" href="' . $d['src'] . '" ' . $d['attr'] . '/>';
$d['consumed'] = true;
}
} }
function isProd() { function isProd() {

View File

@ -10,8 +10,8 @@ global $OPTIONS;
<title>Mikescher.com - About</title> <title>Mikescher.com - About</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/about"/> <link rel="canonical" href="https://www.mikescher.com/about"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
<?php includeScriptOnce("/data/javascript/egh.js", true, 'defer') ?> <?php includeAdditionalScript("/data/javascript/egh.js", 'defer', true) ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -102,5 +102,7 @@ global $OPTIONS;
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -39,9 +39,9 @@ function dumpConsistency($c) {
<title>Mikescher.com - Admin</title> <title>Mikescher.com - Admin</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/about"/> <link rel="canonical" href="https://www.mikescher.com/about"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
<?php includeScriptOnce("https://code.jquery.com/jquery-latest.min.js", true, '') ?> <?php includeAdditionalScript("https://code.jquery.com/jquery-latest.min.js", '', true) ?>
<?php includeScriptOnce("/data/javascript/admin.js", true, 'defer') ?> <?php includeAdditionalScript("/data/javascript/admin.js", 'defer', true) ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -218,5 +218,7 @@ function dumpConsistency($c) {
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -12,7 +12,7 @@ $allposts = Blog::listAllNewestFirst();
<title>Mikescher.com - Blog</title> <title>Mikescher.com - Blog</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/blog"/> <link rel="canonical" href="https://www.mikescher.com/blog"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -49,5 +49,7 @@ $allposts = Blog::listAllNewestFirst();
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -44,9 +44,8 @@ if ($isSubAdventOfCode) $canonical = $adventofcodeday['canonical'];
<meta charset="utf-8"> <meta charset="utf-8">
<title>Mikescher.com - <?php echo $htmltitle; ?></title> <title>Mikescher.com - <?php echo $htmltitle; ?></title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
<?php echo '<link rel="canonical" href="' . $canonical . '"/>'; ?> <?php echo '<link rel="canonical" href="' . $canonical . '"/>'; ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -89,5 +88,7 @@ if ($isSubAdventOfCode) $canonical = $adventofcodeday['canonical'];
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -12,7 +12,7 @@ $allbooks = Books::listAllNewestFirst();
<title>Mikescher.com - Converted Books</title> <title>Mikescher.com - Converted Books</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/books"/> <link rel="canonical" href="https://www.mikescher.com/books"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -58,5 +58,7 @@ $allbooks = Books::listAllNewestFirst();
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -15,9 +15,9 @@ if ($book === NULL) httpError(404, 'Book not found');
<meta charset="utf-8"> <meta charset="utf-8">
<title>Mikescher.com - <?php echo $book['title']; ?></title> <title>Mikescher.com - <?php echo $book['title']; ?></title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
<?php echo '<link rel="canonical" href="' . $book['url'] . '"/>'; ?> <?php echo '<link rel="canonical" href="' . $book['url'] . '"/>'; ?>
<?php includeScriptOnce("/data/javascript/ms_basic.js", true, 'defer') ?> <?php includeAdditionalScript("/data/javascript/ms_basic.js", 'defer', true) ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -96,5 +96,7 @@ if ($book === NULL) httpError(404, 'Book not found');
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -11,7 +11,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Mikescher.com - <?php echo $errormsg; ?></title> <title>Mikescher.com - <?php echo $errormsg; ?></title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -28,5 +28,7 @@
</div> </div>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -28,7 +28,7 @@ $redirect = $OPTIONS['login_target'];
<title>Mikescher.com - Login</title> <title>Mikescher.com - Login</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/login"/> <link rel="canonical" href="https://www.mikescher.com/login"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -85,5 +85,7 @@ $redirect = $OPTIONS['login_target'];
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -21,5 +21,7 @@ You have been logged out
<script> <script>
setTimeout(function () { window.location.href = "<?php echo $redirect; ?>"; }, 1000); setTimeout(function () { window.location.href = "<?php echo $redirect; ?>"; }, 1000);
</script> </script>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -7,7 +7,7 @@
<meta name="google-site-verification" content="pZOhmjeJcQbRMNa8xRLam4dwJ2oYwMwISY1lRKreSSs"/> <meta name="google-site-verification" content="pZOhmjeJcQbRMNa8xRLam4dwJ2oYwMwISY1lRKreSSs"/>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/"/> <link rel="canonical" href="https://www.mikescher.com/"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -29,5 +29,7 @@
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -14,7 +14,7 @@ $allprograms = Programs::listAllNewestFirst($filter);
<title>Mikescher.com - Programs</title> <title>Mikescher.com - Programs</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/programs"/> <link rel="canonical" href="https://www.mikescher.com/programs"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -63,5 +63,7 @@ $allprograms = Programs::listAllNewestFirst($filter);
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -18,8 +18,8 @@ if ($prog === NULL) httpError(404, 'Program not found');
<title>Mikescher.com - <?php echo $prog['name']; ?></title> <title>Mikescher.com - <?php echo $prog['name']; ?></title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="<?php echo $prog['url']; ?>"/> <link rel="canonical" href="<?php echo $prog['url']; ?>"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
<?php if ($prog['has_extra_images']) includeScriptOnce("/data/javascript/ms_basic.js", true, 'defer') ?> <?php if ($prog['has_extra_images']) includeAdditionalScript("/data/javascript/ms_basic.js", 'defer', true) ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -117,5 +117,7 @@ if ($prog === NULL) httpError(404, 'Program not found');
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -12,7 +12,7 @@ $allapps = WebApps::listAllNewestFirst();
<title>Mikescher.com - Tools</title> <title>Mikescher.com - Tools</title>
<link rel="icon" type="image/png" href="/data/images/favicon.png"/> <link rel="icon" type="image/png" href="/data/images/favicon.png"/>
<link rel="canonical" href="https://www.mikescher.com/webapps"/> <link rel="canonical" href="https://www.mikescher.com/webapps"/>
<?php printCSS(); ?> <?php printHeaderCSS(); ?>
</head> </head>
<body> <body>
<div id="mastercontainer"> <div id="mastercontainer">
@ -46,5 +46,7 @@ $allapps = WebApps::listAllNewestFirst();
<?php include (__DIR__ . '/../fragments/footer.php'); ?> <?php include (__DIR__ . '/../fragments/footer.php'); ?>
</div> </div>
<?php printAdditionalScripts(); ?>
<?php printAdditionalStylesheets(); ?>
</body> </body>
</html> </html>

View File

@ -4,31 +4,31 @@ return
[ [
'2018' => '2018' =>
[ [
['day' => 1, 'parts' => 2, 'title' => 'Chronal Calibration', 'languages' => ['cs'], 'solutions' => ['490', '70357'] ], ['day' => 1, 'parts' => 2, 'title' => 'Chronal Calibration', 'language' => 'cs', 'solutions' => ['490', '70357'] ],
['day' => 2, 'parts' => 2, 'title' => 'Inventory Management System', 'languages' => ['cs'], 'solutions' => ['5434', 'agimdjvlhedpsyoqfzuknpjwt'] ], ['day' => 2, 'parts' => 2, 'title' => 'Inventory Management System', 'language' => 'cs', 'solutions' => ['5434', 'agimdjvlhedpsyoqfzuknpjwt'] ],
['day' => 3, 'parts' => 2, 'title' => 'No Matter How You Slice It', 'languages' => ['cs'], 'solutions' => ['116489', '1260'] ], ['day' => 3, 'parts' => 2, 'title' => 'No Matter How You Slice It', 'language' => 'cs', 'solutions' => ['116489', '1260'] ],
['day' => 4, 'parts' => 2, 'title' => 'Repose Record', 'languages' => ['cs'], 'solutions' => ['143415', '49944'] ], ['day' => 4, 'parts' => 2, 'title' => 'Repose Record', 'language' => 'cs', 'solutions' => ['143415', '49944'] ],
['day' => 5, 'parts' => 2, 'title' => 'Alchemical Reduction', 'languages' => ['cs'], 'solutions' => ['10368', '4122'] ], ['day' => 5, 'parts' => 2, 'title' => 'Alchemical Reduction', 'language' => 'cs', 'solutions' => ['10368', '4122'] ],
['day' => 6, 'parts' => 2, 'title' => 'Chronal Coordinates', 'languages' => ['cs'], 'solutions' => ['2917', '44202'] ], ['day' => 6, 'parts' => 2, 'title' => 'Chronal Coordinates', 'language' => 'cs', 'solutions' => ['2917', '44202'] ],
['day' => 7, 'parts' => 2, 'title' => 'The Sum of Its Parts', 'languages' => ['cs'], 'solutions' => ['GKPTSLUXBIJMNCADFOVHEWYQRZ', '920'] ], ['day' => 7, 'parts' => 2, 'title' => 'The Sum of Its Parts', 'language' => 'cs', 'solutions' => ['GKPTSLUXBIJMNCADFOVHEWYQRZ', '920'] ],
['day' => 8, 'parts' => 2, 'title' => 'Memory Maneuver', 'languages' => ['cs'], 'solutions' => ['45194', '22989'] ], ['day' => 8, 'parts' => 2, 'title' => 'Memory Maneuver', 'language' => 'cs', 'solutions' => ['45194', '22989'] ],
['day' => 9, 'parts' => 2, 'title' => 'Marble Mania', 'languages' => ['cs'], 'solutions' => ['398242', '3273842452'] ], ['day' => 9, 'parts' => 2, 'title' => 'Marble Mania', 'language' => 'cs', 'solutions' => ['398242', '3273842452'] ],
['day' => 10, 'parts' => 2, 'title' => 'The Stars Align', 'languages' => ['cs'], 'solutions' => ['KFLBHXGK', '10659'] ], ['day' => 10, 'parts' => 2, 'title' => 'The Stars Align', 'language' => 'cs', 'solutions' => ['KFLBHXGK', '10659'] ],
['day' => 11, 'parts' => 2, 'title' => 'Chronal Charge', 'languages' => ['cs'], 'solutions' => ['34,13', '280,218,11'] ], ['day' => 11, 'parts' => 2, 'title' => 'Chronal Charge', 'language' => 'cs', 'solutions' => ['34,13', '280,218,11'] ],
['day' => 12, 'parts' => 2, 'title' => 'Subterranean Sustainability', 'languages' => ['cs'], 'solutions' => ['3738', '3900000002467'] ], ['day' => 12, 'parts' => 2, 'title' => 'Subterranean Sustainability', 'language' => 'cs', 'solutions' => ['3738', '3900000002467'] ],
['day' => 13, 'parts' => 2, 'title' => 'Mine Cart Madness', 'languages' => ['cs'], 'solutions' => ['124,90', '145,88'] ], ['day' => 13, 'parts' => 2, 'title' => 'Mine Cart Madness', 'language' => 'cs', 'solutions' => ['124,90', '145,88'] ],
['day' => 14, 'parts' => 2, 'title' => 'Chocolate Charts', 'languages' => ['cs'], 'solutions' => ['9276422810', '20319117'] ], ['day' => 14, 'parts' => 2, 'title' => 'Chocolate Charts', 'language' => 'cs', 'solutions' => ['9276422810', '20319117'] ],
['day' => 15, 'parts' => 2, 'title' => 'Beverage Bandits', 'languages' => ['cs'], 'solutions' => ['201123', '54188'] ], ['day' => 15, 'parts' => 2, 'title' => 'Beverage Bandits', 'language' => 'cs', 'solutions' => ['201123', '54188'] ],
['day' => 16, 'parts' => 2, 'title' => 'Chronal Classification', 'languages' => ['cs'], 'solutions' => ['592', '557'] ], ['day' => 16, 'parts' => 2, 'title' => 'Chronal Classification', 'language' => 'cs', 'solutions' => ['592', '557'] ],
['day' => 17, 'parts' => 2, 'title' => 'Reservoir Research', 'languages' => ['cs'], 'solutions' => ['33004', '23294'] ], ['day' => 17, 'parts' => 2, 'title' => 'Reservoir Research', 'language' => 'cs', 'solutions' => ['33004', '23294'] ],
['day' => 18, 'parts' => 2, 'title' => 'Settlers of The North Pole', 'languages' => ['cs'], 'solutions' => ['536370', '190512'] ], ['day' => 18, 'parts' => 2, 'title' => 'Settlers of The North Pole', 'language' => 'cs', 'solutions' => ['536370', '190512'] ],
['day' => 19, 'parts' => 2, 'title' => 'Go With The Flow', 'languages' => ['cs'], 'solutions' => ['1440', '15827040'] ], ['day' => 19, 'parts' => 2, 'title' => 'Go With The Flow', 'language' => 'cs', 'solutions' => ['1440', '15827040'] ],
['day' => 20, 'parts' => 2, 'title' => 'A Regular Map', 'languages' => ['cs'], 'solutions' => ['3675', '7953'] ], ['day' => 20, 'parts' => 2, 'title' => 'A Regular Map', 'language' => 'cs', 'solutions' => ['3675', '7953'] ],
['day' => 21, 'parts' => 2, 'title' => 'Chronal Conversion', 'languages' => ['cs'], 'solutions' => ['103548', '14256686'] ], ['day' => 21, 'parts' => 2, 'title' => 'Chronal Conversion', 'language' => 'cs', 'solutions' => ['103548', '14256686'] ],
['day' => 22, 'parts' => 2, 'title' => 'Mode Maze', 'languages' => ['cs'], 'solutions' => ['11972', '1092'] ], ['day' => 22, 'parts' => 2, 'title' => 'Mode Maze', 'language' => 'cs', 'solutions' => ['11972', '1092'] ],
['day' => 23, 'parts' => 2, 'title' => 'Experimental Emergency Teleportation', 'languages' => ['cs'], 'solutions' => ['417', '112997634'] ], ['day' => 23, 'parts' => 2, 'title' => 'Experimental Emergency Teleportation', 'language' => 'cs', 'solutions' => ['417', '112997634'] ],
['day' => 24, 'parts' => 2, 'title' => 'Immune System Simulator 20XX', 'languages' => ['cs'], 'solutions' => ['21070', '7500'] ], ['day' => 24, 'parts' => 2, 'title' => 'Immune System Simulator 20XX', 'language' => 'cs', 'solutions' => ['21070', '7500'] ],
['day' => 25, 'parts' => 1, 'title' => 'Four-Dimensional Adventure', 'languages' => ['cs'], 'solutions' => ['407'] ], ['day' => 25, 'parts' => 1, 'title' => 'Four-Dimensional Adventure', 'language' => 'cs', 'solutions' => ['407'] ],
], ],
'2019' => '2019' =>
[ [