mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
fac7394ae2 | |||
4a918b1899 | |||
05be3841d7 | |||
02cadcd907 | |||
94dff2421c | |||
51f8824659 | |||
e82c02c768 | |||
dc51e3192c | |||
45ca69432b | |||
f5f572a4d3 | |||
2d418ecffa | |||
c6b3342361 | |||
3614f0503f |
9
.gitattributes
vendored
Normal file
9
.gitattributes
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Text files have auto line endings
|
||||
* text=auto
|
||||
|
||||
# Go source files always have LF line endings
|
||||
*.go text eol=lf
|
||||
|
||||
# Disable next extensions in project "used languages" list
|
||||
*.lua linguist-detectable=false
|
||||
*.html linguist-detectable=false
|
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -155,6 +155,8 @@ jobs: # Docs: <https://git.io/JvxXE>
|
||||
test -f ./out/cats/404.html
|
||||
test -f ./out/lost-in-space/404.html
|
||||
test -f ./out/app-down/404.html
|
||||
test -f ./out/connection/404.html
|
||||
test -f ./out/matrix/404.html
|
||||
|
||||
docker-image:
|
||||
name: Build docker image
|
||||
|
35
CHANGELOG.md
35
CHANGELOG.md
@ -4,6 +4,41 @@ All notable changes to this package will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].
|
||||
|
||||
## v2.11.0
|
||||
|
||||
### Added
|
||||
|
||||
- Template `matrix` [#81]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Localization mistakes [#81]
|
||||
|
||||
[#81]:https://github.com/tarampampam/error-pages/pull/81
|
||||
|
||||
## v2.10.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- Template `shuffle`
|
||||
- Localization mistakes
|
||||
|
||||
## v2.10.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Error pages now translated in 🇺🇦 and 🇷🇺 languages [#80]
|
||||
|
||||
[#80]:https://github.com/tarampampam/error-pages/pull/80
|
||||
|
||||
## v2.9.0
|
||||
|
||||
### Added
|
||||
|
||||
- Template `connection` [#79]
|
||||
|
||||
[#79]:https://github.com/tarampampam/error-pages/pull/79
|
||||
|
||||
## v2.8.1
|
||||
|
||||
### Fixed
|
||||
|
11
README.md
11
README.md
@ -34,6 +34,7 @@ One day you may want to replace the standard error pages of your HTTP server wit
|
||||
- Error pages can be [embedded into your own `nginx`][wiki-usage-with-nginx] docker image
|
||||
- Fully configurable (take a look at the [configuration file](https://github.com/tarampampam/error-pages/blob/master/error-pages.yml) and [project Wiki][wiki])
|
||||
- Distributed using docker image and compiled binary files
|
||||
- Localized (🇺🇸, 🇺🇦, 🇷🇺) HTML error pages (translation process [described here](https://github.com/tarampampam/error-pages/tree/master/l10n) - other translations are welcome!)
|
||||
|
||||
## 🧩 Install
|
||||
|
||||
@ -122,12 +123,14 @@ Transfer/sec: 140.23MB
|
||||
| `cats` | [![cats][cats-screen]][cats-link] |
|
||||
| `lost-in-space` | [![lost-in-space][lost-in-space-screen]][lost-in-space-link] |
|
||||
| `app-down` | [![app-down][app-down-screen]][app-down-link] |
|
||||
| `connection` | [![connection][connection-screen]][connection-link] |
|
||||
| `matrix` | [![matrix][matrix-screen]][matrix-link] |
|
||||
|
||||
> Note: `noise` template highly uses the CPU, be careful
|
||||
|
||||
[ghost-screen]:https://hsto.org/webt/oj/cl/4k/ojcl4ko_cvusy5xuki6efffzsyo.gif
|
||||
[ghost-link]:https://tarampampam.github.io/error-pages/ghost/404.html
|
||||
[l7-light-screen]:https://hsto.org/webt/xc/iq/vt/xciqvty-aoj-rchfarsjhutpjny.png
|
||||
[l7-light-screen]:https://hsto.org/webt/hx/ca/mm/hxcammfm7qjmogtvsjxcidgf7c8.png
|
||||
[l7-light-link]:https://tarampampam.github.io/error-pages/l7-light/404.html
|
||||
[l7-dark-screen]:https://hsto.org/webt/s1/ih/yr/s1ihyrqs_y-sgraoimfhk6ypney.png
|
||||
[l7-dark-link]:https://tarampampam.github.io/error-pages/l7-dark/404.html
|
||||
@ -141,8 +144,12 @@ Transfer/sec: 140.23MB
|
||||
[cats-link]:https://tarampampam.github.io/error-pages/cats/404.html
|
||||
[lost-in-space-screen]:https://hsto.org/webt/lf/ln/x8/lflnx8fuy4rofxju34ttskijdsu.gif
|
||||
[lost-in-space-link]:https://tarampampam.github.io/error-pages/lost-in-space/404.html
|
||||
[app-down-screen]:https://hsto.org/webt/r3/ys/ql/r3ysqlv_1qj29k3qf_3mliedo8s.png
|
||||
[app-down-screen]:https://habrastorage.org/webt/j2/la/fj/j2lafjvu_xjflzrvhiixobxy_ca.png
|
||||
[app-down-link]:https://tarampampam.github.io/error-pages/app-down/404.html
|
||||
[connection-screen]:https://hsto.org/webt/x4/ah/jb/x4ahjboo4-arm3bxpaash_sflmw.png
|
||||
[connection-link]:https://tarampampam.github.io/error-pages/connection/404.html
|
||||
[matrix-screen]:https://hsto.org/webt/ng/tf/oi/ngtfoiolvmq6hf15kimcxmhprhk.gif
|
||||
[matrix-link]:https://tarampampam.github.io/error-pages/matrix/404.html
|
||||
|
||||
## 🦾 Contributors
|
||||
|
||||
|
@ -13,6 +13,8 @@ templates:
|
||||
- path: ./templates/cats.html
|
||||
- path: ./templates/lost-in-space.html
|
||||
- path: ./templates/app-down.html
|
||||
- path: ./templates/connection.html
|
||||
- path: ./templates/matrix.html
|
||||
|
||||
formats:
|
||||
json:
|
||||
|
227
l10n/l10n.js
Normal file
227
l10n/l10n.js
Normal file
@ -0,0 +1,227 @@
|
||||
Object.defineProperty(window, 'l10n', {
|
||||
value: new function () {
|
||||
// language codes list: <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>
|
||||
const data = { // all keys should be in english (it is default/main locale)
|
||||
'Error': {ru: 'Ошибка', uk: 'Помилка'},
|
||||
'Good luck': {ru: 'Удачи', uk: 'Успіхів'},
|
||||
'UH OH': {ru: 'Ох', uk: 'Ох'},
|
||||
'Request details': {ru: 'Детали запроса', uk: 'Деталі запиту'},
|
||||
'Double-check the URL': {ru: 'Дважды проверьте URL', uk: 'Двічі перевіряйте URL-адресу'},
|
||||
'Alternatively, go back': {ru: 'Или можете вернуться назад', uk: 'Або ви можете повернутися'},
|
||||
'Here\'s what might have happened': {ru: 'Из-за чего это могло случиться', uk: 'Що це може статися'},
|
||||
'You may have mistyped the URL': {
|
||||
ru: 'Вы могли ошибиться в URL',
|
||||
uk: 'Ви можете зробити помилку в URL-адресі'
|
||||
},
|
||||
'The site was moved': {ru: 'Сайт был перемещён', uk: 'Сайт був переміщений'},
|
||||
'It was never here': {ru: 'Он никогда не был здесь', uk: 'Він ніколи не був тут'},
|
||||
|
||||
'Bad Request': {ru: 'Некорректный запрос', uk: 'Неправильний запит'},
|
||||
'The server did not understand the request': {
|
||||
ru: 'Сервер не смог обработать запрос из-за ошибки в нём',
|
||||
uk: 'Сервер не міг обробити запит через помилку в ньому'
|
||||
},
|
||||
'Unauthorized': {ru: 'Запрос не авторизован', uk: 'Несанкціонований доступ'},
|
||||
'The requested page needs a username and a password': {
|
||||
ru: 'Для доступа к странице требуется логин и пароль',
|
||||
uk: 'Щоб отримати доступ до сторінки, потрібний логін та пароль'
|
||||
},
|
||||
'Forbidden': {ru: 'Запрещено', uk: 'Заборонено'},
|
||||
'Access is forbidden to the requested page': {
|
||||
ru: 'Доступ к странице запрещён',
|
||||
uk: 'Доступ до сторінки заборонено'
|
||||
},
|
||||
'Not Found': {ru: 'Страница не найдена', uk: 'Сторінка не знайдена'},
|
||||
'The server can not find the requested page': {
|
||||
ru: 'Сервер не смог найти запрашиваемую страницу',
|
||||
uk: 'Сервер не міг знайти запитану сторінку'
|
||||
},
|
||||
'Method Not Allowed': {ru: 'Метод не поддерживается', uk: 'Неприпустимий метод'},
|
||||
'The method specified in the request is not allowed': {
|
||||
ru: 'Указанный в запросе метод не поддерживается',
|
||||
uk: 'Метод, зазначений у запиті, не підтримується'
|
||||
},
|
||||
'Proxy Authentication Required': {ru: 'Нужна аутентификация прокси', uk: 'Потрібна ідентифікація проксі'},
|
||||
'You must authenticate with a proxy server before this request can be served': {
|
||||
ru: 'Вы должны быть авторизованы на прокси сервере для обработки этого запроса',
|
||||
uk: 'Ви повинні увійти до проксі-сервера для обробки цього запиту'
|
||||
},
|
||||
'Request Timeout': {ru: 'Истекло время ожидания', uk: 'Час запиту закінчився'},
|
||||
'The request took longer than the server was prepared to wait': {
|
||||
ru: 'Отправка запроса заняла слишком много времени',
|
||||
uk: 'Надсилання запиту зайняв занадто багато часу'
|
||||
},
|
||||
'Conflict': {ru: 'Конфликт', uk: 'Конфлікт'},
|
||||
'The request could not be completed because of a conflict': {
|
||||
ru: 'Запрос не может быть обработан из-за конфликта',
|
||||
uk: 'Запит не може бути оброблений через конфлікт'
|
||||
},
|
||||
'Gone': {ru: 'Удалено', uk: 'Вилучений'},
|
||||
'The requested page is no longer available': {
|
||||
ru: 'Запрошенная страница была удалена',
|
||||
uk: 'Запитана сторінка була видалена'
|
||||
},
|
||||
'Length Required': {ru: 'Необходима длина', uk: 'Потрібно вказати розмір'},
|
||||
'The "Content-Length" is not defined. The server will not accept the request without it': {
|
||||
ru: 'Заголовок "Content-Length" не был передан. Сервер не может обработать запрос без него',
|
||||
uk: 'Заголовок "Content-Length" не був переданий. Сервер не може обробити запит без нього'
|
||||
},
|
||||
'Precondition Failed': {ru: 'Условие ложно', uk: 'Збій під час обробки попередньої умови'},
|
||||
'The pre condition given in the request evaluated to false by the server': {
|
||||
ru: 'Ни одно из условных полей заголовка запроса не было выполнено',
|
||||
uk: 'Жодна з умовних полів заголовка запиту не була виконана'
|
||||
},
|
||||
'Payload Too Large': {ru: 'Слишком большой запрос', uk: 'Занадто великий запит'},
|
||||
'The server will not accept the request, because the request entity is too large': {
|
||||
ru: 'Сервер не может обработать запрос, так как он слишком большой',
|
||||
uk: 'Сервер не може обробити запит, оскільки він занадто великий'
|
||||
},
|
||||
'Requested Range Not Satisfiable': {ru: 'Диапазон не достижим', uk: 'Запитуваний діапазон недосяжний'},
|
||||
'The requested byte range is not available and is out of bounds': {
|
||||
ru: 'Запрошенный диапазон данных недоступен или вне допустимых пределов',
|
||||
uk: 'Описаний діапазон даних недоступний або з допустимих меж'
|
||||
},
|
||||
'I\'m a teapot': {ru: 'Я чайник', uk: 'Я чайник'},
|
||||
'Attempt to brew coffee with a teapot is not supported': {
|
||||
ru: 'Попытка заварить кофе в чайнике обречена на фиаско',
|
||||
uk: 'Спроба виварити каву в чайник приречена на фіаско'
|
||||
},
|
||||
'Too Many Requests': {ru: 'Слишком много запросов', uk: 'Занадто багато запитів'},
|
||||
'Too many requests in a given amount of time': {
|
||||
ru: 'Отправлено слишком много запросов за короткое время',
|
||||
uk: 'Надіслано занадто багато запитів на короткий час'
|
||||
},
|
||||
'Internal Server Error': {ru: 'Внутренняя ошибка сервера', uk: 'Внутрішня помилка сервера'},
|
||||
'The server met an unexpected condition': {
|
||||
ru: 'Произошло что-то неожиданное на сервере',
|
||||
uk: 'На сервері було щось несподіване'
|
||||
},
|
||||
'Bad Gateway': {ru: 'Ошибка шлюза', uk: 'Помилка шлюзу'},
|
||||
'The server received an invalid response from the upstream server': {
|
||||
ru: 'Сервер получил некорректный ответ от вышестоящего сервера',
|
||||
uk: 'Сервер отримав неправильну відповідь з сервера Upstream'
|
||||
},
|
||||
'Service Unavailable': {ru: 'Сервис недоступен', uk: 'Сервіс недоступний'},
|
||||
'The server is temporarily overloading or down': {
|
||||
ru: 'Сервер временно не может обрабатывать запросы по техническим причинам',
|
||||
uk: 'Сервер тимчасово не може обробляти запити з технічних причин'
|
||||
},
|
||||
'Gateway Timeout': {ru: 'Шлюз не отвечает', uk: 'Шлюз не відповідає'},
|
||||
'The gateway has timed out': {
|
||||
ru: 'Сервер не дождался ответа от вышестоящего сервера',
|
||||
uk: 'Сервер не чекав відповіді від сервера Upstream'
|
||||
},
|
||||
'HTTP Version Not Supported': {ru: 'Версия HTTP не поддерживается', uk: 'Версія НТТР не підтримується'},
|
||||
'The server does not support the "http protocol" version': {
|
||||
ru: 'Сервер не поддерживает запрошенную версию HTTP протокола',
|
||||
uk: 'Сервер не підтримує запитану версію HTTP-протоколу'
|
||||
},
|
||||
|
||||
'Host': {ru: 'Хост', uk: 'Хост'},
|
||||
'Original URI': {ru: 'Исходный URI', uk: 'Вихідний URI'},
|
||||
'Forwarded for': {ru: 'Перенаправлен', uk: 'Перенаправлений'},
|
||||
'Namespace': {ru: 'Пространство имён', uk: 'Простір імен'},
|
||||
'Ingress name': {ru: 'Имя Ingress', uk: 'Ім\'я Ingress'},
|
||||
'Service name': {ru: 'Имя сервиса', uk: 'Ім\'я сервісу'},
|
||||
'Service port': {ru: 'Порт сервиса', uk: 'Порт сервісу'},
|
||||
'Request ID': {ru: 'ID запроса', uk: 'ID запиту'},
|
||||
'Timestamp': {ru: 'Временная метка', uk: 'Тимчасова мітка'},
|
||||
|
||||
'client-side error': {ru: 'ошибка на стороне клиента', uk: 'помилка на стороні клієнта'},
|
||||
'server-side error': {ru: 'ошибка на стороне сервера', uk: 'помилка на стороні сервера'},
|
||||
|
||||
'Your Client': {ru: 'Ваш Браузер', uk: 'Ваш Браузер'},
|
||||
'Network': {ru: 'Сеть', uk: 'Сіть'},
|
||||
'Web Server': {ru: 'Web Сервер', uk: 'Web Сервер'},
|
||||
'What happened?': {ru: 'Что произошло?', uk: 'Що сталося?'},
|
||||
'What can i do?': {ru: 'Что можно сделать?', uk: 'Що можна зробити?'},
|
||||
'Please try again in a few minutes': {
|
||||
ru: 'Пожалуйста, попробуйте повторить запрос ещё раз чуть позже',
|
||||
uk: 'Будь ласка, спробуйте повторити запит ще раз трохи пізніше'
|
||||
},
|
||||
'Working': {ru: 'Работает', uk: 'Працює'},
|
||||
'Unknown': {ru: 'Неизвестно', uk: 'Невідомо'},
|
||||
'Please try to change the request method, headers, payload, or URL': {
|
||||
ru: 'Пожалуйста, попробуйте изменить метод запроса, заголовки, его содержимое или URL',
|
||||
uk: 'Будь ласка, спробуйте змінити метод запиту, заголовки, його вміст або URL-адресу'
|
||||
},
|
||||
'Please check your authorization data': {
|
||||
ru: 'Пожалуйста, проверьте данные авторизации',
|
||||
uk: 'Будь ласка, перевірте дані авторизації'
|
||||
},
|
||||
'Please double-check the URL and try again': {
|
||||
ru: 'Пожалуйста, дважды проверьте URL и попробуйте снова',
|
||||
uk: 'Будь ласка, двічі перевірте URL-адресу і спробуйте знову'
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @return {string}
|
||||
*/
|
||||
const serializeToken = function (token) {
|
||||
return token.toLowerCase().replaceAll(/[^a-z0-9]/g, '');
|
||||
};
|
||||
|
||||
// normalize the data keys
|
||||
for (const key in data) {
|
||||
Object.defineProperty(data, serializeToken(key), Object.getOwnPropertyDescriptor(data, key));
|
||||
delete data[key];
|
||||
}
|
||||
|
||||
// detect browser locale (take only 2 first symbols)
|
||||
let activeLocale = navigator.language.substring(0, 2).toLowerCase();
|
||||
|
||||
/**
|
||||
* @param {string} locale
|
||||
*/
|
||||
this.setLocale = function (locale) {
|
||||
activeLocale = locale.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {string|undefined?} def
|
||||
*/
|
||||
this.translate = function (token, def) {
|
||||
const t = serializeToken(token);
|
||||
|
||||
if (activeLocale === 'en' && data.hasOwnProperty(t)) {
|
||||
return token
|
||||
}
|
||||
|
||||
if (data.hasOwnProperty(t) && data[t].hasOwnProperty(activeLocale)) {
|
||||
return data[t][activeLocale];
|
||||
}
|
||||
|
||||
return def;
|
||||
};
|
||||
|
||||
/**
|
||||
* Localize all elements with HTML attribute `data-l10n`.
|
||||
*/
|
||||
this.localizeDocument = function () {
|
||||
const dataAttributeName = 'data-l10n';
|
||||
|
||||
Array.prototype.forEach.call(document.querySelectorAll('[' + dataAttributeName + ']'), ($el) => {
|
||||
const attr = $el.getAttribute(dataAttributeName).trim(),
|
||||
token = attr.length > 0 ? attr : $el.innerText.trim(),
|
||||
localized = this.translate(token, undefined);
|
||||
|
||||
if (attr.length === 0) {
|
||||
$el.setAttribute(dataAttributeName, token);
|
||||
}
|
||||
|
||||
if (localized !== undefined) {
|
||||
$el.innerText = localized;
|
||||
} else {
|
||||
console.debug(`Unsupported l10n token detected: "${token}" (locale "${activeLocale}")`, $el);
|
||||
}
|
||||
});
|
||||
};
|
||||
},
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
});
|
||||
|
||||
window.l10n.localizeDocument();
|
12
l10n/readme.md
Normal file
12
l10n/readme.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Localization
|
||||
|
||||
[](https://www.jsdelivr.com/package/gh/tarampampam/error-pages)
|
||||
|
||||
This directory contains file [l10n.js](l10n.js) for the error pages localization. The logic is very simple - pages load this file using [jsdelivr.com](https://www.jsdelivr.com/) as a CDN for [versioned content from the GitHub repository](https://www.jsdelivr.com/features#gh), and the script from this file translate tags content using the special HTML attribute `data-l10n`.
|
||||
|
||||
By default, pages markup contains strings in English (`en` locale). If you want to localize the error pages on the different locales, you should:
|
||||
|
||||
- Find your locale name on [this page](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (column `639-1`)
|
||||
- Make a fork of this repository
|
||||
- Edit file [l10n.js](l10n.js) in `data` section (append new localized strings) using locale name from the step 1
|
||||
- Make a PR with your changes
|
@ -35,7 +35,7 @@
|
||||
.details ul li{padding-top:calc(var(--font-size-small) * 1.5)}
|
||||
.details ul li:first-child{padding-top:calc(var(--font-size-small) * .6)}
|
||||
.details code,.details span,.details ul li::before{font-size:var(--font-size-small);font-weight:400}
|
||||
.details span{padding-right:7px}
|
||||
.details code{padding-left:7px}
|
||||
/* {{ end }} */
|
||||
a{text-decoration:none;color:var(--color-img-secondary)}
|
||||
.hidden{display:none}
|
||||
@ -79,30 +79,30 @@
|
||||
<body>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h2 class="title">{{ message }}</h2>
|
||||
<p>{{ description }}</p>
|
||||
<h2 class="title" data-l10n>{{ message }}</h2>
|
||||
<p data-l10n>{{ description }}</p>
|
||||
<div class="subtitle if-not-found hidden">
|
||||
<p>Here's what might have happened:</p>
|
||||
<p><span data-l10n>Here's what might have happened</span>:</p>
|
||||
<ul>
|
||||
<li>You may have mistyped the URL</li>
|
||||
<li>The site was moved</li>
|
||||
<li>It was never here</li>
|
||||
<li data-l10n>You may have mistyped the URL</li>
|
||||
<li data-l10n>The site was moved</li>
|
||||
<li data-l10n>It was never here</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p class="if-maybe-wrong-uri">Double-check the URL. <a class="go-back hidden">Alternatively, go back</a></p>
|
||||
<p class="if-maybe-wrong-uri"><span data-l10n>Double-check the URL</span>. <a class="go-back hidden" data-l10n>Alternatively, go back</a></p>
|
||||
{{ if show_details }}
|
||||
<div class="details">
|
||||
<p>Request details:</p>
|
||||
<p><span data-l10n>Request details</span>:</p>
|
||||
<ul>
|
||||
{{- if host }}<li><span>Host:</span> <code>{{ host }}</code></li>{{ end -}}
|
||||
{{- if original_uri }}<li><span>Original URI:</span> <code>{{ original_uri }}</code></li>{{ end -}}
|
||||
{{- if forwarded_for }}<li><span>Forwarded for:</span> <code>{{ forwarded_for }}</code></li>{{ end -}}
|
||||
{{- if namespace }}<li><span>Namespace:</span> <code>{{ namespace }}</code></li>{{ end -}}
|
||||
{{- if ingress_name }}<li><span>Ingress name:</span> <code>{{ ingress_name }}</code></li>{{ end -}}
|
||||
{{- if service_name }}<li><span>Service name:</span> <code>{{ service_name }}</code></li>{{ end -}}
|
||||
{{- if service_port }}<li><span>Service port:</span> <code>{{ service_port }}</code></li>{{ end -}}
|
||||
{{- if request_id }}<li><span>Request ID:</span> <code>{{ request_id }}</code></li>{{ end -}}
|
||||
<li><span>Timestamp:</span> <code>{{ now.Unix }}</code></li>
|
||||
{{- if host }}<li><span><span data-l10n>Host</span>:</span> <code>{{ host }}</code></li>{{ end -}}
|
||||
{{- if original_uri }}<li><span><span data-l10n>Original URI</span>:</span> <code>{{ original_uri }}</code></li>{{ end -}}
|
||||
{{- if forwarded_for }}<li><span><span data-l10n>Forwarded for</span>:</span> <code>{{ forwarded_for }}</code></li>{{ end -}}
|
||||
{{- if namespace }}<li><span><span data-l10n>Namespace</span>:</span> <code>{{ namespace }}</code></li>{{ end -}}
|
||||
{{- if ingress_name }}<li><span><span data-l10n>Ingress name</span>:</span> <code>{{ ingress_name }}</code></li>{{ end -}}
|
||||
{{- if service_name }}<li><span><span data-l10n>Service name</span>:</span> <code>{{ service_name }}</code></li>{{ end -}}
|
||||
{{- if service_port }}<li><span><span data-l10n>Service port</span>:</span> <code>{{ service_port }}</code></li>{{ end -}}
|
||||
{{- if request_id }}<li><span><span data-l10n>Request ID</span>:</span> <code>{{ request_id }}</code></li>{{ end -}}
|
||||
<li><span><span data-l10n>Timestamp</span>:</span> <code>{{ now.Unix }}</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
||||
@ -224,6 +224,15 @@
|
||||
$el.style.display = 'none'; // hide the element
|
||||
}
|
||||
});
|
||||
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
|
@ -63,39 +63,39 @@
|
||||
<div class="details">
|
||||
<table>
|
||||
{{- if host }}<tr>
|
||||
<td class="name">Host</td>
|
||||
<td class="name" data-l10n>Host</td>
|
||||
<td class="value">{{ host }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if original_uri }}<tr>
|
||||
<td class="name">Original URI</td>
|
||||
<td class="name" data-l10n>Original URI</td>
|
||||
<td class="value">{{ original_uri }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if forwarded_for }}<tr>
|
||||
<td class="name">Forwarded for</td>
|
||||
<td class="name" data-l10n>Forwarded for</td>
|
||||
<td class="value">{{ forwarded_for }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if namespace }}<tr>
|
||||
<td class="name">Namespace</td>
|
||||
<td class="name" data-l10n>Namespace</td>
|
||||
<td class="value">{{ namespace }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if ingress_name }}<tr>
|
||||
<td class="name">Ingress name</td>
|
||||
<td class="name" data-l10n>Ingress name</td>
|
||||
<td class="value">{{ ingress_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_name }}<tr>
|
||||
<td class="name">Service name</td>
|
||||
<td class="name" data-l10n>Service name</td>
|
||||
<td class="value">{{ service_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_port }}<tr>
|
||||
<td class="name">Service port</td>
|
||||
<td class="name" data-l10n>Service port</td>
|
||||
<td class="value">{{ service_port }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if request_id }}<tr>
|
||||
<td class="name">Request ID</td>
|
||||
<td class="name" data-l10n>Request ID</td>
|
||||
<td class="value">{{ request_id }}</td>
|
||||
</tr>{{ end -}}
|
||||
<tr>
|
||||
<td class="name">Timestamp</td>
|
||||
<td class="name" data-l10n>Timestamp</td>
|
||||
<td class="value">{{ now.Unix }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -103,6 +103,16 @@
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
|
270
templates/connection.html
Normal file
270
templates/connection.html
Normal file
@ -0,0 +1,270 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
Description: {{ description }}
|
||||
-->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta name="robots" content="noindex, nofollow"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<title>{{ code }} | {{ message }}</title>
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Red+Hat+Display:wght@500&family=Fira+Mono&family=Ubuntu&display=swap" rel="stylesheet"/>
|
||||
<style>
|
||||
/** Idea author: https://github.com/186526/CloudflareCustomErrorPage */
|
||||
:root{--color-bg-primary:#fff;--color-text-primary:#000;--color-text-secondary:#575958;--font-size-primary:56px;--font-size-secondary:20px;--ui-card-color-bg:#f2f2f2;--color-text-ok:#137333;--color-bg-ok:#e6f4ea;--color-text-error:#c5221f;--color-bg-error:#fce8e6;--color-text-warning:#b05a00;--color-bg-warning:#fef7e0;--icon-size:48px}
|
||||
@media (prefers-color-scheme:dark){
|
||||
:root{--color-bg-primary:#111;--color-text-primary:rgba(255, 255, 255, 0.86);--color-text-secondary:rgba(255, 255, 255, 0.4);--ui-card-color-bg:rgba(40, 40, 40, 0.73);--color-bg-ok:#07220f;--color-bg-error:#270501;--color-bg-warning:#392605}
|
||||
}
|
||||
body{margin:2rem 2rem;font-family:'Red Hat Display',Ubuntu,Roboto,'Noto Sans SC',sans-serif;color:var(--color-text-primary);background-color:var(--color-bg-primary)}
|
||||
header{margin-left:1rem}
|
||||
header .error-code{font-size:var(--font-size-primary);line-height:var(--font-size-primary);font-family:'Fira Mono',Ubuntu,monospace;font-weight:400;margin:0 0 0 10px}
|
||||
header .error-description{font-family:Ubuntu,Roboto,'Noto Sans SC',sans-serif;font-size:var(--font-size-secondary);color:var(--color-text-secondary);margin:0 0 0 10px}
|
||||
code{font-family:'Fira Mono',monospace}
|
||||
.status{margin-top:2.5rem;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;align-items:center}
|
||||
.card{background-color:var(--ui-card-color-bg);padding:2rem;margin:1rem 1rem;min-height:3rem;border-radius:9px;flex-grow:1}
|
||||
.arrows svg{fill:var(--color-text-secondary)}
|
||||
.icon svg{width:var(--icon-size);height:auto;fill:var(--color-text-primary)}
|
||||
.card.ok{background-color:var(--color-bg-ok)}.card.ok .status-text{color:var(--color-text-ok)}.card.ok svg{fill:var(--color-text-ok)}
|
||||
.card.error{background-color:var(--color-bg-error)}.card.error .status-text{color:var(--color-text-error)}.card.error svg{fill:var(--color-text-error)}
|
||||
.card.warning{background-color:var(--color-bg-warning)}.card.warning .status-text{color:var(--color-text-warning)}.card.warning svg{fill:var(--color-text-warning)}
|
||||
.card main{font-size:calc(var(--font-size-secondary) + .1rem)}
|
||||
.card .status-text,.reason p{margin:0;font-family:Ubuntu,Roboto,Noto Sans SC,sans-serif}
|
||||
.reason p{line-height:125%}
|
||||
a{text-decoration:none;color:#1967d2}
|
||||
.reason{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:baseline}
|
||||
.reason>*{display:block;margin:1rem;flex-grow:1;max-width:40%}
|
||||
.reason h2{font-size:calc(var(--font-size-secondary) + .2rem);margin:0 0 .6em 0;font-weight:550}
|
||||
footer{margin:1rem;color:var(--color-text-secondary);font-size:0}
|
||||
/* {{ if show_details }} */
|
||||
footer .details{margin-top:20px}
|
||||
footer .details ul{padding:0}
|
||||
footer .details code,footer .details span{font-size:calc(var(--font-size-secondary) - .6rem)}
|
||||
footer .details code{padding-left:7px}
|
||||
/* {{ end }} */
|
||||
@media screen and (max-width:820px){
|
||||
.arrows{display:none}
|
||||
}
|
||||
@media screen and (max-width:480px){
|
||||
.reason>*{max-width:100%}
|
||||
/* {{ if show_details }} */
|
||||
footer .details code,footer .details span{font-size:calc(var(--font-size-secondary) - .3rem)}
|
||||
/* {{ end }} */
|
||||
}
|
||||
@media screen and (min-width:768px){
|
||||
body{margin:8% 10%}
|
||||
header>*{display:inline-block;margin-left:1%}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1 class="error-code">{{ code }}</h1>
|
||||
<p class="error-description">{{ message }}</p>
|
||||
</header>
|
||||
<div class="status">
|
||||
<div class="card warning" id="client-status-card">
|
||||
<i class="icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||
<path d="M0 0h24v24H0V0z" fill="none"/>
|
||||
<path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm0 14H5V8h14v10z"/>
|
||||
</svg>
|
||||
</i>
|
||||
<main data-l10n>Your Client</main>
|
||||
<p class="status-text" data-l10n>Unknown</p>
|
||||
</div>
|
||||
|
||||
<div class="arrows">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" width="24px" fill="#000000">
|
||||
<defs>
|
||||
<symbol id="arrows-horizontal" viewBox="0 0 24 24">
|
||||
<rect fill="none" height="24" width="24" x="0"/>
|
||||
<polygon points="7.41,13.41 6,12 2,16 6,20 7.41,18.59 5.83,17 21,17 21,15 5.83,15"/>
|
||||
<polygon points="16.59,10.59 18,12 22,8 18,4 16.59,5.41 18.17,7 3,7 3,9 18.17,9"/>
|
||||
</symbol>
|
||||
</defs>
|
||||
<use href="#arrows-horizontal"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="card ok" id="network-status-card">
|
||||
<i class="icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||
<path d="M0 0h24v24H0V0z" fill="none"/>
|
||||
<path d="M12 6c2.62 0 4.88 1.86 5.39 4.43l.3 1.5 1.53.11c1.56.1 2.78 1.41 2.78 2.96 0 1.65-1.35 3-3 3H6c-2.21 0-4-1.79-4-4 0-2.05 1.53-3.76 3.56-3.97l1.07-.11.5-.95C8.08 7.14 9.94 6 12 6m0-2C9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96C18.67 6.59 15.64 4 12 4z"/>
|
||||
</svg>
|
||||
</i>
|
||||
<main data-l10n>Network</main>
|
||||
<p class="status-text" data-l10n>Working</p>
|
||||
</div>
|
||||
|
||||
<div class="arrows">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" width="24px" fill="#000000">
|
||||
<use href="#arrows-horizontal" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="card warning" id="server-status-card">
|
||||
<i class="icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
||||
<path d="M0 0h24v24H0V0z" fill="none"/>
|
||||
<path d="M19 15v4H5v-4h14m1-2H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 18.5c-.82 0-1.5-.67-1.5-1.5s.68-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM19 5v4H5V5h14m1-2H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 8.5c-.82 0-1.5-.67-1.5-1.5S6.18 5.5 7 5.5s1.5.68 1.5 1.5S7.83 8.5 7 8.5z"/>
|
||||
</svg>
|
||||
</i>
|
||||
<main data-l10n>Web Server</main>
|
||||
<p class="status-text" data-l10n>Unknown</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reason">
|
||||
<div class="what-happened">
|
||||
<h2 data-l10n>What happened?</h2>
|
||||
<p class="description" data-l10n>{{ description }}</p>
|
||||
</div>
|
||||
<div class="what-can-i-do">
|
||||
<h2 data-l10n>What can I do?</h2>
|
||||
<p class="description" data-l10n>Please try again in a few minutes</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<footer>
|
||||
{{ if show_details }}
|
||||
<div class="details">
|
||||
<ul>
|
||||
{{- if host }}<li><span><span data-l10n>Host</span>:</span> <code>{{ host }}</code></li>{{ end -}}
|
||||
{{- if original_uri }}<li><span><span data-l10n>Original URI</span>:</span> <code>{{ original_uri }}</code></li>{{ end -}}
|
||||
{{- if forwarded_for }}<li><span><span data-l10n>Forwarded for</span>:</span> <code>{{ forwarded_for }}</code></li>{{ end -}}
|
||||
{{- if namespace }}<li><span><span data-l10n>Namespace</span>:</span> <code>{{ namespace }}</code></li>{{ end -}}
|
||||
{{- if ingress_name }}<li><span><span data-l10n>Ingress name</span>:</span> <code>{{ ingress_name }}</code></li>{{ end -}}
|
||||
{{- if service_name }}<li><span><span data-l10n>Service name</span>:</span> <code>{{ service_name }}</code></li>{{ end -}}
|
||||
{{- if service_port }}<li><span><span data-l10n>Service port</span>:</span> <code>{{ service_port }}</code></li>{{ end -}}
|
||||
{{- if request_id }}<li><span><span data-l10n>Request ID</span>:</span> <code>{{ request_id }}</code></li>{{ end -}}
|
||||
<li><span><span data-l10n>Timestamp</span>:</span> <code>{{ now.Unix }}</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
||||
</footer>
|
||||
<script>
|
||||
const errorCode = parseInt(`{{ code }}`, 10);
|
||||
|
||||
if (typeof errorCode !== 'undefined' && !isNaN(errorCode)) {
|
||||
/**
|
||||
* @param {HTMLElement} $card
|
||||
* @param { {isOk?: boolean, isWarning?: boolean, isError?: boolean} } state
|
||||
* @param {string} statusText
|
||||
*/
|
||||
const setCardState = function ($card, state, statusText) {
|
||||
const okClass = 'ok', warnClass = 'warning', errClass = 'error',
|
||||
$statusText = $card.querySelectorAll('.status-text');
|
||||
|
||||
switch (true) {
|
||||
case state.isOk === true:
|
||||
$card.classList.remove(errClass, warnClass);
|
||||
$card.classList.add(okClass);
|
||||
$statusText.forEach(($statusText) => $statusText.innerText = statusText);
|
||||
break;
|
||||
|
||||
case state.isWarning === true:
|
||||
$card.classList.remove(okClass, errClass);
|
||||
$card.classList.add(warnClass);
|
||||
$statusText.forEach(($statusText) => $statusText.innerText = statusText);
|
||||
break;
|
||||
|
||||
case state.isError === true:
|
||||
$card.classList.remove(okClass, warnClass);
|
||||
$card.classList.add(errClass);
|
||||
$statusText.forEach(($statusText) => $statusText.innerText = statusText);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param { {whatHappened?: string, whatToDo?: string} } reasons
|
||||
*/
|
||||
const setReasons = function (reasons) {
|
||||
const descSelector = '.description';
|
||||
|
||||
Array.prototype.forEach.call(document.getElementsByClassName('what-happened'), ($el) => {
|
||||
if (typeof reasons.whatHappened === 'string' && reasons.whatHappened.length > 0) {
|
||||
Array.prototype.forEach.call($el.querySelectorAll(descSelector), ($desc) => $desc.innerText = reasons.whatHappened);
|
||||
} else {
|
||||
$el.remove();
|
||||
}
|
||||
});
|
||||
|
||||
Array.prototype.forEach.call(document.getElementsByClassName('what-can-i-do'), ($el) => {
|
||||
if (typeof reasons.whatToDo === 'string' && reasons.whatToDo.length > 0) {
|
||||
Array.prototype.forEach.call($el.querySelectorAll(descSelector), ($desc) => $desc.innerText = reasons.whatToDo);
|
||||
} else {
|
||||
$el.remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
const setErrorDescription = function (text) {
|
||||
Array.prototype.forEach.call(document.getElementsByClassName('error-description'), function ($el) {
|
||||
$el.innerHTML = text;
|
||||
});
|
||||
};
|
||||
|
||||
const message = `{{ message }}`.trim(), cards = {
|
||||
$client: document.getElementById('client-status-card'),
|
||||
$network: document.getElementById('network-status-card'),
|
||||
$server: document.getElementById('server-status-card'),
|
||||
};
|
||||
|
||||
let whatToDo = 'Please try again in a few minutes';
|
||||
|
||||
switch (true) {
|
||||
case errorCode >= 400 && errorCode <= 499:
|
||||
switch (errorCode) {
|
||||
case 400: case 405: case 411: case 413: whatToDo = 'Please try to change the request method, headers, payload, or URL'; break;
|
||||
case 401: case 403: case 407: whatToDo = 'Please check your authorization data'; break;
|
||||
case 404: whatToDo = 'Please double-check the URL and try again'; break;
|
||||
case 409: case 410: case 418: whatToDo = '¯\\_(ツ)_/¯'; break;
|
||||
}
|
||||
|
||||
setErrorDescription(`<span data-l10n>${message}</span> (<span data-l10n>client-side error</span>)`);
|
||||
setCardState(cards.$client, {isError: true}, message)
|
||||
setCardState(cards.$network, {isOk: true}, 'Working')
|
||||
setCardState(cards.$server, {isOk: true}, 'Working')
|
||||
break;
|
||||
|
||||
case errorCode >= 500 && errorCode <= 599:
|
||||
setErrorDescription(`<span data-l10n>${message}</span> (<span data-l10n>server-side error</span>)`);
|
||||
setCardState(cards.$client, {isOk: true}, 'Working')
|
||||
setCardState(cards.$network, {isOk: true}, 'Working')
|
||||
setCardState(cards.$server, {isError: true}, message)
|
||||
break;
|
||||
|
||||
default:
|
||||
setErrorDescription(message);
|
||||
setCardState(cards.$client, {isWarning: true}, 'Unknown')
|
||||
setCardState(cards.$network, {isOk: true}, 'Working')
|
||||
setCardState(cards.$server, {isWarning: true}, 'Unknown')
|
||||
break;
|
||||
}
|
||||
|
||||
setReasons({whatHappened: `{{ description }}`.trim(), whatToDo: whatToDo.trim()});
|
||||
} else {
|
||||
console.warn('Cannot parse the error code:', errorCode);
|
||||
}
|
||||
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
Description: {{ description }}
|
||||
-->
|
||||
</html>
|
@ -9,7 +9,8 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<title>{{ code }}: {{ message }}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
html,body {background-color:#1a1a1a;color:#fff;font-family:'Open Sans',sans-serif;height:100vh;margin:0;font-size:0}
|
||||
.container {height:100vh;align-items:center;display:flex;justify-content:center;position:relative}
|
||||
@ -33,7 +34,7 @@
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="wrap">
|
||||
<svg class="ghost" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="127.433px" height="132.743px" viewBox="0 0 127.433 132.743" enable-background="new 0 0 127.433 132.743" xml:space="preserve">
|
||||
<svg class="ghost" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="127.433px" height="132.743px" viewBox="0 0 127.433 132.743" xml:space="preserve">
|
||||
<path fill="#FFF6F4" d="M116.223,125.064c1.032-1.183,1.323-2.73,1.391-3.747V54.76c0,0-4.625-34.875-36.125-44.375 s-66,6.625-72.125,44l-0.781,63.219c0.062,4.197,1.105,6.177,1.808,7.006c1.94,1.811,5.408,3.465,10.099-0.6 c7.5-6.5,8.375-10,12.75-6.875s5.875,9.75,13.625,9.25s12.75-9,13.75-9.625s4.375-1.875,7,1.25s5.375,8.25,12.875,7.875 s12.625-8.375,12.625-8.375s2.25-3.875,7.25,0.375s7.625,9.75,14.375,8.125C114.739,126.01,115.412,125.902,116.223,125.064z"></path>
|
||||
<circle fill="#1a1a1a" cx="86.238" cy="57.885" r="6.667"></circle>
|
||||
<circle fill="#1a1a1a" cx="40.072" cy="57.885" r="6.667"></circle>
|
||||
@ -46,49 +47,49 @@
|
||||
<path fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" d="M116.279,55.814c-0.021-0.286-2.323-28.744-30.221-41.012 c-7.806-3.433-15.777-5.173-23.691-5.173c-16.889,0-30.283,7.783-37.187,15.067c-9.229,9.736-13.84,26.712-14.191,30.259 l-0.748,62.332c0.149,2.133,1.389,6.167,5.019,6.167c1.891,0,4.074-1.083,6.672-3.311c4.96-4.251,7.424-6.295,9.226-6.295 c1.339,0,2.712,1.213,5.102,3.762c4.121,4.396,7.461,6.355,10.833,6.355c2.713,0,5.311-1.296,7.942-3.962 c3.104-3.145,5.701-5.239,8.285-5.239c2.116,0,4.441,1.421,7.317,4.473c2.638,2.8,5.674,4.219,9.022,4.219 c4.835,0,8.991-2.959,11.27-5.728l0.086-0.104c1.809-2.2,3.237-3.938,5.312-3.938c2.208,0,5.271,1.942,9.359,5.936 c0.54,0.743,3.552,4.674,6.86,4.674c1.37,0,2.559-0.65,3.531-1.932l0.203-0.268L116.279,55.814z M114.281,121.405 c-0.526,0.599-1.096,0.891-1.734,0.891c-2.053,0-4.51-2.82-5.283-3.907l-0.116-0.136c-4.638-4.541-7.975-6.566-10.82-6.566 c-3.021,0-4.884,2.267-6.857,4.667l-0.086,0.104c-1.896,2.307-5.582,4.999-9.725,4.999c-2.775,0-5.322-1.208-7.567-3.59 c-3.325-3.528-6.03-5.102-8.772-5.102c-3.278,0-6.251,2.332-9.708,5.835c-2.236,2.265-4.368,3.366-6.518,3.366 c-2.772,0-5.664-1.765-9.374-5.723c-2.488-2.654-4.29-4.395-6.561-4.395c-2.515,0-5.045,2.077-10.527,6.777 c-2.727,2.337-4.426,2.828-5.37,2.828c-2.662,0-3.017-4.225-3.021-4.225l0.745-62.163c0.332-3.321,4.767-19.625,13.647-28.995 c3.893-4.106,10.387-8.632,18.602-11.504c-0.458,0.503-0.744,1.165-0.744,1.898c0,1.565,1.269,2.833,2.833,2.833 c1.564,0,2.833-1.269,2.833-2.833c0-1.355-0.954-2.485-2.226-2.764c4.419-1.285,9.269-2.074,14.437-2.074 c7.636,0,15.336,1.684,22.887,5.004c26.766,11.771,29.011,39.047,29.027,39.251V121.405z"></path>
|
||||
</svg>
|
||||
<p class="shadowFrame">
|
||||
<svg version="1.1" class="shadow" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="61px" y="20px" width="122.436px" height="39.744px" viewBox="0 0 122.436 39.744" enable-background="new 0 0 122.436 39.744" xml:space="preserve">
|
||||
<svg class="shadow" xmlns="http://www.w3.org/2000/svg" x="61px" y="20px" width="122.436px" height="39.744px" viewBox="0 0 122.436 39.744" xml:space="preserve">
|
||||
<ellipse fill="#262626" cx="61.128" cy="19.872" rx="49.25" ry="8.916"></ellipse>
|
||||
</svg>
|
||||
</p>
|
||||
<h3>Error {{ code }}</h3>
|
||||
<p class="description">{{ description }}</p>
|
||||
<h3><span data-l10n>Error</span> {{ code }}</h3>
|
||||
<p class="description" data-l10n>{{ description }}</p>
|
||||
{{ if show_details }}
|
||||
<div class="details">
|
||||
<table>
|
||||
{{- if host }}<tr>
|
||||
<td class="name">Host</td>
|
||||
<td class="name" data-l10n>Host</td>
|
||||
<td class="value">{{ host }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if original_uri }}<tr>
|
||||
<td class="name">Original URI</td>
|
||||
<td class="name" data-l10n>Original URI</td>
|
||||
<td class="value">{{ original_uri }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if forwarded_for }}<tr>
|
||||
<td class="name">Forwarded for</td>
|
||||
<td class="name" data-l10n>Forwarded for</td>
|
||||
<td class="value">{{ forwarded_for }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if namespace }}<tr>
|
||||
<td class="name">Namespace</td>
|
||||
<td class="name" data-l10n>Namespace</td>
|
||||
<td class="value">{{ namespace }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if ingress_name }}<tr>
|
||||
<td class="name">Ingress name</td>
|
||||
<td class="name" data-l10n>Ingress name</td>
|
||||
<td class="value">{{ ingress_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_name }}<tr>
|
||||
<td class="name">Service name</td>
|
||||
<td class="name" data-l10n>Service name</td>
|
||||
<td class="value">{{ service_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_port }}<tr>
|
||||
<td class="name">Service port</td>
|
||||
<td class="name" data-l10n>Service port</td>
|
||||
<td class="value">{{ service_port }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if request_id }}<tr>
|
||||
<td class="name">Request ID</td>
|
||||
<td class="name" data-l10n>Request ID</td>
|
||||
<td class="value">{{ request_id }}</td>
|
||||
</tr>{{ end -}}
|
||||
<tr>
|
||||
<td class="name">Timestamp</td>
|
||||
<td class="name" data-l10n>Timestamp</td>
|
||||
<td class="value">{{ now.Unix }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -96,6 +97,16 @@
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
|
@ -9,8 +9,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<title>{{ message }}</title>
|
||||
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/** Idea author: https://codepen.io/robinselmer */
|
||||
html, body {
|
||||
@ -145,23 +145,33 @@
|
||||
<body>
|
||||
<div class="overlay"></div>
|
||||
<div class="terminal">
|
||||
<h1>Error <span class="error_code">{{ code }}</span></h1>
|
||||
<p class="output">{{ description }}.</p>
|
||||
<p class="output">Good luck.</p>
|
||||
<h1><span data-l10n>Error</span> <span class="error_code">{{ code }}</span></h1>
|
||||
<p class="output" data-l10n>{{ description }}.</p>
|
||||
<p class="output"><span data-l10n>Good luck</span>.</p>
|
||||
{{ if show_details }}
|
||||
<div class="details">
|
||||
{{- if host }}<p class="output small">Host: <code>{{ host }}</code></p>{{ end -}}
|
||||
{{- if original_uri }}<p class="output small">Original URI: <code>{{ original_uri }}</code></p>{{ end -}}
|
||||
{{- if forwarded_for }}<p class="output small">Forwarded for: <code>{{ forwarded_for }}</code></p>{{ end -}}
|
||||
{{- if namespace }}<p class="output small">Namespace: <code>{{ namespace }}</code></p>{{ end -}}
|
||||
{{- if ingress_name }}<p class="output small">Ingress name: <code>{{ ingress_name }}</code></p>{{ end -}}
|
||||
{{- if service_name }}<p class="output small">Service name: <code>{{ service_name }}</code></p>{{ end -}}
|
||||
{{- if service_port }}<p class="output small">Service port: <code>{{ service_port }}</code></p>{{ end -}}
|
||||
{{- if request_id }}<p class="output small">Request ID: <code>{{ request_id }}</code></p>{{ end -}}
|
||||
<p class="output small">Timestamp: <code>{{ now.Unix }}</code></p>
|
||||
{{- if host }}<p class="output small"><span data-l10n>Host</span>: <code>{{ host }}</code></p>{{ end -}}
|
||||
{{- if original_uri }}<p class="output small"><span data-l10n>Original URI</span>: <code>{{ original_uri }}</code></p>{{ end -}}
|
||||
{{- if forwarded_for }}<p class="output small"><span data-l10n>Forwarded for</span>: <code>{{ forwarded_for }}</code></p>{{ end -}}
|
||||
{{- if namespace }}<p class="output small"><span data-l10n>Namespace</span>: <code>{{ namespace }}</code></p>{{ end -}}
|
||||
{{- if ingress_name }}<p class="output small"><span data-l10n>Ingress name</span>: <code>{{ ingress_name }}</code></p>{{ end -}}
|
||||
{{- if service_name }}<p class="output small"><span data-l10n>Service name</span>: <code>{{ service_name }}</code></p>{{ end -}}
|
||||
{{- if service_port }}<p class="output small"><span data-l10n>Service port</span>: <code>{{ service_port }}</code></p>{{ end -}}
|
||||
{{- if request_id }}<p class="output small"><span data-l10n>Request ID</span>: <code>{{ request_id }}</code></p>{{ end -}}
|
||||
<p class="output small"><span data-l10n>Timestamp</span>: <code>{{ now.Unix }}</code></p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<script>
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
|
@ -33,7 +33,7 @@
|
||||
<div class="code">
|
||||
{{ code }}
|
||||
</div>
|
||||
<div class="message">
|
||||
<div class="message" data-l10n>
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
@ -41,39 +41,39 @@
|
||||
<div class="details">
|
||||
<table>
|
||||
{{- if host }}<tr>
|
||||
<td class="name">Host</td>
|
||||
<td class="name" data-l10n>Host</td>
|
||||
<td class="value">{{ host }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if original_uri }}<tr>
|
||||
<td class="name">Original URI</td>
|
||||
<td class="name" data-l10n>Original URI</td>
|
||||
<td class="value">{{ original_uri }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if forwarded_for }}<tr>
|
||||
<td class="name">Forwarded for</td>
|
||||
<td class="name" data-l10n>Forwarded for</td>
|
||||
<td class="value">{{ forwarded_for }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if namespace }}<tr>
|
||||
<td class="name">Namespace</td>
|
||||
<td class="name" data-l10n>Namespace</td>
|
||||
<td class="value">{{ namespace }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if ingress_name }}<tr>
|
||||
<td class="name">Ingress name</td>
|
||||
<td class="name" data-l10n>Ingress name</td>
|
||||
<td class="value">{{ ingress_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_name }}<tr>
|
||||
<td class="name">Service name</td>
|
||||
<td class="name" data-l10n>Service name</td>
|
||||
<td class="value">{{ service_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_port }}<tr>
|
||||
<td class="name">Service port</td>
|
||||
<td class="name" data-l10n>Service port</td>
|
||||
<td class="value">{{ service_port }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if request_id }}<tr>
|
||||
<td class="name">Request ID</td>
|
||||
<td class="name" data-l10n>Request ID</td>
|
||||
<td class="value">{{ request_id }}</td>
|
||||
</tr>{{ end -}}
|
||||
<tr>
|
||||
<td class="name">Timestamp</td>
|
||||
<td class="name" data-l10n>Timestamp</td>
|
||||
<td class="value">{{ now.Unix }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -81,6 +81,16 @@
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
|
@ -35,7 +35,7 @@
|
||||
<div class="code">
|
||||
{{ code }}
|
||||
</div>
|
||||
<div class="message">
|
||||
<div class="message" data-l10n>
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
@ -43,39 +43,39 @@
|
||||
<div class="details">
|
||||
<table>
|
||||
{{- if host }}<tr>
|
||||
<td class="name">Host</td>
|
||||
<td class="name" data-l10n>Host</td>
|
||||
<td class="value">{{ host }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if original_uri }}<tr>
|
||||
<td class="name">Original URI</td>
|
||||
<td class="name" data-l10n>Original URI</td>
|
||||
<td class="value">{{ original_uri }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if forwarded_for }}<tr>
|
||||
<td class="name">Forwarded for</td>
|
||||
<td class="name" data-l10n>Forwarded for</td>
|
||||
<td class="value">{{ forwarded_for }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if namespace }}<tr>
|
||||
<td class="name">Namespace</td>
|
||||
<td class="name" data-l10n>Namespace</td>
|
||||
<td class="value">{{ namespace }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if ingress_name }}<tr>
|
||||
<td class="name">Ingress name</td>
|
||||
<td class="name" data-l10n>Ingress name</td>
|
||||
<td class="value">{{ ingress_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_name }}<tr>
|
||||
<td class="name">Service name</td>
|
||||
<td class="name" data-l10n>Service name</td>
|
||||
<td class="value">{{ service_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_port }}<tr>
|
||||
<td class="name">Service port</td>
|
||||
<td class="name" data-l10n>Service port</td>
|
||||
<td class="value">{{ service_port }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if request_id }}<tr>
|
||||
<td class="name">Request ID</td>
|
||||
<td class="name" data-l10n>Request ID</td>
|
||||
<td class="value">{{ request_id }}</td>
|
||||
</tr>{{ end -}}
|
||||
<tr>
|
||||
<td class="name">Timestamp</td>
|
||||
<td class="name" data-l10n>Timestamp</td>
|
||||
<td class="value">{{ now.Unix }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -83,6 +83,16 @@
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
|
@ -104,12 +104,12 @@
|
||||
.details li span {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.details li code {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
padding-left: 7px;
|
||||
}
|
||||
/* {{ end }} */
|
||||
|
||||
@ -335,20 +335,20 @@
|
||||
</div>
|
||||
<div class="content">
|
||||
<h1>{{ code }}</h1>
|
||||
<h2>UH OH! {{ message }}</h2>
|
||||
<p>{{ description }}</p>
|
||||
<h2><span data-l10n>UH OH</span>! <span data-l10n>{{ message }}</span></h2>
|
||||
<p data-l10n>{{ description }}</p>
|
||||
|
||||
{{ if show_details }}
|
||||
<ul class="details">
|
||||
{{- if host }}<li><span>Host:</span> <code>{{ host }}</code></li>{{ end -}}
|
||||
{{- if original_uri }}<li><span>Original URI:</span> <code>{{ original_uri }}</code></li>{{ end -}}
|
||||
{{- if forwarded_for }}<li><span>Forwarded for:</span> <code>{{ forwarded_for }}</code></li>{{ end -}}
|
||||
{{- if namespace }}<li><span>Namespace:</span> <code>{{ namespace }}</code></li>{{ end -}}
|
||||
{{- if ingress_name }}<li><span>Ingress name:</span> <code>{{ ingress_name }}</code></li>{{ end -}}
|
||||
{{- if service_name }}<li><span>Service name:</span> <code>{{ service_name }}</code></li>{{ end -}}
|
||||
{{- if service_port }}<li><span>Service port:</span> <code>{{ service_port }}</code></li>{{ end -}}
|
||||
{{- if request_id }}<li><span>Request ID:</span> <code>{{ request_id }}</code></li>{{ end -}}
|
||||
<li><span>Timestamp:</span> <code>{{ now.Unix }}</code></li>
|
||||
{{- if host }}<li><span><span data-l10n>Host</span>:</span> <code>{{ host }}</code></li>{{ end -}}
|
||||
{{- if original_uri }}<li><span><span data-l10n>Original URI</span>:</span> <code>{{ original_uri }}</code></li>{{ end -}}
|
||||
{{- if forwarded_for }}<li><span><span data-l10n>Forwarded for</span>:</span> <code>{{ forwarded_for }}</code></li>{{ end -}}
|
||||
{{- if namespace }}<li><span><span data-l10n>Namespace</span>:</span> <code>{{ namespace }}</code></li>{{ end -}}
|
||||
{{- if ingress_name }}<li><span><span data-l10n>Ingress name</span>:</span> <code>{{ ingress_name }}</code></li>{{ end -}}
|
||||
{{- if service_name }}<li><span><span data-l10n>Service name</span>:</span> <code>{{ service_name }}</code></li>{{ end -}}
|
||||
{{- if service_port }}<li><span><span data-l10n>Service port</span>:</span> <code>{{ service_port }}</code></li>{{ end -}}
|
||||
{{- if request_id }}<li><span><span data-l10n>Request ID</span>:</span> <code>{{ request_id }}</code></li>{{ end -}}
|
||||
<li><span><span data-l10n>Timestamp</span>:</span> <code>{{ now.Unix }}</code></li>
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
@ -377,6 +377,15 @@
|
||||
} else {
|
||||
console.warn('gsap library is not initialized (network error?)')
|
||||
}
|
||||
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
279
templates/matrix.html
Normal file
279
templates/matrix.html
Normal file
@ -0,0 +1,279 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
Description: {{ description }}
|
||||
-->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="noindex, nofollow"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>{{ message }} ({{ code }})</title>
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root{--matrix-glyph-size:15px;--matrix-glyph-font-size:15px;--matrix-glyph-front-color:rgba(255, 255, 255, 0.8);--matrix-glyph-tail-color:#0f0;--matrix-overlay-color:rgba(18, 18, 18, 0.05)}
|
||||
body,html{margin:0;padding:0;background-color:#000;height:100vh}
|
||||
#matrix{display:block;position:fixed;width:100vw;height:100vh}
|
||||
.container{align-items:center;display:flex;justify-content:center;position:absolute;top:0;left:0;width:100vw;height:100vh;z-index:1}
|
||||
.container .message{background-color:rgba(0,0,0,.85);border:2px solid var(--matrix-glyph-tail-color);padding:15px 20px;margin:0 20px;font-family:Inconsolata,Helvetica,sans-serif;text-align:center;font-size:0;color:var(--matrix-glyph-tail-color);text-shadow:1px 0 2px var(--matrix-glyph-tail-color),-1px 0 2px var(--matrix-glyph-tail-color);box-shadow:1px 0 5px var(--matrix-glyph-tail-color),-1px 0 2px var(--matrix-glyph-tail-color);max-width:640px}
|
||||
.container .message h1{margin:0;font-size:52px}
|
||||
.container .message p{margin:.3em 0 0 0;font-size:17px;color:var(--matrix-glyph-front-color)}
|
||||
/* {{ if show_details }} */
|
||||
.container .details{margin-top:20px}
|
||||
.container .details ul{padding:0}
|
||||
.container .details code,.container .details span{font-size:11px}
|
||||
.container .details code{padding-left:7px}
|
||||
/* {{ end }} */
|
||||
.hidden {display:none}
|
||||
@media screen and (max-width:820px){
|
||||
:root{--matrix-glyph-size:10px;--matrix-glyph-font-size:10px}
|
||||
.container .message h1{font-size:38px}
|
||||
.container .message p{font-size:13px}
|
||||
/* {{ if show_details }} */
|
||||
.container .details code,.container .details span{font-size:11px}
|
||||
/* {{ end }} */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<ul id="matrix-words" class="hidden">
|
||||
<li>{{ code }}</li>
|
||||
<li>{{ message }}</li>
|
||||
<li>{{ description }}</li>
|
||||
<li>{{ code }} {{ message }}</li>
|
||||
</ul>
|
||||
|
||||
<div class="message">
|
||||
<h1>{{ code }}: <span data-l10n>{{ message }}</span></h1>
|
||||
<p data-l10n>{{ description }}</p>
|
||||
|
||||
{{ if show_details }}
|
||||
<div class="details">
|
||||
<ul>
|
||||
{{- if host }}<li><span><span data-l10n>Host</span>:</span> <code>{{ host }}</code></li>{{ end -}}
|
||||
{{- if original_uri }}<li><span><span data-l10n>Original URI</span>:</span> <code>{{ original_uri }}</code></li>{{ end -}}
|
||||
{{- if forwarded_for }}<li><span><span data-l10n>Forwarded for</span>:</span> <code>{{ forwarded_for }}</code></li>{{ end -}}
|
||||
{{- if namespace }}<li><span><span data-l10n>Namespace</span>:</span> <code>{{ namespace }}</code></li>{{ end -}}
|
||||
{{- if ingress_name }}<li><span><span data-l10n>Ingress name</span>:</span> <code>{{ ingress_name }}</code></li>{{ end -}}
|
||||
{{- if service_name }}<li><span><span data-l10n>Service name</span>:</span> <code>{{ service_name }}</code></li>{{ end -}}
|
||||
{{- if service_port }}<li><span><span data-l10n>Service port</span>:</span> <code>{{ service_port }}</code></li>{{ end -}}
|
||||
{{- if request_id }}<li><span><span data-l10n>Request ID</span>:</span> <code>{{ request_id }}</code></li>{{ end -}}
|
||||
<li><span><span data-l10n>Timestamp</span>:</span> <code>{{ now.Unix }}</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<canvas id="matrix"></canvas>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @param {HTMLCanvasElement} $canvas
|
||||
* @constructor
|
||||
*/
|
||||
const Matrix = function ($canvas) {
|
||||
const symbols = 'ラドクリフマラソンわたしワタシんょンョたばこタバコとうきょうトウキョウ '.split('');
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
const getRandomSymbol = function () {
|
||||
return symbols[Math.floor(Math.random() * symbols.length)];
|
||||
}
|
||||
|
||||
const ctx = $canvas.getContext('2d');
|
||||
ctx.globalCompositeOperation = 'lighter'; // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
|
||||
|
||||
this.redrawInterval = 70; // fade oud speed
|
||||
this.glyphSize = 0;
|
||||
this.rowsCapacity = 0;
|
||||
this.columnsCapacity = 0;
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
this.init = () => {
|
||||
$canvas.width = $canvas.clientWidth;
|
||||
$canvas.height = $canvas.clientHeight;
|
||||
|
||||
this.glyphSize = parseInt(getComputedStyle($canvas).getPropertyValue('--matrix-glyph-size'), 10);
|
||||
this.rowsCapacity = Math.ceil($canvas.clientHeight / this.glyphSize);
|
||||
this.columnsCapacity = Math.ceil($canvas.clientWidth / this.glyphSize);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} symbol
|
||||
* @param {number} row
|
||||
* @param {number} column
|
||||
* @param {string} color
|
||||
*/
|
||||
const drawSymbol = (symbol, row, column, color) => {
|
||||
if (row > this.rowsCapacity || column > this.columnsCapacity) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.fillStyle = color;
|
||||
ctx.font = getComputedStyle($canvas).getPropertyValue('--matrix-glyph-font-size') + ' monospace';
|
||||
|
||||
if (symbol.length > 1) {
|
||||
symbol = symbol.charAt(0); // only one char is allowed
|
||||
}
|
||||
|
||||
let xOffset = 0, charCode = symbol.charCodeAt(0);
|
||||
|
||||
if (charCode >= 33 && charCode <= 126) { // is ascii
|
||||
xOffset = this.glyphSize / 5;
|
||||
}
|
||||
|
||||
ctx.fillText(symbol, (column * this.glyphSize) + xOffset, row * this.glyphSize);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} column
|
||||
* @param {number} speed Lowest = fastest, largest = slowest
|
||||
* @param {string?} text
|
||||
* @param {number?} offset
|
||||
*/
|
||||
const drawLine = (column, speed, text, offset) => {
|
||||
let cursor = 0;
|
||||
|
||||
const tailColor = getComputedStyle($canvas).getPropertyValue('--matrix-glyph-tail-color'),
|
||||
frontColor = getComputedStyle($canvas).getPropertyValue('--matrix-glyph-front-color');
|
||||
|
||||
const handler = window.setInterval(() => {
|
||||
if (column > this.columnsCapacity) {
|
||||
return window.clearInterval(handler);
|
||||
}
|
||||
|
||||
if (cursor <= this.rowsCapacity) {
|
||||
let symbol = getRandomSymbol();
|
||||
|
||||
if (typeof text === 'string' && typeof offset === 'number') {
|
||||
if (cursor >= offset && text.length >= cursor - offset) {
|
||||
symbol = text.charAt(cursor - offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof symbol === 'string' && symbol !== ' ') {
|
||||
const prev = cursor;
|
||||
|
||||
window.setTimeout(() => { // redraw with a green color
|
||||
drawSymbol(symbol, prev, column, tailColor);
|
||||
}, speed / 1.3);
|
||||
|
||||
drawSymbol(symbol, cursor, column, frontColor); // white color first
|
||||
}
|
||||
|
||||
cursor++;
|
||||
} else {
|
||||
window.clearInterval(handler);
|
||||
}
|
||||
}, speed);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
this.redraw = () => {
|
||||
ctx.fillStyle = getComputedStyle($canvas).getPropertyValue('--matrix-overlay-color');
|
||||
ctx.fillRect(0, 0, $canvas.clientWidth, $canvas.clientHeight);
|
||||
};
|
||||
|
||||
let redrawIntervalHandler = undefined, dropsIntervalHandler = undefined;
|
||||
|
||||
/**
|
||||
* @param {HTMLUListElement?} $linesList
|
||||
*/
|
||||
this.run = ($linesList) => {
|
||||
if (redrawIntervalHandler === undefined) {
|
||||
redrawIntervalHandler = window.setInterval(this.redraw, this.redrawInterval);
|
||||
}
|
||||
|
||||
if (dropsIntervalHandler === undefined) {
|
||||
const fn = () => {
|
||||
const randomColumn = Math.floor(Math.random() * (this.columnsCapacity + 1)),
|
||||
minSpeed = 200, maxSpeed = 50,
|
||||
randomSpeed = Math.floor(Math.random() * (maxSpeed - minSpeed + 1)) + minSpeed;
|
||||
|
||||
const list = [];
|
||||
let line = undefined, offset = undefined;
|
||||
|
||||
if ($linesList !== undefined) {
|
||||
Array.prototype.forEach.call($linesList.querySelectorAll('li'), $li => {
|
||||
const text = $li.innerText.trim();
|
||||
|
||||
if (text.length > 0) {
|
||||
list.push(text);
|
||||
}
|
||||
});
|
||||
|
||||
if (list.length > 0 && Math.random() > 0.4) {
|
||||
line = list[Math.floor(Math.random() * list.length)];
|
||||
offset = Math.floor(Math.random() * line.length);
|
||||
|
||||
if (offset <= 5) {
|
||||
offset *= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawLine(randomColumn, randomSpeed, line, offset);
|
||||
|
||||
if (dropsIntervalHandler !== undefined) {
|
||||
window.clearInterval(dropsIntervalHandler);
|
||||
dropsIntervalHandler = undefined;
|
||||
}
|
||||
|
||||
dropsIntervalHandler = window.setInterval(fn, ((minSpeed + maxSpeed) / 2 * this.rowsCapacity) / this.columnsCapacity / 0.5);
|
||||
};
|
||||
|
||||
fn();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
this.stop = () => {
|
||||
if (redrawIntervalHandler !== undefined) {
|
||||
window.clearInterval(redrawIntervalHandler);
|
||||
redrawIntervalHandler = undefined;
|
||||
}
|
||||
|
||||
if (dropsIntervalHandler !== undefined) {
|
||||
window.clearInterval(dropsIntervalHandler);
|
||||
dropsIntervalHandler = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof ResizeObserver === 'function') {
|
||||
(new ResizeObserver(this.init)).observe($canvas);
|
||||
} else {
|
||||
this.init();
|
||||
}
|
||||
};
|
||||
|
||||
(new Matrix(document.getElementById('matrix'))).run(document.getElementById('matrix-words'));
|
||||
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
Description: {{ description }}
|
||||
-->
|
||||
</html>
|
@ -130,7 +130,7 @@
|
||||
<div class="container-center">
|
||||
<div>
|
||||
<h1>{{ code }}</h1>
|
||||
<h2>{{ description }}</h2>
|
||||
<h2 data-l10n>{{ description }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -174,6 +174,15 @@
|
||||
window.addEventListener('beforeunload', function (/** @param BeforeUnloadEvent event */ event) {
|
||||
window.clearInterval(flickerInterval);
|
||||
});
|
||||
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
|
@ -72,60 +72,63 @@
|
||||
<body>
|
||||
<div class="flex-center full-height">
|
||||
<div>
|
||||
<span id="error_text">{{ code }}: {{ message }}</span>
|
||||
<div id="error_text">
|
||||
<span class="source">{{ code }}: <span data-l10n>{{ message }}</span></span>
|
||||
<span class="target"></span>
|
||||
</div>
|
||||
{{ if show_details }}
|
||||
<div class="hidden" id="details">
|
||||
<table>
|
||||
{{- if host }}
|
||||
<tr>
|
||||
<td class="name">Host:</td>
|
||||
<td class="name"><span data-l10n>Host</span>:</td>
|
||||
<td class="value">{{ host }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
{{- if original_uri }}
|
||||
<tr>
|
||||
<td class="name">Original URI:</td>
|
||||
<td class="name"><span data-l10n>Original URI</span>:</td>
|
||||
<td class="value">{{ original_uri }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
{{- if forwarded_for }}
|
||||
<tr>
|
||||
<td class="name">Forwarded for:</td>
|
||||
<td class="name"><span data-l10n>Forwarded for</span>:</td>
|
||||
<td class="value">{{ forwarded_for }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
{{- if namespace }}
|
||||
<tr>
|
||||
<td class="name">Namespace:</td>
|
||||
<td class="name"><span data-l10n>Namespace</span>:</td>
|
||||
<td class="value">{{ namespace }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
{{- if ingress_name }}
|
||||
<tr>
|
||||
<td class="name">Ingress name:</td>
|
||||
<td class="name"><span data-l10n>Ingress name</span>:</td>
|
||||
<td class="value">{{ ingress_name }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
{{- if service_name }}
|
||||
<tr>
|
||||
<td class="name">Service name:</td>
|
||||
<td class="name"><span data-l10n>Service name</span>:</td>
|
||||
<td class="value">{{ service_name }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
{{- if service_port }}
|
||||
<tr>
|
||||
<td class="name">Service port:</td>
|
||||
<td class="name"><span data-l10n>Service port</span>:</td>
|
||||
<td class="value">{{ service_port }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
{{- if request_id }}
|
||||
<tr>
|
||||
<td class="name">Request ID:</td>
|
||||
<td class="name"><span data-l10n>Request ID</span>:</td>
|
||||
<td class="value">{{ request_id }}</td>
|
||||
</tr>
|
||||
{{ end -}}
|
||||
<tr>
|
||||
<td class="name">Timestamp:</td>
|
||||
<td class="name"><span data-l10n>Timestamp</span>:</td>
|
||||
<td class="value">{{ now.Unix }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -137,24 +140,74 @@
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const $errorText = document.getElementById('error_text'),
|
||||
text = $errorText.innerText,
|
||||
characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=+<>,./?[{()}]!@#$%^&*~`\|'.split('');
|
||||
let progress = 0;
|
||||
/**
|
||||
* @param {HTMLElement} $el
|
||||
*/
|
||||
const Shuffle = function ($el) {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=+<>,./?[{()}]!@#$%^&*~`\|'.split(''),
|
||||
$source = $el.querySelector('.source'), $target = $el.querySelector('.target');
|
||||
|
||||
const scrambleInterval = window.setInterval(function () {
|
||||
let newText = text;
|
||||
let cursor = 0, scrambleInterval = undefined, cursorDelayInterval = undefined, cursorInterval = undefined;
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (i >= progress) {
|
||||
newText = newText.substr(0, i) +
|
||||
characters[Math.round(Math.random() * (characters.length - 1))] +
|
||||
newText.substr(i + 1);
|
||||
/**
|
||||
* @param {Number} len
|
||||
* @return {string}
|
||||
*/
|
||||
const getRandomizedString = function (len) {
|
||||
let s = '';
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
s += chars[Math.floor(Math.random() * chars.length)];
|
||||
}
|
||||
}
|
||||
|
||||
$errorText.innerText = newText;
|
||||
}, 450 / 60);
|
||||
return s;
|
||||
};
|
||||
|
||||
this.start = function () {
|
||||
$source.style.display = 'none';
|
||||
$target.style.display = 'block';
|
||||
|
||||
scrambleInterval = window.setInterval(() => {
|
||||
if (cursor <= $source.innerText.length) {
|
||||
$target.innerText = $source.innerText.substring(0, cursor) + getRandomizedString($source.innerText.length - cursor);
|
||||
}
|
||||
}, 450 / 30);
|
||||
|
||||
cursorDelayInterval = window.setTimeout(() => {
|
||||
cursorInterval = window.setInterval(() => {
|
||||
if (cursor > $source.innerText.length - 1) {
|
||||
this.stop();
|
||||
}
|
||||
|
||||
cursor++;
|
||||
}, 70);
|
||||
}, 350);
|
||||
};
|
||||
|
||||
this.stop = function () {
|
||||
$source.style.display = 'block';
|
||||
$target.style.display = 'none';
|
||||
$target.innerText = '';
|
||||
cursor = 0;
|
||||
|
||||
if (scrambleInterval !== undefined) {
|
||||
window.clearInterval(scrambleInterval);
|
||||
scrambleInterval = undefined;
|
||||
}
|
||||
|
||||
if (cursorInterval !== undefined) {
|
||||
window.clearInterval(cursorInterval);
|
||||
cursorInterval = undefined;
|
||||
}
|
||||
|
||||
if (cursorDelayInterval !== undefined) {
|
||||
window.clearInterval(cursorDelayInterval);
|
||||
cursorDelayInterval = undefined;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
(new Shuffle(document.getElementById('error_text'))).start();
|
||||
|
||||
// {{ if show_details }}
|
||||
window.setTimeout(function () {
|
||||
@ -162,16 +215,14 @@
|
||||
}, 550);
|
||||
// {{ end }}
|
||||
|
||||
window.setTimeout(function () {
|
||||
let revealInterval = window.setInterval(function () {
|
||||
if (progress < text.length) {
|
||||
progress++;
|
||||
} else {
|
||||
window.clearInterval(revealInterval);
|
||||
window.clearInterval(scrambleInterval);
|
||||
}
|
||||
}, 70);
|
||||
}, 350);
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
|
Reference in New Issue
Block a user