2021-04-21 20:53:59 +00:00
|
|
|
<!DOCTYPE html>
|
2021-04-28 08:08:24 +00:00
|
|
|
<!--
|
2022-01-27 12:29:49 +00:00
|
|
|
{{ if show_details }}
|
2022-01-31 05:53:51 +00:00
|
|
|
{{ if host }}Host: {{ host }}{{ end }}
|
2022-01-27 12:29:49 +00:00
|
|
|
{{ if original_uri }}Original URI: {{ original_uri }}{{ end }}
|
2022-01-31 05:53:51 +00:00
|
|
|
{{ if forwarded_for }}Forwarded for: {{ forwarded_for }}{{ end }}
|
2022-01-27 12:29:49 +00:00
|
|
|
{{ if namespace }}Namespace: {{ namespace }}{{ end }}
|
|
|
|
{{ if ingress_name }}Ingress name: {{ ingress_name }}{{ end }}
|
|
|
|
{{ if service_name }}Service name: {{ service_name }}{{ end }}
|
|
|
|
{{ if service_port }}Service port: {{ service_port }}{{ end }}
|
|
|
|
{{ if request_id }}Request ID: {{ request_id }}{{ end }}
|
2024-07-03 14:12:13 +00:00
|
|
|
Timestamp: {{ nowUnix }}
|
2022-01-27 12:29:49 +00:00
|
|
|
{{ end }}
|
2021-04-28 08:08:24 +00:00
|
|
|
-->
|
2021-04-21 20:53:59 +00:00
|
|
|
<html lang="en">
|
|
|
|
<head>
|
2024-07-03 14:12:13 +00:00
|
|
|
<meta charset="utf-8">
|
|
|
|
<meta name="robots" content="nofollow,noarchive,noindex">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<!-- {{ if or (eq code 408) (eq code 425) (eq code 429) (eq code 500) (eq code 502) (eq code 503) (eq code 504) }} -->
|
|
|
|
<meta http-equiv="refresh" content="30">
|
|
|
|
<!-- {{ end }} -->
|
|
|
|
<meta name="title" content="{{ code }}: {{ message | escape }}">
|
|
|
|
<meta name="description" content="{{ description | escape }}">
|
|
|
|
<meta property="og:title" content="{{ code }}: {{ message | escape }}">
|
|
|
|
<meta property="og:description" content="{{ description | escape }}">
|
|
|
|
<meta property="twitter:title" content="{{ code }}: {{ message | escape }}">
|
|
|
|
<meta property="twitter:description" content="{{ description | escape }}">
|
|
|
|
<title>{{ code }}: {{ message }}</title>
|
|
|
|
<style>
|
|
|
|
html, body {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
min-height: 100%;
|
|
|
|
height: 100%;
|
|
|
|
width: 100%;
|
|
|
|
background-color: #111;
|
|
|
|
color: #333;
|
|
|
|
overflow: hidden;
|
|
|
|
font-family: sans-serif;
|
|
|
|
font-size: 20px;
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas {
|
|
|
|
z-index: 1;
|
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
top: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.frame {
|
|
|
|
z-index: 3;
|
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
top: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
background: radial-gradient(ellipse at center, rgba(0, 0, 0, .1) 0%, rgba(0, 0, 0, .2) 19%, rgba(0, 0, 0, .9) 100%);
|
|
|
|
}
|
|
|
|
|
|
|
|
@keyframes horizontalLine {
|
|
|
|
0% {
|
|
|
|
top: -25%;
|
|
|
|
}
|
|
|
|
100% {
|
|
|
|
top: 100%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.frame div {
|
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
top: -25%;
|
|
|
|
width: 100%;
|
|
|
|
height: 20%;
|
|
|
|
background-color: rgba(0, 0, 0, .12);
|
|
|
|
box-shadow: 0 0 30px rgba(0, 0, 0, .25);
|
|
|
|
transform: rotate(2deg);
|
|
|
|
animation: horizontalLine 12s linear infinite;
|
|
|
|
}
|
|
|
|
|
|
|
|
.frame div:nth-child(1) {
|
|
|
|
animation-delay: 0ms;
|
|
|
|
}
|
|
|
|
|
|
|
|
.frame div:nth-child(2) {
|
|
|
|
animation-delay: 4s;
|
|
|
|
}
|
|
|
|
|
|
|
|
.frame div:nth-child(3) {
|
|
|
|
animation-delay: 8s;
|
|
|
|
}
|
|
|
|
|
|
|
|
.container-center {
|
|
|
|
height: 100%;
|
|
|
|
align-items: center;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.container-center div {
|
|
|
|
z-index: 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
h1, h2 {
|
|
|
|
text-align: center;
|
|
|
|
color: transparent;
|
|
|
|
text-shadow: 0 0 10px rgba(0, 0, 0, .6);
|
|
|
|
}
|
|
|
|
|
|
|
|
@keyframes codeText {
|
|
|
|
0% {
|
|
|
|
text-shadow: 0 0 15px rgba(0, 0, 0, .3);
|
|
|
|
}
|
|
|
|
33% {
|
|
|
|
text-shadow: 0 0 5px rgba(0, 0, 0, .2);
|
|
|
|
}
|
|
|
|
66% {
|
|
|
|
text-shadow: 0 0 10px rgba(0, 0, 0, .1);
|
|
|
|
}
|
|
|
|
100% {
|
|
|
|
text-shadow: 0 0 15px rgba(0, 0, 0, .3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
font: bold 13em Arial, sans-serif;
|
|
|
|
animation: codeText 2s linear infinite;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@keyframes descriptionText {
|
|
|
|
0% {
|
|
|
|
text-shadow: 0 0 10px rgba(0, 0, 0, .5)
|
|
|
|
}
|
|
|
|
33% {
|
|
|
|
text-shadow: 0 0 5px rgba(0, 0, 0, .1)
|
|
|
|
}
|
|
|
|
66% {
|
|
|
|
text-shadow: 0 0 5px rgba(0, 0, 0, .25)
|
|
|
|
}
|
|
|
|
100% {
|
|
|
|
text-shadow: 0 0 10px rgba(0, 0, 0, .5)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
h2 {
|
|
|
|
font: bold 2.5em Arial, sans-serif;
|
|
|
|
animation: descriptionText 4s linear infinite;
|
|
|
|
margin-bottom: 0;
|
|
|
|
}
|
|
|
|
</style>
|
2021-04-21 20:53:59 +00:00
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
|
|
|
|
<div class="container-center">
|
2024-07-03 14:12:13 +00:00
|
|
|
<div>
|
|
|
|
<h1>{{code}}</h1>
|
|
|
|
<h2 data-l10n>{{ description }}</h2>
|
|
|
|
</div>
|
2021-04-21 20:53:59 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="frame">
|
2024-07-03 14:12:13 +00:00
|
|
|
<div></div>
|
|
|
|
<div></div>
|
|
|
|
<div></div>
|
2021-04-21 20:53:59 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<canvas id="canvas"></canvas>
|
|
|
|
|
|
|
|
<script>
|
2024-07-03 14:12:13 +00:00
|
|
|
// main idea author: https://codepen.io/moklick
|
|
|
|
const $canvas = document.getElementById('canvas');
|
|
|
|
const width = Math.max(800, document.body.clientWidth);
|
|
|
|
const height = Math.max(600, document.body.clientHeight);
|
|
|
|
|
|
|
|
$canvas.width = width;
|
|
|
|
$canvas.height = height;
|
|
|
|
|
|
|
|
const ctx = $canvas.getContext('2d');
|
|
|
|
|
|
|
|
ctx.fillStyle = '#404040';
|
|
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
ctx.fill();
|
|
|
|
|
|
|
|
const imgData = ctx.getImageData(0, 0, width, height)
|
|
|
|
const onScreen = imgData.data;
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
// allocate a peace of memory to fill with random color
|
|
|
|
const pixelsBuffToRepeat = new Uint8ClampedArray(Math.min(onScreen.length, 1024 * 32));
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
// fill the buffer with random grayscale colors
|
|
|
|
for (let i = 0; i < pixelsBuffToRepeat.length; i += 4) {
|
|
|
|
const color = Math.floor((Math.random() * 255) + 50);
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
pixelsBuffToRepeat[i] = color; // R value
|
|
|
|
pixelsBuffToRepeat[i + 1] = color; // G value
|
|
|
|
pixelsBuffToRepeat[i + 2] = color; // B value
|
|
|
|
pixelsBuffToRepeat[i + 3] = 255; // A value
|
|
|
|
}
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
// prevent the redraw function from running multiple times at the same time
|
|
|
|
let redrawMutex = false;
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
const redraw = () => {
|
|
|
|
if (redrawMutex) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
redrawMutex = true;
|
|
|
|
|
|
|
|
const dstLen = onScreen.length;
|
|
|
|
let pos = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
// pick a random length of bytes to copy from the source slice in range [0...buff.length] with the step of 4
|
|
|
|
let takeLen = Math.floor(Math.random() * pixelsBuffToRepeat.length / 4) * 4;
|
|
|
|
|
|
|
|
// if picked length is greater than the remaining space in the onScreen, adjust it
|
|
|
|
if (pos + takeLen > dstLen) {
|
|
|
|
takeLen = dstLen - pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy the random length of bytes from the buffer to the onScreen
|
|
|
|
onScreen.set(pixelsBuffToRepeat.slice(0, takeLen), pos);
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
// move the position in the onScreen to the next random position
|
|
|
|
pos += takeLen;
|
|
|
|
} while (pos < dstLen)
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
ctx.putImageData(imgData, 0, 0);
|
2021-04-21 20:53:59 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
queueMicrotask(() => {
|
|
|
|
redrawMutex = false
|
2021-04-21 20:53:59 +00:00
|
|
|
});
|
2024-07-03 14:12:13 +00:00
|
|
|
};
|
2022-03-23 19:31:34 +00:00
|
|
|
|
2024-07-03 14:12:13 +00:00
|
|
|
redraw(); // draw the noise first time
|
|
|
|
|
|
|
|
const redrawFrequency = 45; // redraw the noise every 45ms
|
|
|
|
/** @type {Number|undefined} */
|
|
|
|
let flickerInterval = window.setInterval(redraw, redrawFrequency);
|
|
|
|
|
|
|
|
// stop drawing when the tab is hidden
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event
|
|
|
|
window.addEventListener('visibilitychange', () => {
|
|
|
|
if (document.hidden && flickerInterval !== undefined) {
|
|
|
|
window.clearInterval(flickerInterval);
|
|
|
|
flickerInterval = undefined;
|
|
|
|
} else if (!document.hidden && flickerInterval === undefined) {
|
|
|
|
flickerInterval = window.setInterval(redraw, redrawFrequency);
|
2022-03-23 19:31:34 +00:00
|
|
|
}
|
2024-07-03 14:12:13 +00:00
|
|
|
});
|
2021-04-21 20:53:59 +00:00
|
|
|
</script>
|
2024-07-03 14:12:13 +00:00
|
|
|
|
|
|
|
<!-- {{- if l10n_enabled -}} -->
|
|
|
|
<script>// {{ l10nScript }}</script>
|
|
|
|
<!-- {{- end -}} -->
|
2021-04-21 20:53:59 +00:00
|
|
|
</body>
|
|
|
|
</html>
|