From 83f00f9a7983a597640dbbd7ce12b3ac8058d4b4 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Thu, 24 Sep 2020 21:18:02 +0200 Subject: [PATCH 01/14] Dump --- .gitignore | 3 +- composer.json | 15 - composer.lock | 1023 ---------- index.js | 21 + nodemon.json | 6 + package-lock.json | 1752 +++++++++++++++++ package.json | 32 + {static => public}/dank-mono.css | 0 favicon.png => public/favicon.png | Bin {static => public}/fonts/Lora-Bold.otf | Bin {static => public}/fonts/Lora-BoldItalic.otf | Bin {static => public}/fonts/Lora-Italic.otf | Bin {static => public}/fonts/Lora-Medium.otf | Bin .../fonts/Lora-MediumItalic.otf | Bin {static => public}/fonts/Lora-Regular.otf | Bin {static => public}/img/github.svg | 0 {static => public}/img/gitlab.svg | 0 {static => public}/img/gnuprivacyguard.svg | 0 {static => public}/img/mail.svg | 0 {static => public}/img/mastodon.svg | 0 {static => public}/img/profile.orig.png | Bin {static => public}/img/profile.png | Bin {static => public}/img/profile.webp | Bin {static => public}/img/qr_fp.png | Bin {static => public}/img/rss.svg | 0 {static => public}/img/xmpp.svg | 0 {static => public}/norm.css | 0 {static => public}/style.css | 0 routes/main.js | 40 + routes/static.js | 8 + server/middlewares.js | 30 + server/util.js | 17 + views/index.pug | 12 +- views/{layout.pug => templates/main.pug} | 8 +- 34 files changed, 1916 insertions(+), 1051 deletions(-) delete mode 100644 composer.json delete mode 100644 composer.lock create mode 100644 index.js create mode 100644 nodemon.json create mode 100644 package-lock.json create mode 100644 package.json rename {static => public}/dank-mono.css (100%) rename favicon.png => public/favicon.png (100%) rename {static => public}/fonts/Lora-Bold.otf (100%) rename {static => public}/fonts/Lora-BoldItalic.otf (100%) rename {static => public}/fonts/Lora-Italic.otf (100%) rename {static => public}/fonts/Lora-Medium.otf (100%) rename {static => public}/fonts/Lora-MediumItalic.otf (100%) rename {static => public}/fonts/Lora-Regular.otf (100%) rename {static => public}/img/github.svg (100%) rename {static => public}/img/gitlab.svg (100%) rename {static => public}/img/gnuprivacyguard.svg (100%) rename {static => public}/img/mail.svg (100%) rename {static => public}/img/mastodon.svg (100%) rename {static => public}/img/profile.orig.png (100%) rename {static => public}/img/profile.png (100%) rename {static => public}/img/profile.webp (100%) rename {static => public}/img/qr_fp.png (100%) rename {static => public}/img/rss.svg (100%) rename {static => public}/img/xmpp.svg (100%) rename {static => public}/norm.css (100%) rename {static => public}/style.css (100%) create mode 100644 routes/main.js create mode 100644 routes/static.js create mode 100644 server/middlewares.js create mode 100644 server/util.js rename views/{layout.pug => templates/main.pug} (91%) diff --git a/.gitignore b/.gitignore index 7033121..95b8b82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ .well-known -vendor -cache \ No newline at end of file +node_modules \ No newline at end of file diff --git a/composer.json b/composer.json deleted file mode 100644 index be1d1cf..0000000 --- a/composer.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "require": { - "pug-php/pug": "^3.4", - "altorouter/altorouter": "^2.0", - "pagerange/metaparsedown": "^1.0", - "bhaktaraz/php-rss-generator": "dev-master", - "symfony/yaml": "^5.1", - "tubalmartin/cssmin": "^4.1" - }, - "scripts": { - "minifyCSS": [ - "php scripts/minifyCSS.php" - ] - } -} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index e0d02c5..0000000 --- a/composer.lock +++ /dev/null @@ -1,1023 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "35784685ae33a06c8c827535fe266724", - "packages": [ - { - "name": "altorouter/altorouter", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/dannyvankooten/AltoRouter.git", - "reference": "127f6e96998708a31ef32252985bea82e3b03888" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dannyvankooten/AltoRouter/zipball/127f6e96998708a31ef32252985bea82e3b03888", - "reference": "127f6e96998708a31ef32252985bea82e3b03888", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "require-dev": { - "codeclimate/php-test-reporter": "dev-master", - "phpunit/phpunit": "5.7.*", - "squizlabs/php_codesniffer": "3.4.2" - }, - "type": "library", - "autoload": { - "classmap": [ - "AltoRouter.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Danny van Kooten", - "email": "dannyvankooten@gmail.com", - "homepage": "http://dannyvankooten.com/" - }, - { - "name": "Koen Punt", - "homepage": "https://github.com/koenpunt" - }, - { - "name": "niahoo", - "homepage": "https://github.com/niahoo" - } - ], - "description": "A lightning fast router for PHP", - "homepage": "https://github.com/dannyvankooten/AltoRouter", - "keywords": [ - "lightweight", - "router", - "routing" - ], - "time": "2019-11-23T11:01:41+00:00" - }, - { - "name": "bhaktaraz/php-rss-generator", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/bhaktaraz/php-rss-generator.git", - "reference": "1507b60b407b89467317797abc9604ecb5eac990" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bhaktaraz/php-rss-generator/zipball/1507b60b407b89467317797abc9604ecb5eac990", - "reference": "1507b60b407b89467317797abc9604ecb5eac990", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Bhaktaraz\\RSSGenerator\\": "Source/Bhaktaraz/RSSGenerator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bhaktaraz Bhatta", - "email": "bhattabhakta@gmail.com" - } - ], - "description": "Simple RSS generator library for PHP 5.5 or later.", - "homepage": "https://github.com/bhaktaraz/php-rss-generator", - "keywords": [ - "Facebook product feed generator", - "feed", - "generator", - "rss", - "writer" - ], - "time": "2020-04-16T11:24:27+00:00" - }, - { - "name": "erusev/parsedown", - "version": "1.7.4", - "source": { - "type": "git", - "url": "https://github.com/erusev/parsedown.git", - "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3", - "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35" - }, - "type": "library", - "autoload": { - "psr-0": { - "Parsedown": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Emanuil Rusev", - "email": "hello@erusev.com", - "homepage": "http://erusev.com" - } - ], - "description": "Parser for Markdown.", - "homepage": "http://parsedown.org", - "keywords": [ - "markdown", - "parser" - ], - "time": "2019-12-30T22:54:17+00:00" - }, - { - "name": "erusev/parsedown-extra", - "version": "0.7.1", - "source": { - "type": "git", - "url": "https://github.com/erusev/parsedown-extra.git", - "reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/0db5cce7354e4b76f155d092ab5eb3981c21258c", - "reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c", - "shasum": "" - }, - "require": { - "erusev/parsedown": "~1.4" - }, - "type": "library", - "autoload": { - "psr-0": { - "ParsedownExtra": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Emanuil Rusev", - "email": "hello@erusev.com", - "homepage": "http://erusev.com" - } - ], - "description": "An extension of Parsedown that adds support for Markdown Extra.", - "homepage": "https://github.com/erusev/parsedown-extra", - "keywords": [ - "markdown", - "markdown extra", - "parsedown", - "parser" - ], - "time": "2015-11-01T10:19:22+00:00" - }, - { - "name": "js-phpize/js-phpize", - "version": "2.8.1", - "source": { - "type": "git", - "url": "https://github.com/pug-php/js-phpize.git", - "reference": "f7f76ae7974d588738527b204910b08d520b63d1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pug-php/js-phpize/zipball/f7f76ae7974d588738527b204910b08d520b63d1", - "reference": "f7f76ae7974d588738527b204910b08d520b63d1", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=7.0" - }, - "require-dev": { - "codeclimate/php-test-reporter": "dev-master", - "phpunit/phpunit": "^6.0 || ^7.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsPhpize": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kyle Katarn", - "email": "kylekatarnls@gmail.com" - } - ], - "description": "Convert js-like syntax to standalone PHP code.", - "time": "2020-04-06T14:13:38+00:00" - }, - { - "name": "js-phpize/js-phpize-phug", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/pug-php/js-phpize-phug.git", - "reference": "086536acf9d72ed8180210c3dcf1c0d248ad4f69" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pug-php/js-phpize-phug/zipball/086536acf9d72ed8180210c3dcf1c0d248ad4f69", - "reference": "086536acf9d72ed8180210c3dcf1c0d248ad4f69", - "shasum": "" - }, - "require": { - "js-phpize/js-phpize": "^2.0.0", - "php": ">=7.0", - "phug/compiler": "^0.5.0 || ^1.0@dev", - "phug/formatter": "^0.5.43 || ^1.0@dev" - }, - "require-dev": { - "codeclimate/php-test-reporter": "dev-master", - "phpunit/phpunit": ">=4.8.35 <6.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsPhpize": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kyle Katarn", - "email": "kylekatarnls@gmail.com" - } - ], - "description": "Convert js-like syntax to standalone PHP code in Phug template.", - "time": "2019-09-08T19:12:39+00:00" - }, - { - "name": "js-transformer/js-transformer", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/kylekatarnls/js-transformer-php-wrap.git", - "reference": "81730d3ae67824d664615ebb7f721cfa7d77179f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/kylekatarnls/js-transformer-php-wrap/zipball/81730d3ae67824d664615ebb7f721cfa7d77179f", - "reference": "81730d3ae67824d664615ebb7f721cfa7d77179f", - "shasum": "" - }, - "require": { - "nodejs-php-fallback/nodejs-php-fallback": "^1.2" - }, - "require-dev": { - "codeclimate/php-test-reporter": ">=0.3", - "phpunit/phpunit": ">=4.8 <6.0" - }, - "type": "library", - "extra": { - "npm": { - "jstransformer": "^1.0.0" - } - }, - "autoload": { - "psr-4": { - "": "./src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "homepage": "https://github.com/kylekatarnls/js-transformer-php-wrap", - "keywords": [ - "js-transformer" - ], - "time": "2017-10-27T21:27:00+00:00" - }, - { - "name": "nodejs-php-fallback/nodejs-php-fallback", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/kylekatarnls/nodejs-php-fallback.git", - "reference": "24963d8833905356cfdcb197fb575f3eade8750e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/kylekatarnls/nodejs-php-fallback/zipball/24963d8833905356cfdcb197fb575f3eade8750e", - "reference": "24963d8833905356cfdcb197fb575f3eade8750e", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0", - "php": ">=5.3.0" - }, - "require-dev": { - "codeclimate/php-test-reporter": "dev-master", - "composer/composer": "^1.2", - "phpunit/phpunit": ">=4.8.35 <6.0" - }, - "type": "composer-plugin", - "extra": { - "class": "NodejsPhpFallback\\ComposerPlugin" - }, - "autoload": { - "psr-0": { - "NodejsPhpFallback\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kyle", - "email": "kylekatarnls@gmail.com" - } - ], - "description": "Allow you to call node.js module or scripts throught PHP and call a fallback function if node.js is not available", - "time": "2020-01-09T23:51:08+00:00" - }, - { - "name": "pagerange/metaparsedown", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/pagerange/metaparsedown.git", - "reference": "9a97dcee80569d11169fcc548708e329f56163fd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pagerange/metaparsedown/zipball/9a97dcee80569d11169fcc548708e329f56163fd", - "reference": "9a97dcee80569d11169fcc548708e329f56163fd", - "shasum": "" - }, - "require": { - "erusev/parsedown": "^1.7.2", - "erusev/parsedown-extra": "^0.7.1", - "symfony/yaml": "^3.3 || ^4.0 || ^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Pagerange\\Markdown\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Steve George", - "email": "steve@pagerange.com" - } - ], - "description": "Adds ability to have meta data in markdown files parsed by eursev/parsedown or eruseve/parsedown-extra", - "keywords": [ - "markdown", - "markdown-extra", - "meta", - "pagerange", - "parsedown", - "parsedown-extra", - "yaml" - ], - "time": "2019-12-07T19:10:44+00:00" - }, - { - "name": "phug/js-transformer-filter", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/phug-php/js-transformer-filter.git", - "reference": "dbadf07950ee552471905001266cdae7793868a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phug-php/js-transformer-filter/zipball/dbadf07950ee552471905001266cdae7793868a8", - "reference": "dbadf07950ee552471905001266cdae7793868a8", - "shasum": "" - }, - "require": { - "js-transformer/js-transformer": "^1.0", - "phug/phug": "^0.1.8 || ^0.2.0 || ^0.3.0 || ^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4 || ^5", - "phug/dev-tool": "^0.1.11" - }, - "type": "library", - "extra": { - "npm-confirm": { - "jstransformer": "It allows you to use any jstransformer npm package as filter by adding it in your extra.npm section of composer.json." - } - }, - "autoload": { - "psr-0": { - "Phug\\": "./src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Allow to use any js-transformer as filter in Phug", - "homepage": "https://phug-lang.com", - "keywords": [ - "js-transformer" - ], - "time": "2019-10-05T16:02:15+00:00" - }, - { - "name": "phug/phug", - "version": "1.7.1", - "source": { - "type": "git", - "url": "https://github.com/phug-php/phug.git", - "reference": "e7ad585433b663511cf86aebf6112fa50e7c3b51" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phug-php/phug/zipball/e7ad585433b663511cf86aebf6112fa50e7c3b51", - "reference": "e7ad585433b663511cf86aebf6112fa50e7c3b51", - "shasum": "" - }, - "require": { - "php": ">=5.5.0", - "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0" - }, - "replace": { - "phug/ast": "self.version", - "phug/compiler": "self.version", - "phug/dependency-injection": "self.version", - "phug/event": "self.version", - "phug/facade": "self.version", - "phug/formatter": "self.version", - "phug/invoker": "self.version", - "phug/lexer": "self.version", - "phug/parser": "self.version", - "phug/reader": "self.version", - "phug/renderer": "self.version", - "phug/util": "self.version" - }, - "require-dev": { - "cebe/markdown": "^1.1", - "js-phpize/js-phpize-phug": "^1.2 || ^2.2", - "kylekatarnls/multi-tester": "^1.4", - "nodejs-php-fallback/coffeescript": "^1.0", - "nodejs-php-fallback/less": "^1.0", - "nodejs-php-fallback/stylus": "^1.0", - "nodejs-php-fallback/uglify": "^1.0", - "phpunit/php-code-coverage": "^2.2 || ^4.0 || ^5.2 || ^6.0 || ^7.0", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.0", - "pug-php/pug-filter-coffee-script": "^1.2", - "squizlabs/php_codesniffer": "~3.4.2" - }, - "bin": [ - "phug" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev", - "dev-facade": "0.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "": "./src/Phug/Phug/" - }, - "psr-4": { - "Phug\\": [ - "./src/Phug/Ast/", - "./src/Phug/Compiler/", - "./src/Phug/DependencyInjection/", - "./src/Phug/Event/", - "./src/Phug/Formatter/", - "./src/Phug/Invoker/", - "./src/Phug/Lexer/", - "./src/Phug/Parser/", - "./src/Phug/Reader/", - "./src/Phug/Renderer/", - "./src/Phug/Util/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", - "homepage": "http://github.com/kylekatarnls" - } - ], - "description": "Pug (ex-Jade) facade engine for PHP, HTML template engine structured by indentation", - "homepage": "http://phug-lang.com", - "keywords": [ - "compiler", - "dialect", - "html", - "jade", - "php", - "phtml", - "phug", - "presentation", - "pug", - "render", - "template", - "views" - ], - "time": "2020-04-10T10:42:54+00:00" - }, - { - "name": "pug-php/pug", - "version": "3.4.0", - "source": { - "type": "git", - "url": "https://github.com/pug-php/pug.git", - "reference": "81e10e2d890de01182aaeacc00ff4b25da807bab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pug-php/pug/zipball/81e10e2d890de01182aaeacc00ff4b25da807bab", - "reference": "81e10e2d890de01182aaeacc00ff4b25da807bab", - "shasum": "" - }, - "require": { - "js-phpize/js-phpize-phug": "^1.1 || ^2.0", - "nodejs-php-fallback/nodejs-php-fallback": "^1.3.1", - "php": ">=5.5.0", - "phug/js-transformer-filter": "^1.0", - "phug/phug": "^1.6" - }, - "replace": { - "kylekatarnls/jade-php": "self.version" - }, - "require-dev": { - "phpunit/phpunit": ">=4.8.35 <9.0" - }, - "bin": [ - "pug" - ], - "type": "library", - "extra": { - "npm": { - "pug-cli": "^1.0.0-alpha6" - }, - "npm-confirm": { - "pug-cli": "It allows you to use the native JS pug engine instead of the default PHP one with the `pugjs` option set to `true`" - } - }, - "autoload": { - "psr-4": { - "": "./src" - }, - "psr-0": { - "Pug\\": "src/", - "Jade\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "kylekatarnls", - "email": "pug@selfbuild.fr", - "homepage": "http://github.com/kylekatarnls", - "role": "Developer" - }, - { - "name": "pug-php/pug contributors", - "homepage": "https://github.com/pug-php/pug/graphs/contributors", - "role": "Contributor" - }, - { - "name": "phug-php/phug renderer contributors", - "homepage": "https://github.com/phug-php/renderer/graphs/contributors", - "role": "Contributor" - }, - { - "name": "phug-php/phug compiler contributors", - "homepage": "https://github.com/phug-php/compiler/graphs/contributors", - "role": "Contributor" - }, - { - "name": "pug-php/js-phpize contributors", - "homepage": "https://github.com/pug-php/js-phpize/graphs/contributors", - "role": "Contributor" - } - ], - "description": "HAML-like template engine for PHP", - "homepage": "https://github.com/pug-php/pug", - "keywords": [ - "jade", - "minification", - "pug", - "template" - ], - "time": "2020-02-03T23:15:28+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.1.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", - "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "time": "2020-05-27T08:34:37+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/4719fa9c18b0464d399f1a63bf624b42b6fa8d14", - "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "time": "2020-02-27T09:26:54+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac", - "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2020-03-09T19:04:49+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v5.0.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "f74a126acd701392eef2492a17228d42552c86b5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f74a126acd701392eef2492a17228d42552c86b5", - "reference": "f74a126acd701392eef2492a17228d42552c86b5", - "shasum": "" - }, - "require": { - "php": "^7.2.5", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "phpunit/phpunit": "<5.4.3", - "symfony/console": "<4.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "twig/twig": "^2.4|^3.0" - }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony mechanism for exploring and dumping PHP variables", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "time": "2020-03-27T16:56:45+00:00" - }, - { - "name": "symfony/yaml", - "version": "v5.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "ea342353a3ef4f453809acc4ebc55382231d4d23" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/ea342353a3ef4f453809acc4ebc55382231d4d23", - "reference": "ea342353a3ef4f453809acc4ebc55382231d4d23", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/console": "<4.4" - }, - "require-dev": { - "symfony/console": "^4.4|^5.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2020-05-20T17:43:50+00:00" - }, - { - "name": "tubalmartin/cssmin", - "version": "v4.1.1", - "source": { - "type": "git", - "url": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port.git", - "reference": "3cbf557f4079d83a06f9c3ff9b957c022d7805cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tubalmartin/YUI-CSS-compressor-PHP-port/zipball/3cbf557f4079d83a06f9c3ff9b957c022d7805cf", - "reference": "3cbf557f4079d83a06f9c3ff9b957c022d7805cf", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.2" - }, - "require-dev": { - "cogpowered/finediff": "0.3.*", - "phpunit/phpunit": "4.8.*" - }, - "bin": [ - "cssmin" - ], - "type": "library", - "autoload": { - "psr-4": { - "tubalmartin\\CssMin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Túbal Martín", - "homepage": "http://tubalmartin.me/" - } - ], - "description": "A PHP port of the YUI CSS compressor", - "homepage": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port", - "keywords": [ - "compress", - "compressor", - "css", - "cssmin", - "minify", - "yui" - ], - "time": "2018-01-15T15:26:51+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "bhaktaraz/php-rss-generator": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] -} diff --git a/index.js b/index.js new file mode 100644 index 0000000..f08f756 --- /dev/null +++ b/index.js @@ -0,0 +1,21 @@ +const express = require('express') +const fs = require('fs') +const app = express() +require('dotenv').config() + +app.set('env', process.env.NODE_ENV || "production") +app.set('view engine', 'pug') +app.set('port', process.env.PORT || 3000) + +app.use('/', require('./routes/main')) +app.use('/', require('./routes/static')) +// app.use('/server', require('./routes/server')) +// app.use('/encrypt', require('./routes/encrypt')) +// app.use('/verify', require('./routes/verify')) +// app.use('/proofs', require('./routes/proofs')) +// app.use('/util', require('./routes/util')) +// app.use('/', require('./routes/profile')) + +app.listen(app.get('port'), () => { + console.log(`Node server listening at http://localhost:${app.get('port')}`) +}) diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..1690325 --- /dev/null +++ b/nodemon.json @@ -0,0 +1,6 @@ +{ + "ignore": [], + "env": { + "NODE_ENV": "development" + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a014b8a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1752 @@ +{ + "name": "yarmo.eu", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/parser": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==" + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==" + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "requires": { + "@babel/types": "^7.9.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "^1.0.3" + } + }, + "chokidar": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "requires": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "express-validator": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.6.1.tgz", + "integrity": "sha512-+MrZKJ3eGYXkNF9p9Zf7MS7NkPJFg9MDYATU5c80Cf4F62JdLBIjWxy6481tRC0y1NnC9cgOw8FuN364bWaGhA==", + "requires": { + "lodash": "^4.17.19", + "validator": "^13.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "dev": true, + "requires": { + "ini": "^1.3.5" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "requires": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "jstransformer-markdown-it": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/jstransformer-markdown-it/-/jstransformer-markdown-it-2.1.0.tgz", + "integrity": "sha1-aewwzkUYvtWZezjwJ2SOjChekvc=", + "requires": { + "markdown-it": "^8.0.0" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "requires": { + "uc.micro": "^1.0.1" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "luxon": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.25.0.tgz", + "integrity": "sha512-hEgLurSH8kQRjY6i4YLey+mcKVAWXbDNlZRmM6AgWDJ1cY3atl8Ztf5wEY7VBReFbmGnwQPz7KYJblL8B2k0jQ==" + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==" + }, + "markdown-it-table-of-contents": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", + "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==" + }, + "markdown-it-title": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-title/-/markdown-it-title-3.0.0.tgz", + "integrity": "sha512-iHZptfptAXGJlcboqWxUSWNkJLUyxZ452CobBzkQ7MtwfVhTI77W1LTAy+miQTqo3U+wkDUOFhhXj2XUD0dVWQ==" + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nodemon": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", + "integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^4.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.0.tgz", + "integrity": "sha512-inmsJyFBSHZaiGLaguoFgJGViX0If6AcfcElimvwj9perqjDpUpw79UIEDZbWFmoGVidh08aoE+e8tVkjVJPCw==", + "requires": { + "pug-code-gen": "^3.0.0", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.0", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.0", + "pug-strip-comments": "^2.0.0" + } + }, + "pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "requires": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "pug-code-gen": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.1.tgz", + "integrity": "sha512-xJIGvmXTQlkJllq6hqxxjRWcay2F9CU69TuAuiVZgHK0afOhG5txrQOcZyaPHBvSWCU/QQOqEp5XCH94rRZpBQ==", + "requires": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + }, + "pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "requires": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "pug-lexer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.0.tgz", + "integrity": "sha512-52xMk8nNpuyQ/M2wjZBN5gXQLIylaGkAoTk5Y1pBhVqaopaoj8Z0iVzpbFZAqitL4RHNVDZRnJDsqEYe99Ti0A==", + "requires": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "requires": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "requires": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "requires": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "pug-runtime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.0.tgz", + "integrity": "sha512-GoEPcmQNnaTsePEdVA05bDpY+Op5VLHKayg08AQiqJBWU/yIaywEYv7TetC5dEQS3fzBBoyb2InDcZEg3mPTIA==" + }, + "pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "requires": { + "pug-error": "^2.0.0" + } + }, + "pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pupa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", + "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "registry-auth-token": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", + "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "term-size": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", + "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz", + "integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "validator": { + "version": "13.1.17", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.1.17.tgz", + "integrity": "sha512-zL5QBoemJ3jYFb2/j38y7ljhwYGXVLUp8H6W1nVxadnAOvUOytec+L7BHh1oBQ82/TzWXHd+GSaxUWp4lROkLg==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "requires": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yaml-front-matter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/yaml-front-matter/-/yaml-front-matter-4.1.0.tgz", + "integrity": "sha512-E2NKXUe8Amsf3kyLDK48c2gvnfom0Yj3m7455iVVg+G5UbX66V5iqFSpEUkQ+A3iJCKIz+mvAbkN7BQ+N0wiLA==", + "requires": { + "commander": "^2.14.1", + "js-yaml": "^3.10.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4dcfd18 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "yarmo.eu", + "version": "0.1.0", + "description": "Yarmo.eu website", + "main": "index.js", + "scripts": { + "start": "node index", + "dev": "nodemon --config nodemon.json index" + }, + "repository": { + "type": "git", + "url": "https://git.yarmo.eu/yarmo/yarmo.eu" + }, + "keywords": [], + "author": "Yarmo Mackenbach (https://yarmo.eu)", + "license": "AGPL-3.0-or-later", + "dependencies": { + "dotenv": "^8.2.0", + "express": "^4.17.1", + "express-validator": "^6.6.1", + "jstransformer-markdown-it": "^2.1.0", + "luxon": "^1.25.0", + "markdown-it-anchor": "^5.3.0", + "markdown-it-table-of-contents": "^0.4.4", + "markdown-it-title": "^3.0.0", + "pug": "^3.0.0", + "yaml-front-matter": "^4.1.0" + }, + "devDependencies": { + "nodemon": "^2.0.4" + } +} diff --git a/static/dank-mono.css b/public/dank-mono.css similarity index 100% rename from static/dank-mono.css rename to public/dank-mono.css diff --git a/favicon.png b/public/favicon.png similarity index 100% rename from favicon.png rename to public/favicon.png diff --git a/static/fonts/Lora-Bold.otf b/public/fonts/Lora-Bold.otf similarity index 100% rename from static/fonts/Lora-Bold.otf rename to public/fonts/Lora-Bold.otf diff --git a/static/fonts/Lora-BoldItalic.otf b/public/fonts/Lora-BoldItalic.otf similarity index 100% rename from static/fonts/Lora-BoldItalic.otf rename to public/fonts/Lora-BoldItalic.otf diff --git a/static/fonts/Lora-Italic.otf b/public/fonts/Lora-Italic.otf similarity index 100% rename from static/fonts/Lora-Italic.otf rename to public/fonts/Lora-Italic.otf diff --git a/static/fonts/Lora-Medium.otf b/public/fonts/Lora-Medium.otf similarity index 100% rename from static/fonts/Lora-Medium.otf rename to public/fonts/Lora-Medium.otf diff --git a/static/fonts/Lora-MediumItalic.otf b/public/fonts/Lora-MediumItalic.otf similarity index 100% rename from static/fonts/Lora-MediumItalic.otf rename to public/fonts/Lora-MediumItalic.otf diff --git a/static/fonts/Lora-Regular.otf b/public/fonts/Lora-Regular.otf similarity index 100% rename from static/fonts/Lora-Regular.otf rename to public/fonts/Lora-Regular.otf diff --git a/static/img/github.svg b/public/img/github.svg similarity index 100% rename from static/img/github.svg rename to public/img/github.svg diff --git a/static/img/gitlab.svg b/public/img/gitlab.svg similarity index 100% rename from static/img/gitlab.svg rename to public/img/gitlab.svg diff --git a/static/img/gnuprivacyguard.svg b/public/img/gnuprivacyguard.svg similarity index 100% rename from static/img/gnuprivacyguard.svg rename to public/img/gnuprivacyguard.svg diff --git a/static/img/mail.svg b/public/img/mail.svg similarity index 100% rename from static/img/mail.svg rename to public/img/mail.svg diff --git a/static/img/mastodon.svg b/public/img/mastodon.svg similarity index 100% rename from static/img/mastodon.svg rename to public/img/mastodon.svg diff --git a/static/img/profile.orig.png b/public/img/profile.orig.png similarity index 100% rename from static/img/profile.orig.png rename to public/img/profile.orig.png diff --git a/static/img/profile.png b/public/img/profile.png similarity index 100% rename from static/img/profile.png rename to public/img/profile.png diff --git a/static/img/profile.webp b/public/img/profile.webp similarity index 100% rename from static/img/profile.webp rename to public/img/profile.webp diff --git a/static/img/qr_fp.png b/public/img/qr_fp.png similarity index 100% rename from static/img/qr_fp.png rename to public/img/qr_fp.png diff --git a/static/img/rss.svg b/public/img/rss.svg similarity index 100% rename from static/img/rss.svg rename to public/img/rss.svg diff --git a/static/img/xmpp.svg b/public/img/xmpp.svg similarity index 100% rename from static/img/xmpp.svg rename to public/img/xmpp.svg diff --git a/static/norm.css b/public/norm.css similarity index 100% rename from static/norm.css rename to public/norm.css diff --git a/static/style.css b/public/style.css similarity index 100% rename from static/style.css rename to public/style.css diff --git a/routes/main.js b/routes/main.js new file mode 100644 index 0000000..3ce2972 --- /dev/null +++ b/routes/main.js @@ -0,0 +1,40 @@ +const router = require('express').Router() +const fs = require('fs') +const mw = require('../server/middlewares') + +router.get('/', mw.getBlogPosts, (req, res) => { + res.render('index', { title: 'yarmo.eu' }) +}) + +router.get('/getting-started', (req, res) => { + let rawContent = fs.readFileSync(`./content/getting-started.md`, "utf8") + const content = md.render(rawContent) + res.render(`basic`, { title: `Getting started - Keyoxide`, content: content }) +}) + +router.get('/faq', (req, res) => { + const mdAlt = require('markdown-it')({typographer: true}) + mdAlt.use(require("markdown-it-anchor"), { "level": 2, "permalink": true, "permalinkClass": 'header-anchor', "permalinkSymbol": '¶', "permalinkBefore": false }) + mdAlt.use(require("markdown-it-table-of-contents"), { "includeLevel": [2], "listType": "ul" }) + + let rawContent = fs.readFileSync(`./content/faq.md`, "utf8") + rawContent = rawContent.replace('${domain}', req.app.get('domain')) + const content = mdAlt.render(rawContent) + res.render(`basic`, { title: `Frequently Asked Questions - Keyoxide`, content: content }) +}) + +router.get('/guides', (req, res) => { + res.render('guides', { title: `Guides - Keyoxide` }) +}) + +router.get('/guides/:guideId', (req, res) => { + let env = {} + let rawContent = fs.readFileSync(`./content/guides/${req.params.guideId}.md`, "utf8", (err, data) => { + if (err) throw err + return data + }) + const content = md.render(rawContent, env) + res.render(`basic`, { title: `${env.title} - Keyoxide`, content: content }) +}) + +module.exports = router diff --git a/routes/static.js b/routes/static.js new file mode 100644 index 0000000..f373067 --- /dev/null +++ b/routes/static.js @@ -0,0 +1,8 @@ +const express = require('express') +const router = require('express').Router() +const path = require('path') + +router.use('/favicon.png', express.static(path.join(__dirname, '../', 'public', 'favicon.png'))) +router.use('/static', express.static(path.join(__dirname, '../', 'public'))) + +module.exports = router diff --git a/server/middlewares.js b/server/middlewares.js new file mode 100644 index 0000000..e807341 --- /dev/null +++ b/server/middlewares.js @@ -0,0 +1,30 @@ +const path = require('path') +const fs = require('fs') +const util = require('./util') +const md = require('markdown-it')({ typographer: true }) +const yamlFront = require('yaml-front-matter') +const { DateTime } = require('luxon') + +module.exports.getBlogPosts = async (req, res, next) => { + let data = [] + for await (const f of util.getFiles(path.join(__dirname, '../', 'content', 'blog'))) { + const rawContent = fs.readFileSync(f, 'utf8') + const fm = yamlFront.loadFront(rawContent) + data.push({ + type: 'blog', + title: fm['title'], + author: fm['author'], + urlrel: `/post/${fm['slug']}`, + url: `https://yarmo.eu/post/${fm['slug']}`, + slug: fm['slug'], + date: fm['date'], + // date_formatted: DateTime.fromFormat(fm['date'], 'yyyy-LL-dd hh:mm:ss').toFormat('yyyy-LL-dd'), + date_formatted: DateTime.fromFormat(fm['date'], 'yyyy-LL-dd hh:mm:ss').setLocale("en").toLocaleString(DateTime.DATE_MED), + published: fm['published'], + discussion: fm['discussion'], + content: md.render(fm.__content) + }) + } + res.locals.blogPosts = data.reverse() + next() +} diff --git a/server/util.js b/server/util.js new file mode 100644 index 0000000..fedf988 --- /dev/null +++ b/server/util.js @@ -0,0 +1,17 @@ +const { resolve } = require('path') +const { readdir } = require('fs').promises +const fs = require('fs') + +async function* getFiles(dir) { + const dirents = await readdir(dir, { withFileTypes: true }) + for (const dirent of dirents) { + const res = resolve(dir, dirent.name) + if (dirent.isDirectory()) { + yield* getFiles(res) + } else { + yield res + } + } +} + +module.exports.getFiles = getFiles diff --git a/views/index.pug b/views/index.pug index 8d5ee65..968b807 100644 --- a/views/index.pug +++ b/views/index.pug @@ -1,12 +1,12 @@ -extends layout +extends templates/main -mixin entry($item) +mixin entry(item) article.longform_list__item.h-entry p - a(href="{$item['urlrel']}").p-name.u-url !{$item['title']} + a(href="{item['urlrel']}").p-name.u-url !{item['title']} br | Posted on - time(datetime="{$item['date']}").dt-published !{$item['date_formatted']} + time(datetime="{item['date']}").dt-published !{item['date_formatted']} block content .h-card @@ -34,5 +34,5 @@ block content include id .longform_list.h-feed - each $item in $posts - +entry($item) + each item in blogPosts + +entry(item) diff --git a/views/layout.pug b/views/templates/main.pug similarity index 91% rename from views/layout.pug rename to views/templates/main.pug index cdd3bf5..a7e61be 100644 --- a/views/layout.pug +++ b/views/templates/main.pug @@ -4,12 +4,10 @@ html meta(name="viewport", content="width=device-width, initial-scale=1.0") meta(name="theme-color", content="#4ab4ab") meta(http-equiv="X-UA-Compatible", content="ie=edge") - title #{$title} + title #{title} link(rel="stylesheet", href="/static/dank-mono.css") - style - dyninclude "static/norm.css" - style - dyninclude "static/style.css" + link(rel="stylesheet", href="/static/norm.css") + link(rel="stylesheet", href="/static/style.css") link(rel="shortcut icon", href="/favicon.png") link(rel="alternate", href="/rss/all", title="RSS blog feed for yarmo.eu", type="application/rss+xml") link(rel="webmention", href="https://webm.yarmo.eu/receive") From 48e2b4ab6aa48f0c8e61a8f1466b9db2398801d1 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 00:51:24 +0200 Subject: [PATCH 02/14] Dump --- .../2020/06/2020-06-05--missing-entropy.md | 2 +- .../2020-06-05--website-load-performance.md | 24 ++-- .../2020/07/2020-07-03--keybase-website.md | 14 +- .../07/2020-07-31--flipper-zero-limited.md | 14 +- content/music/aotw.yaml | 12 -- .../2020/06/2020-06-08--nuc-fan-cleaning.md | 2 +- .../2020/06/2020-06-29--github-sinking.md | 2 +- index.js | 9 +- package-lock.json | 26 ++++ package.json | 3 + routes/main.js | 82 +++++++---- routes/rss.js | 19 +++ routes/static.js | 1 + server/middlewares.js | 38 ++--- server/util.js | 134 +++++++++++++++++- views/404.pug | 2 +- views/about.pug | 15 +- views/aotw.pug | 19 --- views/{index.pug => blog.pug} | 9 +- views/blogroll.pug | 10 +- views/contact.pug | 12 +- views/feeds.pug | 10 +- views/foss.pug | 2 +- views/music.pug | 14 +- views/notes.pug | 26 +++- views/now.pug | 10 +- views/pgp.pug | 10 +- views/post.pug | 82 +++++------ views/projects.pug | 2 +- views/projects_details.pug | 2 +- views/reply.pug | 2 +- views/uses.pug | 10 +- views/vinyl.pug | 16 ++- 33 files changed, 409 insertions(+), 226 deletions(-) delete mode 100644 content/music/aotw.yaml create mode 100644 routes/rss.js delete mode 100644 views/aotw.pug rename views/{index.pug => blog.pug} (79%) diff --git a/content/blog/2020/06/2020-06-05--missing-entropy.md b/content/blog/2020/06/2020-06-05--missing-entropy.md index 8fd0452..c7e4fba 100644 --- a/content/blog/2020/06/2020-06-05--missing-entropy.md +++ b/content/blog/2020/06/2020-06-05--missing-entropy.md @@ -70,7 +70,7 @@ In other words, VPSs are severely lacking in sources of entropy. That is why the There is a way to remedy the situation: [haveged](https://wiki.archlinux.org/index.php/Haveged). Having only discovered it last night, I do not fully understand it yet but from what I have read, it is a pseudorandom number generator (PRNG) that fills the `entropy pool` with "pseudorandomness". Installing `haveged` immediately solved my issue, all docker commands were running instantly again. -![Available entropy suddenly increases after installing haveged](/content/img/entropy_haveged.png) +![Available entropy suddenly increases after installing haveged](/static/entropy_haveged.png) *Can you tell when I installed haveged?* ## Caveat: pseudorandomness diff --git a/content/blog/2020/06/2020-06-05--website-load-performance.md b/content/blog/2020/06/2020-06-05--website-load-performance.md index ba40c98..a6cde5c 100644 --- a/content/blog/2020/06/2020-06-05--website-load-performance.md +++ b/content/blog/2020/06/2020-06-05--website-load-performance.md @@ -28,13 +28,13 @@ I decided to use [WebPageTest.org](https://www.webpagetest.org) to measure load First, a baseline measurement of my existing Cloudways solution. -![Cloudways - overview](/content/img/wpt_1_1a.png) +![Cloudways - overview](/static/wpt_1_1a.png) *Cloudways - overview* -![Cloudways - rating](/content/img/wpt_1_1b.png) +![Cloudways - rating](/static/wpt_1_1b.png) *Cloudways - rating* -![Cloudways - waterfall](/content/img/wpt_1_1c.png) +![Cloudways - waterfall](/static/wpt_1_1c.png) *Cloudways - waterfall* So the server returns the first byte of information after 480 milliseconds. Now, I should tell you that my website is based on [Phug](https://phug-lang.com), the PHP port of [pug.js templating](https://pugjs.org). The page is rendered in real-time and apparently, that takes a little over 300 ms. @@ -53,13 +53,13 @@ Anyway, can Caddy do better? ### Caddy -![Caddy - overview](/content/img/wpt_1_2a.png) +![Caddy - overview](/static/wpt_1_2a.png) *Caddy - overview* -![Caddy - rating](/content/img/wpt_1_2b.png) +![Caddy - rating](/static/wpt_1_2b.png) *Caddy - rating* -![Caddy - waterfall](/content/img/wpt_1_2c.png) +![Caddy - waterfall](/static/wpt_1_2c.png) *Caddy - waterfall* Well, as it turns out, it's largely the same performance. First byte arrived after 459 ms, but I've ran it a few times and there's really little difference between Cloudways and Caddy. @@ -76,13 +76,13 @@ I've tried a lot of things, I'll just narrow it down to the two most important f As it turned out, I had a few small SVG icons and some CSS files. I tried rendering them into the HTML page, so the data would be sent on the first data transmission and no separate requests were needed. For good measure, I also minified the CSS files which, for one file, reduced the size by 30%! -![Caddy+inline - overview](/content/img/wpt_1_6a.png) +![Caddy+inline - overview](/static/wpt_1_6a.png) *Caddy+inline - overview* -![Caddy+inline - rating](/content/img/wpt_1_6b.png) +![Caddy+inline - rating](/static/wpt_1_6b.png) *Caddy+inline - rating* -![Caddy+inline - waterfall](/content/img/wpt_1_6c.png) +![Caddy+inline - waterfall](/static/wpt_1_6c.png) *Caddy+inline - waterfall* On the waterfall above, you can clearly see the `dank-mono.css` was not inlined but I tried multiple configurations, there was no real gain as the image also needed to load and took longer anyway. So, all in all, inlining the SVG and CSS content did little in this case. @@ -97,13 +97,13 @@ As described on [their website](https://phug-lang.com/#usage), PHUG has support ### Caddy - PHUG optimization -![Caddy+PHUG - overview](/content/img/wpt_1_7a.png) +![Caddy+PHUG - overview](/static/wpt_1_7a.png) *Caddy+PHUG - overview* -![Caddy+PHUG - rating](/content/img/wpt_1_7b.png) +![Caddy+PHUG - rating](/static/wpt_1_7b.png) *Caddy+PHUG - rating* -![Caddy+PHUG - waterfall](/content/img/wpt_1_7c.png) +![Caddy+PHUG - waterfall](/static/wpt_1_7c.png) *Caddy+PHUG - waterfall* Well, there it is!!! First byte of data arrived after a mere 173 ms, website is useable in less than half a second and all scores are `A`! diff --git a/content/blog/2020/07/2020-07-03--keybase-website.md b/content/blog/2020/07/2020-07-03--keybase-website.md index dc071c5..a01561c 100644 --- a/content/blog/2020/07/2020-07-03--keybase-website.md +++ b/content/blog/2020/07/2020-07-03--keybase-website.md @@ -26,19 +26,19 @@ When you load that specific page, make sure to load it in a private session or w It is slow. Really slow. I noticed so too and decided to run a [Webpagetest (link to result)](https://www.webpagetest.org/result/200627_0Q_044080ef3ab8a678721658c90d2f4706/). Out of three runs, we analyze only the median run (so not the best one, not the worst one). -![Keybase encrypt Webpagetest overview](/content/img/keybase_encrypt__wpt_overview.png) +![Keybase encrypt Webpagetest overview](/static/keybase_encrypt__wpt_overview.png) *keybase.io/encrypt* ## The content loaded It takes **6.25 seconds** to fully load the **2.9 megabytes** that are used on this page. That is hefty for a page that is essentially a single form. I mean, look at it: -![Keybase encrypt page](/content/img/keybase_encrypt.png) +![Keybase encrypt page](/static/keybase_encrypt.png) *Why 2.9 megabytes?* That's a regular web form. What could possibly be **2.9 megabytes**? The javascript? -![Webpagetest run 1 overview](/content/img/keybase_encrypt__wpt_1.png) +![Webpagetest run 1 overview](/static/keybase_encrypt__wpt_1.png) *How many requests? How many bytes?* Most requests are fonts. That makes sense. Earlier, we saw the page only makes **12 requests**, so I could imagine a few of those being several fonts files. Fortunately, fonts are only **6.5%** of the bytes loaded, so we'll forgive them. @@ -49,7 +49,7 @@ Most requests are fonts. That makes sense. Earlier, we saw the page only makes * Let's grab the [waterfall](https://www.webpagetest.org/result/200627_0Q_044080ef3ab8a678721658c90d2f4706/1/details/#waterfall_view_step1) and see what is going on: -![Webpagetest run 1 waterfall](/content/img/keybase_encrypt__wpt_1_waterfall.png) +![Webpagetest run 1 waterfall](/static/keybase_encrypt__wpt_1_waterfall.png) *Run 1 waterfall* At two points in time, the loading of the website stalls. The first stall is **2.6 seconds** for the file `sitewide-js.js`. The second stall is **2.5 seconds** for the file `footprints_transp.png`. Let's go. @@ -58,7 +58,7 @@ At two points in time, the loading of the website stalls. The first stall is **2 This file is **4.7 megabytes** raw and **1.2 megabytes** gzipped. Let us look at a random excerpt: -![Javascript excerpt](/content/img/keybase_encrypt__js_excerpt.png) +![Javascript excerpt](/static/keybase_encrypt__js_excerpt.png) *Javascript excerpt* This is not really optimized for performance: one could choose to minimize the javascript. Allow me to use `@node-minify/cli`. @@ -78,7 +78,7 @@ Well, I need to specify one thing: the website loads a gzipped version of the or Have you found the image yet? It's the little image at the bottom of the dog (?) following footprints. Cute :) -![Footprints image](/content/img/keybase_encrypt__img.png) +![Footprints image](/static/keybase_encrypt__img.png) *Footprints image* Dimensions on page: **330 x 90 pixels** @@ -122,7 +122,7 @@ Anything else? Given that this is all cryptography related, maybe some security ## Security -![Webpagetest security score](/content/img/keybase_encrypt__security.png) +![Webpagetest security score](/static/keybase_encrypt__security.png) *Webpagetest security score* I've ran quite a few webpagetests on different website, but a **0** security score is new to me. What does that even mean? diff --git a/content/blog/2020/07/2020-07-31--flipper-zero-limited.md b/content/blog/2020/07/2020-07-31--flipper-zero-limited.md index 8a41468..bc0953c 100644 --- a/content/blog/2020/07/2020-07-31--flipper-zero-limited.md +++ b/content/blog/2020/07/2020-07-31--flipper-zero-limited.md @@ -14,39 +14,39 @@ I'm not going to lie, Flipper Zero sounds like a cool project for hackers. Here' Something extremely scummy is going on right now! Have a look: -![Flipper Zero Kickstarter](/content/img/kickstarted_counter__1a.png) +![Flipper Zero Kickstarter](/static/kickstarted_counter__1a.png) Looking good, lot's of stuff to read, let's take our time. -![Flipper Zero Kickstarter](/content/img/kickstarted_counter__1b.png) +![Flipper Zero Kickstarter](/static/kickstarted_counter__1b.png) My word, they're almost out of Early Birds! Please, for the love of god, if you want to save some money, pledge now, only 9 left and it clearly says "Limited"! ### One minute later -![Flipper Zero Kickstarter](/content/img/kickstarted_counter__2.png) +![Flipper Zero Kickstarter](/static/kickstarted_counter__2.png) A person has just pledged! Where's my credit card? ### Another minute later -![Flipper Zero Kickstarter](/content/img/kickstarted_counter__3.png) +![Flipper Zero Kickstarter](/static/kickstarted_counter__3.png) Wait, 9 left? Someone bailed? Doesn't matter, I need this! ### Yet another minute later -![Flipper Zero Kickstarter](/content/img/kickstarted_counter__4.png) +![Flipper Zero Kickstarter](/static/kickstarted_counter__4.png) Wait, what? ### And it goes on -![Flipper Zero Kickstarter](/content/img/kickstarted_counter__5.png) +![Flipper Zero Kickstarter](/static/kickstarted_counter__5.png) ### And on -![Flipper Zero Kickstarter](/content/img/kickstarted_counter__6.png) +![Flipper Zero Kickstarter](/static/kickstarted_counter__6.png) ## This needs to stop diff --git a/content/music/aotw.yaml b/content/music/aotw.yaml deleted file mode 100644 index aaf4954..0000000 --- a/content/music/aotw.yaml +++ /dev/null @@ -1,12 +0,0 @@ -- week: 2020-26 - year: 2017 - artist: Peter Silberman - title: Impermanence -- week: 2020-25 - year: 1984 - artist: Jean-Michel Jarre - title: Zoolook -- week: 2020-24 - year: 1962 - artist: Booker T. & the M.G.'s - title: Green Onions diff --git a/content/notes/2020/06/2020-06-08--nuc-fan-cleaning.md b/content/notes/2020/06/2020-06-08--nuc-fan-cleaning.md index bf7b075..f370977 100644 --- a/content/notes/2020/06/2020-06-08--nuc-fan-cleaning.md +++ b/content/notes/2020/06/2020-06-08--nuc-fan-cleaning.md @@ -14,5 +14,5 @@ If you haven't cleaned the fan in a while, your best bet is to open the NUC up a To prevent having to open a NUC up too often, I bought a few cans of compressed air and regularly blow air through the device. I'm also looking into placing air filters near the air intake. -![NUC cools down when fan is cleaned](/content/img/nuc_temp_fan_cleaning.png) +![NUC cools down when fan is cleaned](/static/nuc_temp_fan_cleaning.png) *Can you tell when compressed air was applied to the NUC?* diff --git a/content/notes/2020/06/2020-06-29--github-sinking.md b/content/notes/2020/06/2020-06-29--github-sinking.md index b022552..84525ca 100644 --- a/content/notes/2020/06/2020-06-29--github-sinking.md +++ b/content/notes/2020/06/2020-06-29--github-sinking.md @@ -10,7 +10,7 @@ published: true I rarely interact with [Github](https://github.com) anymore. All my projects are either on my selfhosted [Gitea](https://gitea.io) instance or on [Codeberg.org](https://codeberg.org/). That's why I missed the following on [Github Status](https://www.githubstatus.com/): -![Github status shows a lot of downtimes](/content/img/github_status.png) +![Github status shows a lot of downtimes](/static/github_status.png) *Yikes* Yikes, indeed. How everyone handles this is up to them. Large projects will find it hard to move, no doubt. diff --git a/index.js b/index.js index f08f756..038255c 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ const express = require('express') -const fs = require('fs') const app = express() +const fs = require('fs') require('dotenv').config() app.set('env', process.env.NODE_ENV || "production") @@ -9,12 +9,7 @@ app.set('port', process.env.PORT || 3000) app.use('/', require('./routes/main')) app.use('/', require('./routes/static')) -// app.use('/server', require('./routes/server')) -// app.use('/encrypt', require('./routes/encrypt')) -// app.use('/verify', require('./routes/verify')) -// app.use('/proofs', require('./routes/proofs')) -// app.use('/util', require('./routes/util')) -// app.use('/', require('./routes/profile')) +app.use('/rss', require('./routes/rss')) app.listen(app.get('port'), () => { console.log(`Node server listening at http://localhost:${app.get('port')}`) diff --git a/package-lock.json b/package-lock.json index a014b8a..546e5f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -562,6 +562,14 @@ "validator": "^13.1.1" } }, + "feed": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.1.tgz", + "integrity": "sha512-l28KKcK1J/u3iq5dRDmmoB2p7dtBfACC2NqJh4dI2kFptxH0asfjmOfcxqh5Sv8suAlVa73gZJ4REY5RrafVvg==", + "requires": { + "xml-js": "^1.6.11" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1402,6 +1410,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -1739,6 +1752,19 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, + "xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "requires": { + "sax": "^1.2.4" + } + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + }, "yaml-front-matter": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/yaml-front-matter/-/yaml-front-matter-4.1.0.tgz", diff --git a/package.json b/package.json index 4dcfd18..8731977 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,15 @@ "dotenv": "^8.2.0", "express": "^4.17.1", "express-validator": "^6.6.1", + "feed": "^4.2.1", "jstransformer-markdown-it": "^2.1.0", + "lodash": "^4.17.20", "luxon": "^1.25.0", "markdown-it-anchor": "^5.3.0", "markdown-it-table-of-contents": "^0.4.4", "markdown-it-title": "^3.0.0", "pug": "^3.0.0", + "yaml": "^1.10.0", "yaml-front-matter": "^4.1.0" }, "devDependencies": { diff --git a/routes/main.js b/routes/main.js index 3ce2972..4eef129 100644 --- a/routes/main.js +++ b/routes/main.js @@ -1,40 +1,66 @@ const router = require('express').Router() const fs = require('fs') +const _ = require('lodash') const mw = require('../server/middlewares') +const util = require('../server/util') + +router.param('slug', async (req, res, next, slug) => { + let posts = await util.getBlogPosts() + posts = _.filter(posts, (p) => { return slug == p.slug }) + if (posts.length > 0) { + res.locals.post = posts[0] + next() + return + } + posts = await util.getNotes() + posts = _.filter(posts, (p) => { return slug == p.slug }) + if (posts.length > 0) { + res.locals.post = posts[0] + next() + return + } + res.locals.post = null + next() +}) router.get('/', mw.getBlogPosts, (req, res) => { - res.render('index', { title: 'yarmo.eu' }) + res.render('blog', { title: 'yarmo.eu' }) }) - -router.get('/getting-started', (req, res) => { - let rawContent = fs.readFileSync(`./content/getting-started.md`, "utf8") - const content = md.render(rawContent) - res.render(`basic`, { title: `Getting started - Keyoxide`, content: content }) +router.get('/blog', mw.getBlogPosts, (req, res) => { + res.render('blog', { title: 'yarmo.eu' }) }) - -router.get('/faq', (req, res) => { - const mdAlt = require('markdown-it')({typographer: true}) - mdAlt.use(require("markdown-it-anchor"), { "level": 2, "permalink": true, "permalinkClass": 'header-anchor', "permalinkSymbol": '¶', "permalinkBefore": false }) - mdAlt.use(require("markdown-it-table-of-contents"), { "includeLevel": [2], "listType": "ul" }) - - let rawContent = fs.readFileSync(`./content/faq.md`, "utf8") - rawContent = rawContent.replace('${domain}', req.app.get('domain')) - const content = mdAlt.render(rawContent) - res.render(`basic`, { title: `Frequently Asked Questions - Keyoxide`, content: content }) +router.get('/notes', mw.getNotes, (req, res) => { + res.render('notes', { title: 'yarmo.eu' }) }) - -router.get('/guides', (req, res) => { - res.render('guides', { title: `Guides - Keyoxide` }) +router.get('/post/:slug', (req, res) => { + res.render('post', { title: 'yarmo.eu' }) }) - -router.get('/guides/:guideId', (req, res) => { - let env = {} - let rawContent = fs.readFileSync(`./content/guides/${req.params.guideId}.md`, "utf8", (err, data) => { - if (err) throw err - return data - }) - const content = md.render(rawContent, env) - res.render(`basic`, { title: `${env.title} - Keyoxide`, content: content }) +router.get('/blogroll', (req, res) => { + res.render('blogroll', { title: 'yarmo.eu' }) +}) +router.get('/feeds', (req, res) => { + res.render('feeds', { title: 'yarmo.eu' }) +}) +router.get('/about', (req, res) => { + res.render('about', { title: 'yarmo.eu' }) +}) +router.get('/contact', (req, res) => { + res.render('contact', { title: 'yarmo.eu' }) +}) +router.get('/now', (req, res) => { + res.render('now', { title: 'yarmo.eu' }) +}) +router.get('/uses', (req, res) => { + res.render('uses', { title: 'yarmo.eu' }) +}) +router.get('/music', (req, res) => { + res.render('music', { title: 'yarmo.eu' }) +}) +router.get('/vinyl', mw.getVinyl, (req, res) => { + res.render('vinyl', { title: 'yarmo.eu' }) +}) +router.get('/pgp', (req, res) => { + res.render('pgp', { title: 'yarmo.eu' }) }) module.exports = router diff --git a/routes/rss.js b/routes/rss.js new file mode 100644 index 0000000..ffc9ee5 --- /dev/null +++ b/routes/rss.js @@ -0,0 +1,19 @@ +const router = require('express').Router() +const fs = require('fs') +const _ = require('lodash') +const util = require('../server/util') + +router.get('/all', async (req, res) => { + res.setHeader('Content-Type', 'application/xml') + res.end(await util.getRSS()) +}) +router.get('/blog', async (req, res) => { + res.setHeader('Content-Type', 'application/xml') + res.end(await util.getRSS({ include: ['blog'] })) +}) +router.get('/notes', async (req, res) => { + res.setHeader('Content-Type', 'application/xml') + res.end(await util.getRSS({ include: ['notes'] })) +}) + +module.exports = router diff --git a/routes/static.js b/routes/static.js index f373067..252bb0a 100644 --- a/routes/static.js +++ b/routes/static.js @@ -4,5 +4,6 @@ const path = require('path') router.use('/favicon.png', express.static(path.join(__dirname, '../', 'public', 'favicon.png'))) router.use('/static', express.static(path.join(__dirname, '../', 'public'))) +router.use('/static', express.static(path.join(__dirname, '../', 'content', 'img'))) module.exports = router diff --git a/server/middlewares.js b/server/middlewares.js index e807341..d43ed78 100644 --- a/server/middlewares.js +++ b/server/middlewares.js @@ -1,30 +1,20 @@ -const path = require('path') const fs = require('fs') +const path = require('path') +const YAML = require('yaml') const util = require('./util') -const md = require('markdown-it')({ typographer: true }) -const yamlFront = require('yaml-front-matter') -const { DateTime } = require('luxon') module.exports.getBlogPosts = async (req, res, next) => { - let data = [] - for await (const f of util.getFiles(path.join(__dirname, '../', 'content', 'blog'))) { - const rawContent = fs.readFileSync(f, 'utf8') - const fm = yamlFront.loadFront(rawContent) - data.push({ - type: 'blog', - title: fm['title'], - author: fm['author'], - urlrel: `/post/${fm['slug']}`, - url: `https://yarmo.eu/post/${fm['slug']}`, - slug: fm['slug'], - date: fm['date'], - // date_formatted: DateTime.fromFormat(fm['date'], 'yyyy-LL-dd hh:mm:ss').toFormat('yyyy-LL-dd'), - date_formatted: DateTime.fromFormat(fm['date'], 'yyyy-LL-dd hh:mm:ss').setLocale("en").toLocaleString(DateTime.DATE_MED), - published: fm['published'], - discussion: fm['discussion'], - content: md.render(fm.__content) - }) - } - res.locals.blogPosts = data.reverse() + res.locals.blogPosts = await util.getBlogPosts({ publishedOnly: true }) + next() +} + +module.exports.getNotes = async (req, res, next) => { + res.locals.notes = await util.getNotes({ publishedOnly: true }) + next() +} + +module.exports.getVinyl = async (req, res, next) => { + const file = fs.readFileSync(path.join(__dirname, '../', 'content', 'music', 'vinyl.yaml'), 'utf8') + res.locals.vinyl = YAML.parse(file) next() } diff --git a/server/util.js b/server/util.js index fedf988..989d666 100644 --- a/server/util.js +++ b/server/util.js @@ -1,6 +1,12 @@ -const { resolve } = require('path') -const { readdir } = require('fs').promises const fs = require('fs') +const { readdir } = require('fs').promises +const path = require('path') +const { resolve } = require('path') +const _ = require('lodash') +const md = require('markdown-it')({ typographer: true }) +const yamlFront = require('yaml-front-matter') +const { DateTime } = require('luxon') +const Feed = require('feed').Feed async function* getFiles(dir) { const dirents = await readdir(dir, { withFileTypes: true }) @@ -14,4 +20,126 @@ async function* getFiles(dir) { } } -module.exports.getFiles = getFiles +const getBlogPosts = async (opts) => { + if (!opts) { opts = {} } + opts.publishedOnly = 'publishedOnly' in opts ? opts.publishedOnly : true + + let data = [] + for await (const f of getFiles(path.join(__dirname, '../', 'content', 'blog'))) { + const rawContent = fs.readFileSync(f, 'utf8') + const fm = yamlFront.loadFront(rawContent) + + if (opts.publishedOnly && !fm.published) { continue } + + data.push({ + type: 'blog', + title: fm.title, + author: fm.author, + urlrel: `/post/${fm.slug}`, + url: `https://yarmo.eu/post/${fm.slug}`, + slug: fm.slug, + date: fm.date, + date_formatted: DateTime.fromFormat(fm.date, 'yyyy-LL-dd hh:mm:ss').setLocale("en").toLocaleString(DateTime.DATE_MED), + published: fm.published, + discussion: fm.discussion, + content: md.render(fm.__content) + }) + } + return data.reverse() +} + +const getNotes = async (opts) => { + if (!opts) { opts = {} } + opts.publishedOnly = 'publishedOnly' in opts ? opts.publishedOnly : true + + let data = [] + for await (const f of getFiles(path.join(__dirname, '../', 'content', 'notes'))) { + const rawContent = fs.readFileSync(f, 'utf8') + const fm = yamlFront.loadFront(rawContent) + + if (opts.publishedOnly && !fm.published) { continue } + + data.push({ + type: 'note', + title: fm.title, + author: fm.author, + urlrel: `/post/${fm.slug}`, + url: `https://yarmo.eu/post/${fm.slug}`, + slug: fm.slug, + date: fm.date, + date_formatted: DateTime.fromFormat(fm.date, 'yyyy-LL-dd hh:mm:ss').setLocale("en").toLocaleString(DateTime.DATE_MED), + published: fm.published, + discussion: fm.discussion, + content: md.render(fm.__content) + }) + } + return data.reverse() +} + +const getRSS = async (opts) => { + if (!opts) { opts = {} } + opts.include = 'include' in opts ? opts.include : ['blog', 'notes'] + // opts.excludeBlogPosts = 'excludeBlogPosts' in opts ? opts.excludeBlogPosts : false + // opts.excludeNotes = 'excludeNotes' in opts ? opts.excludeNotes : false + + const feed = new Feed({ + title: "Yarmo's blog and notes", + description: "Blog posts and notes feed for yarmo.eu discussing open source, privacy and selfhosted stuff", + id: "https://yarmo.eu", + link: "https://yarmo.eu", + language: "en", + favicon: "https://yarmo.eu/favicon.png", + copyright: "All rights reserved 2020 Yarmo Mackenbach", + updated: new Date(Date.now()), + author: { + name: "Yarmo Mackenbach", + email: "yarmo@yarmo.eu", + link: "https://yarmo.eu" + } + }) + + feed.addCategory("Technology") + feed.addCategory("FOSS") + feed.addCategory("Decentralization") + feed.addCategory("Privacy") + feed.addCategory("Identity") + feed.addCategory("Cryptography") + feed.addCategory("Selfhosted") + + let posts = [] + if (opts.include.includes('blog')) { + posts = posts.concat(await getBlogPosts()) + } + if (opts.include.includes('notes')) { + posts = posts.concat(await getNotes()) + } + + posts = _.sortBy(posts, ['date']).reverse() + + posts.forEach((item, i) => { + feed.addItem({ + title: item.title, + id: item.url, + link: item.url, + description: item.content, + content: item.content, + author: [ + { + name: "Yarmo Mackenbach", + email: "yarmo@yarmo.eu", + link: "https://yarmo.eu" + } + ], + date: new Date(item.date) + }) + }) + + return feed.rss2() +} + +module.exports = { + getFiles: getFiles, + getBlogPosts: getBlogPosts, + getNotes: getNotes, + getRSS: getRSS +} diff --git a/views/404.pug b/views/404.pug index 8fd6645..d33bf36 100644 --- a/views/404.pug +++ b/views/404.pug @@ -1,4 +1,4 @@ -extends layout +extends templates/main block content h2 HTTP 404 diff --git a/views/about.pug b/views/about.pug index cebefe3..fc990da 100644 --- a/views/about.pug +++ b/views/about.pug @@ -1,28 +1,25 @@ -extends layout +extends templates/main block content header - nav - | about me h1 | About Me + nav + | >> + a(href="/about") about me nav | Go to: - a(href="/now") now - | | a(href="/") blog | | a(href="/notes") notes | | a(href="/feeds") feeds | | - a(href="/blogroll") blogroll + a(href="/now") now | | a(href="/uses") uses | | - a(href="/foss") FOSS - | | - a(href="/projects") projects + a(href="/work") work | | a(href="/music") music | | diff --git a/views/aotw.pug b/views/aotw.pug deleted file mode 100644 index e12d466..0000000 --- a/views/aotw.pug +++ /dev/null @@ -1,19 +0,0 @@ -extends layout - -mixin entry($item) - .list__item - p !{$item['week']} >> !{$item['artist']} - !{$item['title']} (!{$item['year']}) - -block content - header - nav - a(href="/about") about me - | > - a(href="/music") music - | > album of the week - h1 Yarmo's Album Of The Week - - main - .list - each $item in $albums - +entry($item) diff --git a/views/index.pug b/views/blog.pug similarity index 79% rename from views/index.pug rename to views/blog.pug index 968b807..a51dcd6 100644 --- a/views/index.pug +++ b/views/blog.pug @@ -3,19 +3,22 @@ extends templates/main mixin entry(item) article.longform_list__item.h-entry p - a(href="{item['urlrel']}").p-name.u-url !{item['title']} + a(href=item['urlrel']).p-name.u-url !{item['title']} br | Posted on - time(datetime="{item['date']}").dt-published !{item['date_formatted']} + time(datetime=item['date']).dt-published !{item['date_formatted']} block content .h-card header - nav + //nav a(href="/about") about me | > blog h1 | Yarmo's blog + nav + | >> + a(href="/") blog nav | Go to: a(href="/about") about me diff --git a/views/blogroll.pug b/views/blogroll.pug index f01d3ce..c4fa75a 100644 --- a/views/blogroll.pug +++ b/views/blogroll.pug @@ -1,12 +1,14 @@ -extends layout +extends templates/main block content header - nav - a(href="/about") about me - | > blogroll h1 | Blogroll + nav + | >> + a(href="/about") about me + | > + a(href="/blogroll") blogroll main a(href="https://ar.al/") Aral Balkan diff --git a/views/contact.pug b/views/contact.pug index 215d603..375aa46 100644 --- a/views/contact.pug +++ b/views/contact.pug @@ -1,12 +1,14 @@ -extends layout +extends templates/main block content header - nav - a(href="/about") about me - | > contact h1 | Contact me + nav + | >> + a(href="/about") about me + | > + a(href="/contact") contact main h2 >> Online presence @@ -106,7 +108,7 @@ block content a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu | . - h3#pgp-advanced#kleopatra Using the Kleopatra software (advanced) + h3#pgp-advanced Using the Kleopatra software (advanced) ol li diff --git a/views/feeds.pug b/views/feeds.pug index f338f89..e397a14 100644 --- a/views/feeds.pug +++ b/views/feeds.pug @@ -1,12 +1,14 @@ -extends layout +extends templates/main block content header - nav - a(href="/about") about me - | > feeds h1 | Feeds + nav + | >> + a(href="/about") about me + | > + a(href="/feeds") feeds main ul diff --git a/views/foss.pug b/views/foss.pug index 4dd38ea..3adaca4 100644 --- a/views/foss.pug +++ b/views/foss.pug @@ -1,4 +1,4 @@ -extends layout +extends templates/main mixin foss_contribution($item) p diff --git a/views/music.pug b/views/music.pug index a9245a5..a23da9b 100644 --- a/views/music.pug +++ b/views/music.pug @@ -1,16 +1,16 @@ -extends layout +extends templates/main block content header - nav - a(href="/about") about me - | > music h1 Yarmo's music - p + nav + | >> + a(href="/about") about me + | > + a(href="/music") music + nav | Go to: a(href="/vinyl") vinyl - | | - a(href="/aotw") Album Of The Week main h3 Instruments diff --git a/views/notes.pug b/views/notes.pug index 8d96450..a8c5d98 100644 --- a/views/notes.pug +++ b/views/notes.pug @@ -1,21 +1,33 @@ -extends layout +extends templates/main -mixin entry($item) +mixin entry(item) article.longform_list__item.h-entry p - a(href="{$item['urlrel']}").p-nameu-url !{$item['title']} + a(href=item['urlrel']).p-nameu-url !{item['title']} br | Posted on - time(datetime="{$item['date']}").dt-published !{$item['date_formatted']} + time(datetime=item['date']).dt-published !{item['date_formatted']} block content header - nav + //nav a(href="/about") about me | > notes h1 Yarmo's notes + nav + | >> + a(href="/notes") notes + nav + | Go to: + a(href="/about") about me + | | + a(href="/") blog + | | + a(href="/feeds") feeds + | | + a(href="/contact") contact main .longform_list - each $item in $posts - +entry($item) + each item in notes + +entry(item) diff --git a/views/now.pug b/views/now.pug index 2b30320..4694626 100644 --- a/views/now.pug +++ b/views/now.pug @@ -1,12 +1,14 @@ -extends layout +extends templates/main block content header - nav - a(href="/about") about me - | > now h1 | Now + nav + | >> + a(href="/about") about me + | > + a(href="/now") now main h3 Working on diff --git a/views/pgp.pug b/views/pgp.pug index 81df1dc..647f762 100644 --- a/views/pgp.pug +++ b/views/pgp.pug @@ -1,12 +1,14 @@ -extends layout +extends templates/main block content header - nav - a(href="/about") about me - | > pgp h1 | PGP public key + nav + | >> + a(href="/about") about me + | > + a(href="/pgp") pgp main h3#pgp-fingerprint Fingerprint diff --git a/views/post.pug b/views/post.pug index 1a6426a..ab8b45f 100644 --- a/views/post.pug +++ b/views/post.pug @@ -1,72 +1,72 @@ -extends layout +extends templates/main -mixin webmention($item) - if (!array_key_exists('type', $item)) +mixin webmention(item) + if (!array_key_exists('type', item)) p - if (array_key_exists('title', $item)) - a(href="{$item['source']}") !{$item['title']} + if (array_key_exists('title', item)) + a(href="{item['source']}") !{item['title']} else - a(href="{$item['source']}") !{$item['source']} - if (array_key_exists('author_name', $item)) - | by !{$item['author_name']} - if (array_key_exists('date', $item)) - | on !{$item['date']} - if (array_key_exists('time', $item)) - | at !{$item['time']} UTC - else if ($item['type'] == "comment") + a(href="{item['source']}") !{item['source']} + if (array_key_exists('author_name', item)) + | by !{item['author_name']} + if (array_key_exists('date', item)) + | on !{item['date']} + if (array_key_exists('time', item)) + | at !{item['time']} UTC + else if (item['type'] == "comment") .comment p.quote - if (array_key_exists('title', $item)) - strong !{$item['title']} + if (array_key_exists('title', item)) + strong !{item['title']} br - if (array_key_exists('content', $item)) - | !{$item['content']} + if (array_key_exists('content', item)) + | !{item['content']} p.sub - a(href="{$item['source']}") Commented - if (array_key_exists('author_name', $item)) - | by !{$item['author_name']} - if (array_key_exists('date', $item)) - | on !{$item['date']} - if (array_key_exists('time', $item)) - | at !{$item['time']} UTC + a(href="{item['source']}") Commented + if (array_key_exists('author_name', item)) + | by !{item['author_name']} + if (array_key_exists('date', item)) + | on !{item['date']} + if (array_key_exists('time', item)) + | at !{item['time']} UTC -mixin discussionLink($item) +mixin discussionLink(item) p - a(href="{$item}") !{$item} + a(href="{item}") !{item} block content header nav - a(href="/about") about me - | > - if ($post["type"] == "blog") + | >> + if post.type == 'blog' a(href="/") blog - if ($post["type"] == "note") + if post.type == 'note' a(href="/notes") notes - | > !{$post['slug']} + | > + a(href=post.url)= post.slug main article.longform.h-entry - h1.p-name !{$post['title']} + h1.p-name !{post.title} p.longform__header | Posted on - a(href="{$post['url']}" datetime="{$post['date']}").u-url.dt-published !{$post['date_formatted']} + a(href=post.url datetime="{post.date}").u-url.dt-published !{post.date_formatted} | by - a(href="/" rel="author").p-author.h-card !{$post['author']} + a(href="/" rel="author").p-author.h-card !{post.author} .longform__content.e-content - | !{$post['content']} + | !{post.content} - if (array_key_exists('discussion', $post) && isset($post['discussion'])) + if ('discussion' in post && post.discussion) .discussion.subsection h2 Join the discussion - each $item in $post["discussion"] - +discussionLink($item) + each item in post["discussion"] + +discussionLink(item) .webmentions.subsection h2 Webmentions - if ($post['hasWebmentions']) - each $item in $post["webmentions"] - +webmention($item) + if (post.hasWebmentions) + each item in post["webmentions"] + +webmention(item) else p This post has not been mentioned yet. diff --git a/views/projects.pug b/views/projects.pug index a7d200c..7d07df8 100644 --- a/views/projects.pug +++ b/views/projects.pug @@ -1,4 +1,4 @@ -extends layout +extends templates/main mixin entry($item) article.longform_list__item diff --git a/views/projects_details.pug b/views/projects_details.pug index 7360efe..e97daa8 100644 --- a/views/projects_details.pug +++ b/views/projects_details.pug @@ -1,4 +1,4 @@ -extends layout +extends templates/main mixin webmention($item) p diff --git a/views/reply.pug b/views/reply.pug index 1cbfa92..ab80420 100644 --- a/views/reply.pug +++ b/views/reply.pug @@ -1,4 +1,4 @@ -extends layout +extends templates/main mixin webmention($item) if (!array_key_exists('type', $item)) diff --git a/views/uses.pug b/views/uses.pug index a554058..8597b2d 100644 --- a/views/uses.pug +++ b/views/uses.pug @@ -1,12 +1,14 @@ -extends layout +extends templates/main block content header - nav - a(href="/about") about me - | > uses h1 | Uses + nav + | >> + a(href="/about") about me + | > + a(href="/uses") uses main h2 Hardware diff --git a/views/vinyl.pug b/views/vinyl.pug index c5904bb..28ad33d 100644 --- a/views/vinyl.pug +++ b/views/vinyl.pug @@ -1,19 +1,21 @@ -extends layout +extends templates/main -mixin entry($item) +mixin entry(item) .list__item - p !{$item['artist']} - !{$item['title']} (!{$item['year']}) + p !{item['artist']} - !{item['title']} (!{item['year']}) block content header + h1 Yarmo's vinyl collection nav + | >> a(href="/about") about me | > a(href="/music") music - | > vinyl - h1 Yarmo's vinyl collection + | > + a(href="/vinyl") vinyl main .list - each $item in $albums - +entry($item) + each item in vinyl.albums + +entry(item) From 2e862dfe9544028fdd6bfe1b8e4b830a985a3564 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 10:12:13 +0200 Subject: [PATCH 03/14] Improve titles --- routes/main.js | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/routes/main.js b/routes/main.js index 4eef129..f4ff806 100644 --- a/routes/main.js +++ b/routes/main.js @@ -24,43 +24,46 @@ router.param('slug', async (req, res, next, slug) => { }) router.get('/', mw.getBlogPosts, (req, res) => { - res.render('blog', { title: 'yarmo.eu' }) + res.render('blog', { title: 'Blog — yarmo.eu' }) }) router.get('/blog', mw.getBlogPosts, (req, res) => { - res.render('blog', { title: 'yarmo.eu' }) + res.render('blog', { title: 'Blog — yarmo.eu' }) }) router.get('/notes', mw.getNotes, (req, res) => { - res.render('notes', { title: 'yarmo.eu' }) + res.render('notes', { title: 'Notes — yarmo.eu' }) }) router.get('/post/:slug', (req, res) => { - res.render('post', { title: 'yarmo.eu' }) + res.render('post', { title: `${res.locals.post.title} — yarmo.eu` }) }) router.get('/blogroll', (req, res) => { - res.render('blogroll', { title: 'yarmo.eu' }) + res.render('blogroll', { title: 'Blogroll — yarmo.eu' }) }) router.get('/feeds', (req, res) => { - res.render('feeds', { title: 'yarmo.eu' }) + res.render('feeds', { title: 'Feeds — yarmo.eu' }) }) router.get('/about', (req, res) => { - res.render('about', { title: 'yarmo.eu' }) + res.render('about', { title: 'About me — yarmo.eu' }) +}) +router.get('/work', (req, res) => { + res.render('work', { title: 'Work — yarmo.eu' }) }) router.get('/contact', (req, res) => { - res.render('contact', { title: 'yarmo.eu' }) + res.render('contact', { title: 'Contact — yarmo.eu' }) }) router.get('/now', (req, res) => { - res.render('now', { title: 'yarmo.eu' }) + res.render('now', { title: 'Now — yarmo.eu' }) }) router.get('/uses', (req, res) => { - res.render('uses', { title: 'yarmo.eu' }) + res.render('uses', { title: 'Uses — yarmo.eu' }) }) router.get('/music', (req, res) => { - res.render('music', { title: 'yarmo.eu' }) + res.render('music', { title: 'Music — yarmo.eu' }) }) router.get('/vinyl', mw.getVinyl, (req, res) => { - res.render('vinyl', { title: 'yarmo.eu' }) + res.render('vinyl', { title: 'Vinyl — yarmo.eu' }) }) router.get('/pgp', (req, res) => { - res.render('pgp', { title: 'yarmo.eu' }) + res.render('pgp', { title: 'PGP — yarmo.eu' }) }) module.exports = router From 060daae4167364b36bcc528bc2218f413fd47c1f Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 12:44:14 +0200 Subject: [PATCH 04/14] Dump --- ...0048AC0B23301E1F77E994909F6BD6F80F485D.asc | 0 ...0048AC0B23301E1F77E994909F6BD6F80F485D.pgp | Bin routes/static.js | 7 +++ views/id.pug | 2 +- views/pgp.pug | 2 +- views/work.pug | 44 ++++++++++++++++++ 6 files changed, 53 insertions(+), 2 deletions(-) rename 9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc => keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc (100%) rename 9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp => keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp (100%) create mode 100644 views/work.pug diff --git a/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc b/keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc similarity index 100% rename from 9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc rename to keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc diff --git a/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp b/keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp similarity index 100% rename from 9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp rename to keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp diff --git a/routes/static.js b/routes/static.js index 252bb0a..cec477b 100644 --- a/routes/static.js +++ b/routes/static.js @@ -6,4 +6,11 @@ router.use('/favicon.png', express.static(path.join(__dirname, '../', 'public', router.use('/static', express.static(path.join(__dirname, '../', 'public'))) router.use('/static', express.static(path.join(__dirname, '../', 'content', 'img'))) +router.use('/*.asc', (req, res, next) => { + res.sendFile(path.join(__dirname, '../', 'keys', `${req.params[0]}.asc`)) +}) +router.use('/*.pgp', (req, res, next) => { + res.sendFile(path.join(__dirname, '../', 'keys', `${req.params[0]}.pgp`)) +}) + module.exports = router diff --git a/views/id.pug b/views/id.pug index bf42af3..dc2fb4b 100644 --- a/views/id.pug +++ b/views/id.pug @@ -44,4 +44,4 @@ | Location: span.p-country-name The Netherlands pre(style="display:none").key - include ../9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc + include ../keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc diff --git a/views/pgp.pug b/views/pgp.pug index 647f762..85b1af4 100644 --- a/views/pgp.pug +++ b/views/pgp.pug @@ -27,4 +27,4 @@ block content h3#pgp-public-key Plaintext pre.select-all code - include ../9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc + include ../keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc diff --git a/views/work.pug b/views/work.pug new file mode 100644 index 0000000..8414a07 --- /dev/null +++ b/views/work.pug @@ -0,0 +1,44 @@ +extends templates/main + +mixin foss_contribution($item) + p + a(href="{$item['url-repo']}") !{$item['repo']} + | — + a(href="{$item['url-item']}") #!{$item['id']} + br + | !{$item['title']} + +block content + header + h1 + | Work + nav + | >> + a(href="/about") about me + | > + a(href="/work") work + + main + h2 >> VCS accounts + + .wrapper-table + table + tbody + tr + td Codeberg + td + a(href="https://codeberg.org/yarmo" rel="me") @yarmo + tr + td GitLab + td + a(href="https://gitlab.com/yarmo" rel="me") @yarmo + tr + td Github + td + a(href="https://github.com/YarmoM" rel="me") @YarmoM + + h2 >> Contributions + + each $item in $foss + +foss_contribution($item) + From a284995ee8ddf610409cc81dce8217ed671d53f3 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 14:59:04 +0200 Subject: [PATCH 05/14] Dump --- package-lock.json | 25 ++++++++++++++ package.json | 1 + routes/main.js | 25 ++++---------- server/middlewares.js | 12 +++++++ server/util.js | 25 ++++++++++++++ views/post.pug | 52 ++++++++++++++--------------- views/vinyl.pug | 30 ++++++++--------- views/work.pug | 77 ++++++++++++++++++++----------------------- 8 files changed, 146 insertions(+), 101 deletions(-) diff --git a/package-lock.json b/package-lock.json index 546e5f4..4130218 100644 --- a/package-lock.json +++ b/package-lock.json @@ -150,6 +150,16 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "bent": { + "version": "7.3.10", + "resolved": "https://registry.npmjs.org/bent/-/bent-7.3.10.tgz", + "integrity": "sha512-X2P2nGRWejGn6IjJfL4usOuAVMng1DdyuRhXLGOcUvEblBcLZenrSjlkgS8ob1s3tbq3mo1FDxKhCRNvcf0y0Q==", + "requires": { + "bytesish": "^0.4.1", + "caseless": "~0.12.0", + "is-stream": "^2.0.0" + } + }, "binary-extensions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", @@ -213,6 +223,11 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "bytesish": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/bytesish/-/bytesish-0.4.3.tgz", + "integrity": "sha512-OuwahLpcvvYfFnxZL0E/Gx6D7U2A72JM8cXL+5uiiZP/x84B/arG5kL8QfRLCLKb/Ttp1Jk2bPDLeltP96dtbw==" + }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -251,6 +266,11 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -834,6 +854,11 @@ "has-symbols": "^1.0.1" } }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", diff --git a/package.json b/package.json index 8731977..3a94515 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "author": "Yarmo Mackenbach (https://yarmo.eu)", "license": "AGPL-3.0-or-later", "dependencies": { + "bent": "^7.3.10", "dotenv": "^8.2.0", "express": "^4.17.1", "express-validator": "^6.6.1", diff --git a/routes/main.js b/routes/main.js index f4ff806..893b603 100644 --- a/routes/main.js +++ b/routes/main.js @@ -4,24 +4,7 @@ const _ = require('lodash') const mw = require('../server/middlewares') const util = require('../server/util') -router.param('slug', async (req, res, next, slug) => { - let posts = await util.getBlogPosts() - posts = _.filter(posts, (p) => { return slug == p.slug }) - if (posts.length > 0) { - res.locals.post = posts[0] - next() - return - } - posts = await util.getNotes() - posts = _.filter(posts, (p) => { return slug == p.slug }) - if (posts.length > 0) { - res.locals.post = posts[0] - next() - return - } - res.locals.post = null - next() -}) +router.param('slug', mw.getPostBySlug) router.get('/', mw.getBlogPosts, (req, res) => { res.render('blog', { title: 'Blog — yarmo.eu' }) @@ -29,9 +12,15 @@ router.get('/', mw.getBlogPosts, (req, res) => { router.get('/blog', mw.getBlogPosts, (req, res) => { res.render('blog', { title: 'Blog — yarmo.eu' }) }) +router.get('/blog/:s', (req, res) => { + res.redirect(`/post/${req.params.s}`) +}) router.get('/notes', mw.getNotes, (req, res) => { res.render('notes', { title: 'Notes — yarmo.eu' }) }) +router.get('/notes/:s', (req, res) => { + res.redirect(`/post/${req.params.s}`) +}) router.get('/post/:slug', (req, res) => { res.render('post', { title: `${res.locals.post.title} — yarmo.eu` }) }) diff --git a/server/middlewares.js b/server/middlewares.js index d43ed78..c7c3dc5 100644 --- a/server/middlewares.js +++ b/server/middlewares.js @@ -13,6 +13,18 @@ module.exports.getNotes = async (req, res, next) => { next() } +module.exports.getPostBySlug = async (req, res, next, slug) => { + let post = await util.getPost(slug) + + if (post) { + post.webmentions = await util.getWebmentions(post.url) + post.hasWebmentions = post.webmentions.length > 0 + } + + res.locals.post = post + next() +} + module.exports.getVinyl = async (req, res, next) => { const file = fs.readFileSync(path.join(__dirname, '../', 'content', 'music', 'vinyl.yaml'), 'utf8') res.locals.vinyl = YAML.parse(file) diff --git a/server/util.js b/server/util.js index 989d666..3e706ba 100644 --- a/server/util.js +++ b/server/util.js @@ -2,6 +2,8 @@ const fs = require('fs') const { readdir } = require('fs').promises const path = require('path') const { resolve } = require('path') +const bent = require('bent') +const getJSON = bent('json') const _ = require('lodash') const md = require('markdown-it')({ typographer: true }) const yamlFront = require('yaml-front-matter') @@ -76,6 +78,27 @@ const getNotes = async (opts) => { return data.reverse() } +const getPost = async (slug) => { + let post = null, posts = await getBlogPosts() + posts = _.filter(posts, (p) => { return slug == p.slug }) + post = posts.length > 0 ? posts[0] : null + + if (!post) { + posts = await getNotes() + posts = _.filter(posts, (p) => { return slug == p.slug }) + post = posts.length > 0 ? posts[0] : null + } + + return post +} + +const getWebmentions = async (url) => { + const data_1 = await getJSON(`https://webm.yarmo.eu/get?target=${url}`) + const data_2 = await getJSON(`https://webm.yarmo.eu/get?target=${url.replace('/post/', '/blog/')}`) + const data_3 = await getJSON(`https://webm.yarmo.eu/get?target=${url.replace('/post/', '/notes/')}`) + return data_1.concat(data_2).concat(data_3) +} + const getRSS = async (opts) => { if (!opts) { opts = {} } opts.include = 'include' in opts ? opts.include : ['blog', 'notes'] @@ -141,5 +164,7 @@ module.exports = { getFiles: getFiles, getBlogPosts: getBlogPosts, getNotes: getNotes, + getPost: getPost, + getWebmentions: getWebmentions, getRSS: getRSS } diff --git a/views/post.pug b/views/post.pug index ab8b45f..1fa9cd5 100644 --- a/views/post.pug +++ b/views/post.pug @@ -1,38 +1,38 @@ extends templates/main mixin webmention(item) - if (!array_key_exists('type', item)) + if (!('type' in item)) p - if (array_key_exists('title', item)) - a(href="{item['source']}") !{item['title']} + if ('title' in item) + a(href=item.source) !{item.title} else - a(href="{item['source']}") !{item['source']} - if (array_key_exists('author_name', item)) - | by !{item['author_name']} - if (array_key_exists('date', item)) - | on !{item['date']} - if (array_key_exists('time', item)) - | at !{item['time']} UTC - else if (item['type'] == "comment") + a(href=item.source) !{item.source} + if ('author_name' in item) + | by !{item.author_name} + if ('date' in item) + | on !{item.date} + if ('time' in item) + | at !{item.time} UTC + else if (item.type == "comment") .comment p.quote - if (array_key_exists('title', item)) - strong !{item['title']} + if ('title' in item) + strong !{item.title} br - if (array_key_exists('content', item)) - | !{item['content']} + if ('content' in item) + | !{item.content} p.sub - a(href="{item['source']}") Commented - if (array_key_exists('author_name', item)) - | by !{item['author_name']} - if (array_key_exists('date', item)) - | on !{item['date']} - if (array_key_exists('time', item)) - | at !{item['time']} UTC + a(href=item.source) Commented + if ('author_name' in item) + | by !{item.author_name} + if ('date' in item) + | on !{item.date} + if ('time' in item) + | at !{item.time} UTC mixin discussionLink(item) p - a(href="{item}") !{item} + a(href=item) !{item} block content header @@ -60,13 +60,13 @@ block content if ('discussion' in post && post.discussion) .discussion.subsection h2 Join the discussion - each item in post["discussion"] + each item in post.discussion +discussionLink(item) .webmentions.subsection h2 Webmentions - if (post.hasWebmentions) - each item in post["webmentions"] + if post.hasWebmentions + each item in post.webmentions +webmention(item) else p This post has not been mentioned yet. diff --git a/views/vinyl.pug b/views/vinyl.pug index 28ad33d..0231c92 100644 --- a/views/vinyl.pug +++ b/views/vinyl.pug @@ -1,21 +1,21 @@ extends templates/main mixin entry(item) - .list__item - p !{item['artist']} - !{item['title']} (!{item['year']}) + .list__item + p !{item['artist']} - !{item['title']} (!{item['year']}) block content - header - h1 Yarmo's vinyl collection - nav - | >> - a(href="/about") about me - | > - a(href="/music") music - | > - a(href="/vinyl") vinyl + header + h1 Yarmo's vinyl collection + nav + | >> + a(href="/about") about me + | > + a(href="/music") music + | > + a(href="/vinyl") vinyl - main - .list - each item in vinyl.albums - +entry(item) + main + .list + each item in vinyl.albums + +entrysitem) diff --git a/views/work.pug b/views/work.pug index 8414a07..707faf3 100644 --- a/views/work.pug +++ b/views/work.pug @@ -1,44 +1,37 @@ extends templates/main - -mixin foss_contribution($item) - p - a(href="{$item['url-repo']}") !{$item['repo']} - | — - a(href="{$item['url-item']}") #!{$item['id']} - br - | !{$item['title']} - + block content - header - h1 - | Work - nav - | >> - a(href="/about") about me - | > - a(href="/work") work - - main - h2 >> VCS accounts - - .wrapper-table - table - tbody - tr - td Codeberg - td - a(href="https://codeberg.org/yarmo" rel="me") @yarmo - tr - td GitLab - td - a(href="https://gitlab.com/yarmo" rel="me") @yarmo - tr - td Github - td - a(href="https://github.com/YarmoM" rel="me") @YarmoM - - h2 >> Contributions - - each $item in $foss - +foss_contribution($item) - + header + h1 + | Work + nav + | >> + a(href="/about") about me + | > + a(href="/work") work + + main + h2 >> Open Source developer + + h3 Projects + p + | Currently working on + a(href="https://keyoxide.org") Keyoxide + | . + + h3 VCS accounts + .wrapper-table + table + tbody + tr + td Codeberg + td + a(href="https://codeberg.org/yarmo" rel="me") @yarmo + tr + td GitLab + td + a(href="https://gitlab.com/yarmo" rel="me") @yarmo + tr + td Github + td + a(href="https://github.com/YarmoM" rel="me") @YarmoM From 02d277e063e651c898ae5310381fc6069f3961c7 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 15:15:01 +0200 Subject: [PATCH 06/14] Add anchors to header --- content/blog/2020/06/2020-06-18--no-io-yes-xyz.md | 4 ++-- public/style.css | 8 ++++++++ server/util.js | 8 ++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/content/blog/2020/06/2020-06-18--no-io-yes-xyz.md b/content/blog/2020/06/2020-06-18--no-io-yes-xyz.md index 6b80b69..53ea4e1 100644 --- a/content/blog/2020/06/2020-06-18--no-io-yes-xyz.md +++ b/content/blog/2020/06/2020-06-18--no-io-yes-xyz.md @@ -71,7 +71,7 @@ I have bought .io domains in the past. I did not have the knowledge of what was --- -## Update 1 +## Update 1 There is also the issue of the **.io** TLD's [future](https://www.prolificlondon.co.uk/marketing-tech-news/tech-news/2019/05/future-popular-io-domains-question-over-british-empire-row): @@ -81,7 +81,7 @@ Who knows what will happen to your domain registration when control is passed to --- -## Update 2 +## Update 2 It has been pointed out by many that this post focuses too much on the **.xyz** gTLD. This was not my intention. In fact, any gTLD will do just fine, after all they are generic. A non-exhaustive list of gTLDs that could perfectly replace **.io** (assuming **.io** simply stands for "input/output"): diff --git a/public/style.css b/public/style.css index b7c3c0d..aec424b 100644 --- a/public/style.css +++ b/public/style.css @@ -38,6 +38,7 @@ --clr-link-alt: hsl(175,38%,60%); --clr-code: hsl(0,0%,15%); } + * { box-sizing: border-box; } @@ -82,6 +83,13 @@ a:hover { background-color: var(--clr-link-alt); text-decoration: none; } +a.header-anchor { + text-decoration: none; + opacity: 0.5; +} +h2:hover a.header-anchor { + opacity: 1; +} h1 { line-height: 1.2em; margin: 8px 0 12px 0; diff --git a/server/util.js b/server/util.js index 3e706ba..9c622fa 100644 --- a/server/util.js +++ b/server/util.js @@ -10,6 +10,14 @@ const yamlFront = require('yaml-front-matter') const { DateTime } = require('luxon') const Feed = require('feed').Feed +md.use(require("markdown-it-anchor"), { + "level": 2, + "permalink": true, + "permalinkClass": 'header-anchor', + "permalinkSymbol": '¶', + "permalinkBefore": false +}) + async function* getFiles(dir) { const dirents = await readdir(dir, { withFileTypes: true }) for (const dirent of dirents) { From 150e90381acb7718509b1fb7a103c0e9a03c5a2b Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 15:25:49 +0200 Subject: [PATCH 07/14] Reindent --- views/404.pug | 10 +- views/about.pug | 324 ++++++++++++++++++------------------- views/blog.pug | 72 ++++----- views/blogroll.pug | 46 +++--- views/contact.pug | 280 ++++++++++++++++---------------- views/feeds.pug | 34 ++-- views/foss.pug | 76 ++++----- views/id.pug | 92 +++++------ views/music.pug | 92 +++++------ views/notes.pug | 56 +++---- views/now.pug | 46 +++--- views/pgp.pug | 52 +++--- views/post.pug | 128 +++++++-------- views/projects.pug | 30 ++-- views/projects_details.pug | 54 +++---- views/reply.pug | 112 ++++++------- views/templates/main.pug | 66 ++++---- views/uses.pug | 218 ++++++++++++------------- views/work.pug | 66 ++++---- 19 files changed, 927 insertions(+), 927 deletions(-) diff --git a/views/404.pug b/views/404.pug index d33bf36..0c57dcb 100644 --- a/views/404.pug +++ b/views/404.pug @@ -1,8 +1,8 @@ extends templates/main block content - h2 HTTP 404 - p - | This page could not be found... Go back to - a(href="/") yarmo.eu - | and try again! \ No newline at end of file + h2 HTTP 404 + p + | This page could not be found... Go back to + a(href="/") yarmo.eu + | and try again! \ No newline at end of file diff --git a/views/about.pug b/views/about.pug index fc990da..fb8d3ab 100644 --- a/views/about.pug +++ b/views/about.pug @@ -1,169 +1,169 @@ extends templates/main block content - header - h1 - | About Me - nav - | >> - a(href="/about") about me - nav - | Go to: - a(href="/") blog - | | - a(href="/notes") notes - | | - a(href="/feeds") feeds - | | - a(href="/now") now - | | - a(href="/uses") uses - | | - a(href="/work") work - | | - a(href="/music") music - | | - a(href="/pgp") PGP - | | - a(href="/contact") contact - - main - - include id - - h2 >> About me - - h3 Principles - ul - li The internet needs to be decentralized - li - a(href="https://publiccode.eu/") Public money? Public code! - li Open science benefits society - li Code documentation is essential - li - | Remove - a(href="https://en.wikipedia.org/wiki/Big_Four_tech_companies") GAFAM - | from one's life - - h3 Interests - ul - li Cryptography and decentralized identity - li Advancing and democratizing science - li Building and maintaining a homelab - li Statistics, machine learning - li Halo universe - li Making music - li Podcasts - - h3 Languages (spoken, written, read) - ul - li Dutch (native) - li English (+++) - li French (+++) - li Portuguese (+) - - h2 >> Science - p I have finished a PhD project in the field of Neurosciences. My research focused on the neuronal basis of directional hearing. + header + h1 + | About Me + nav + | >> + a(href="/about") about me + nav + | Go to: + a(href="/") blog + | | + a(href="/notes") notes + | | + a(href="/feeds") feeds + | | + a(href="/now") now + | | + a(href="/uses") uses + | | + a(href="/work") work + | | + a(href="/music") music + | | + a(href="/pgp") PGP + | | + a(href="/contact") contact + + main + + include id + + h2 >> About me + + h3 Principles + ul + li The internet needs to be decentralized + li + a(href="https://publiccode.eu/") Public money? Public code! + li Open science benefits society + li Code documentation is essential + li + | Remove + a(href="https://en.wikipedia.org/wiki/Big_Four_tech_companies") GAFAM + | from one's life + + h3 Interests + ul + li Cryptography and decentralized identity + li Advancing and democratizing science + li Building and maintaining a homelab + li Statistics, machine learning + li Halo universe + li Making music + li Podcasts + + h3 Languages (spoken, written, read) + ul + li Dutch (native) + li English (+++) + li French (+++) + li Portuguese (+) + + h2 >> Science + p I have finished a PhD project in the field of Neurosciences. My research focused on the neuronal basis of directional hearing. - h3 Skills - ul - li Experimental electrophysiology - li Histology - li Behavioral techniques - li Programming & data analysis - ul - li Data visualisation - li Fourier / signal processing - li Circular statistics - li Machine learning - li Database management (SQL & NoSQL) - - h3 Work experience - .wrapper-table - table.work-experience - thead - tr - th Years - th Name - th Location - tbody - tr - td 2015-2019 - td PhD in Neurosciences - td Erasmus MC, Rotterdam, The Netherlands - - h3 Academic record - .wrapper-table - table.academic-record - thead - tr - th Years - th Name - th Location - tbody - tr - td 2010-2013 - td Bachelor Biology - td Université Victor Segalen, Bordeaux, France - tr - td 2013-2015 - td Master Neurosciences & Neuropsychopharmacology - td Université Victor Segalen, Bordeaux, France - tr - td 2013-2015 - td Master Cellular & Molecular Biology - td Universidade de Coimbra, Portugal - tr - td 2015-2019 - td PhD in Neurosciences - td Erasmus MC, Rotterdam, The Netherlands - - h3 Publications - .wrapper-table - table.publications - thead - tr - th Years - th Authors - th Title - tbody - tr - td 2017 - td Arnau Busquets-Garcia, [...], Giovanni Marsicano - td - a(href="https://www.nature.com/articles/mp20174") Pregnenolone blocks cannabinoid-induced acute psychotic-like states in mice - - h2 >> Programming + h3 Skills + ul + li Experimental electrophysiology + li Histology + li Behavioral techniques + li Programming & data analysis + ul + li Data visualisation + li Fourier / signal processing + li Circular statistics + li Machine learning + li Database management (SQL & NoSQL) + + h3 Work experience + .wrapper-table + table.work-experience + thead + tr + th Years + th Name + th Location + tbody + tr + td 2015-2019 + td PhD in Neurosciences + td Erasmus MC, Rotterdam, The Netherlands + + h3 Academic record + .wrapper-table + table.academic-record + thead + tr + th Years + th Name + th Location + tbody + tr + td 2010-2013 + td Bachelor Biology + td Université Victor Segalen, Bordeaux, France + tr + td 2013-2015 + td Master Neurosciences & Neuropsychopharmacology + td Université Victor Segalen, Bordeaux, France + tr + td 2013-2015 + td Master Cellular & Molecular Biology + td Universidade de Coimbra, Portugal + tr + td 2015-2019 + td PhD in Neurosciences + td Erasmus MC, Rotterdam, The Netherlands + + h3 Publications + .wrapper-table + table.publications + thead + tr + th Years + th Authors + th Title + tbody + tr + td 2017 + td Arnau Busquets-Garcia, [...], Giovanni Marsicano + td + a(href="https://www.nature.com/articles/mp20174") Pregnenolone blocks cannabinoid-induced acute psychotic-like states in mice + + h2 >> Programming - h3 Languages used - ul - li Matlab / Octave - li Python / R - li HTML / JS / (S)CSS - li PHP / NodeJS - li SQL / NoSQL (cypher) + h3 Languages used + ul + li Matlab / Octave + li Python / R + li HTML / JS / (S)CSS + li PHP / NodeJS + li SQL / NoSQL (cypher) - h3 Experience (science) - ul - li Data visualisation - li Fourier / signal processing - li Circular statistics - li Machine learning + h3 Experience (science) + ul + li Data visualisation + li Fourier / signal processing + li Circular statistics + li Machine learning - h3 Experience (hobbies) - ul - li Homelab / self-hosting - li Web design - li Raspberry Pi / Arduino - li Home automation - li Cryptography - - h3 Open source contributions - p - | Go to: - a(href="/foss") FOSS - - h2 >> Music - p - | Go to: - a(href="/music") music + h3 Experience (hobbies) + ul + li Homelab / self-hosting + li Web design + li Raspberry Pi / Arduino + li Home automation + li Cryptography + + h3 Open source contributions + p + | Go to: + a(href="/foss") FOSS + + h2 >> Music + p + | Go to: + a(href="/music") music diff --git a/views/blog.pug b/views/blog.pug index a51dcd6..58ee72e 100644 --- a/views/blog.pug +++ b/views/blog.pug @@ -1,41 +1,41 @@ extends templates/main mixin entry(item) - article.longform_list__item.h-entry - p - a(href=item['urlrel']).p-name.u-url !{item['title']} - br - | Posted on - time(datetime=item['date']).dt-published !{item['date_formatted']} + article.longform_list__item.h-entry + p + a(href=item['urlrel']).p-name.u-url !{item['title']} + br + | Posted on + time(datetime=item['date']).dt-published !{item['date_formatted']} block content - .h-card - header - //nav - a(href="/about") about me - | > blog - h1 - | Yarmo's blog - nav - | >> - a(href="/") blog - nav - | Go to: - a(href="/about") about me - | | - a(href="/notes") notes - | | - a(href="/blogroll") blogroll - | | - a(href="/feeds") feeds - | | - a(href="/contact") contact - - main - - div(style="display:none") - include id - - .longform_list.h-feed - each item in blogPosts - +entry(item) + .h-card + header + //nav + a(href="/about") about me + | > blog + h1 + | Yarmo's blog + nav + | >> + a(href="/") blog + nav + | Go to: + a(href="/about") about me + | | + a(href="/notes") notes + | | + a(href="/blogroll") blogroll + | | + a(href="/feeds") feeds + | | + a(href="/contact") contact + + main + + div(style="display:none") + include id + + .longform_list.h-feed + each item in blogPosts + +entry(item) diff --git a/views/blogroll.pug b/views/blogroll.pug index c4fa75a..a70c017 100644 --- a/views/blogroll.pug +++ b/views/blogroll.pug @@ -1,26 +1,26 @@ extends templates/main block content - header - h1 - | Blogroll - nav - | >> - a(href="/about") about me - | > - a(href="/blogroll") blogroll - - main - a(href="https://ar.al/") Aral Balkan - br - a(href="https://write.privacytools.io/freddy/") Freddy's Ramblings - br - a(href="https://www.garron.blog/posts/") Guillermo Garron - br - a(href="https://goel.io/") Karan Goel - br - a(href="https://kevq.uk/") Kev Quirk - br - a(href="https://mikestone.me/") Mike Stone - br - a(href="https://degruchy.org/") Nathan DeGruchy + header + h1 + | Blogroll + nav + | >> + a(href="/about") about me + | > + a(href="/blogroll") blogroll + + main + a(href="https://ar.al/") Aral Balkan + br + a(href="https://write.privacytools.io/freddy/") Freddy's Ramblings + br + a(href="https://www.garron.blog/posts/") Guillermo Garron + br + a(href="https://goel.io/") Karan Goel + br + a(href="https://kevq.uk/") Kev Quirk + br + a(href="https://mikestone.me/") Mike Stone + br + a(href="https://degruchy.org/") Nathan DeGruchy diff --git a/views/contact.pug b/views/contact.pug index 375aa46..0ce2ce4 100644 --- a/views/contact.pug +++ b/views/contact.pug @@ -1,147 +1,147 @@ extends templates/main block content - header - h1 - | Contact me - nav - | >> - a(href="/about") about me - | > - a(href="/contact") contact - - main - h2 >> Online presence - - .wrapper-table - table - tbody - tr - td Fediverse - td - a(href="https://fosstodon.org/@yarmo" rel="me") @yarmo@fosstodon.org - tr - td Lobste.rs - td - a(href="https://lobste.rs/u/yarmo" rel="me") yarmo - tr - td Codeberg - td - a(href="https://codeberg.org/yarmo" rel="me") @yarmo - tr - td GitLab - td - a(href="https://gitlab.com/yarmo" rel="me") @yarmo - tr - td Github - td - a(href="https://github.com/YarmoM" rel="me") @YarmoM - - h2 >> Instant messaging - - .wrapper-table - table - tbody - tr - td Mail * - td - a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu - tr - td Delta Chat ** - td - a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu - tr - td XMPP ** - td - a(href="xmpp:yarmo@404.city") yarmo@404.city - tr - td Matrix ** - td - a(href="https://matrix.to/#/@yarmo:matrix.org") @yarmo:matrix.org - tr - td Wire ** - td @yarmo - tr - td Briar ** - td - a(href="briar://acdxuw4lym5l77ezsonbswj3aerwphckgnnrskokxw3t3mz3ncxq4" rel="me") acdxuw4lym5l77ezsonbswj3aerwphckgnnrskokxw3t3mz3ncxq4 - tr - td Session * - td 0526f4bf4feb46f61b3382b317276ec2e207d75b11c995d41a78c1f4f2cefbcd5f - tr - td Tox * - td AD4EF6D540949E55A666D8D7BF58EF5422A91F0C99EE334ADBB7123189C4C17A640915B3CC64 - tr - td Signal * - td ask me on any platform above - tr - td Telegram - td - a(href="https://t.me/yarmom" rel="me") YarmoM - tr - td Manyverse - td ask me on any platform above - - p - | ** Excellent for secure messaging - br - | * Adequate for secure messaging - - h2 >> How to send an encrypted message - - p If you wish to send me an encrypted message and make sure that I and only I can read it, use any of the instant messaging services marked with ** (preferred) or * from the list above. - - p If you do not have accounts on any of the services above and/or prefer email, use any of the two guides below. + header + h1 + | Contact me + nav + | >> + a(href="/about") about me + | > + a(href="/contact") contact + + main + h2 >> Online presence + + .wrapper-table + table + tbody + tr + td Fediverse + td + a(href="https://fosstodon.org/@yarmo" rel="me") @yarmo@fosstodon.org + tr + td Lobste.rs + td + a(href="https://lobste.rs/u/yarmo" rel="me") yarmo + tr + td Codeberg + td + a(href="https://codeberg.org/yarmo" rel="me") @yarmo + tr + td GitLab + td + a(href="https://gitlab.com/yarmo" rel="me") @yarmo + tr + td Github + td + a(href="https://github.com/YarmoM" rel="me") @YarmoM + + h2 >> Instant messaging + + .wrapper-table + table + tbody + tr + td Mail * + td + a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu + tr + td Delta Chat ** + td + a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu + tr + td XMPP ** + td + a(href="xmpp:yarmo@404.city") yarmo@404.city + tr + td Matrix ** + td + a(href="https://matrix.to/#/@yarmo:matrix.org") @yarmo:matrix.org + tr + td Wire ** + td @yarmo + tr + td Briar ** + td + a(href="briar://acdxuw4lym5l77ezsonbswj3aerwphckgnnrskokxw3t3mz3ncxq4" rel="me") acdxuw4lym5l77ezsonbswj3aerwphckgnnrskokxw3t3mz3ncxq4 + tr + td Session * + td 0526f4bf4feb46f61b3382b317276ec2e207d75b11c995d41a78c1f4f2cefbcd5f + tr + td Tox * + td AD4EF6D540949E55A666D8D7BF58EF5422A91F0C99EE334ADBB7123189C4C17A640915B3CC64 + tr + td Signal * + td ask me on any platform above + tr + td Telegram + td + a(href="https://t.me/yarmom" rel="me") YarmoM + tr + td Manyverse + td ask me on any platform above + + p + | ** Excellent for secure messaging + br + | * Adequate for secure messaging + + h2 >> How to send an encrypted message + + p If you wish to send me an encrypted message and make sure that I and only I can read it, use any of the instant messaging services marked with ** (preferred) or * from the list above. + + p If you do not have accounts on any of the services above and/or prefer email, use any of the two guides below. - h3#pgp-easy Using Keyoxide (easy) + h3#pgp-easy Using Keyoxide (easy) - ol - li - | Visit my - a(href="https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d", title="Keyoxide") Keyoxide profile - | . - li Press the encrypt message link at the bottom of the page. - li Write the message in the big textarea. - li Press the ENCRYPT MESSAGE button and copy the encrypted content. - li - | Send an email with the encrypted content to - a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu - | . + ol + li + | Visit my + a(href="https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d", title="Keyoxide") Keyoxide profile + | . + li Press the encrypt message link at the bottom of the page. + li Write the message in the big textarea. + li Press the ENCRYPT MESSAGE button and copy the encrypted content. + li + | Send an email with the encrypted content to + a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu + | . - h3#pgp-advanced Using the Kleopatra software (advanced) - - ol - li - | Download my - a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", title="PGP public key") public key - | . - li - | Download Kleopatra ( - a(href="https://www.openpgp.org/software/kleopatra/") Linux - | - - a(href="https://www.gpg4win.org/get-gpg4win.html") Windows - | - - a(href="https://chocolatey.org/packages/Gpg4win") Chocolatey - | ) and run it. - li Press Import and locate the file downloaded in the first step. - li You may be asked to "Certify" the public key. This is optional (read below) and can be skipped. - li Go to the Notepad section. - li After you are done writing your message, go to the Recipients tab and choose Yarmo Mackenbach in the Encrypt for others: field. - li Return to the Notepad tab and press the Encrypt Notepad button. - li - | Copy the entire message that is now displayed and send it to - a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu - | . - - p - | "Certifying" my key via Kleopatra requires you to make your own keypair. To manually verify the validity of my public key, right-click on my key, press on Details and make sure the fingerprint matches my - a(href="/pgp") PGP signature - | . - - h3 Getting an encrypted response + h3#pgp-advanced Using the Kleopatra software (advanced) + + ol + li + | Download my + a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", title="PGP public key") public key + | . + li + | Download Kleopatra ( + a(href="https://www.openpgp.org/software/kleopatra/") Linux + | - + a(href="https://www.gpg4win.org/get-gpg4win.html") Windows + | - + a(href="https://chocolatey.org/packages/Gpg4win") Chocolatey + | ) and run it. + li Press Import and locate the file downloaded in the first step. + li You may be asked to "Certify" the public key. This is optional (read below) and can be skipped. + li Go to the Notepad section. + li After you are done writing your message, go to the Recipients tab and choose Yarmo Mackenbach in the Encrypt for others: field. + li Return to the Notepad tab and press the Encrypt Notepad button. + li + | Copy the entire message that is now displayed and send it to + a(href="mailto:yarmo@yarmo.eu") yarmo@yarmo.eu + | . + + p + | "Certifying" my key via Kleopatra requires you to make your own keypair. To manually verify the validity of my public key, right-click on my key, press on Details and make sure the fingerprint matches my + a(href="/pgp") PGP signature + | . + + h3 Getting an encrypted response - p If you would like to get an encrypted response from me, please include the public key of your personal keypair or upload it to a key server. - - p If you do not have a personal keypair yet, both Mailvelope and Kleopatra allow you to generate a new keypair. The public part of your keypair can be used by anyone to encrypt their messages to you, and the secret part MUST REMAIN SECRET and can be used by you AND ONLY YOU to decrypt those messages. - - p Please note that dealing with PGP keys is advanced stuff: if you are not comfortable with PGP, let's talk using any of the encrypted instant messaging tools listed above. + p If you would like to get an encrypted response from me, please include the public key of your personal keypair or upload it to a key server. + + p If you do not have a personal keypair yet, both Mailvelope and Kleopatra allow you to generate a new keypair. The public part of your keypair can be used by anyone to encrypt their messages to you, and the secret part MUST REMAIN SECRET and can be used by you AND ONLY YOU to decrypt those messages. + + p Please note that dealing with PGP keys is advanced stuff: if you are not comfortable with PGP, let's talk using any of the encrypted instant messaging tools listed above. diff --git a/views/feeds.pug b/views/feeds.pug index e397a14..369358d 100644 --- a/views/feeds.pug +++ b/views/feeds.pug @@ -1,20 +1,20 @@ extends templates/main block content - header - h1 - | Feeds - nav - | >> - a(href="/about") about me - | > - a(href="/feeds") feeds - - main - ul - li - a(href="/rss/all") RSS blog and notes - li - a(href="/rss/blog") RSS blog - li - a(href="/rss/notes") RSS notes + header + h1 + | Feeds + nav + | >> + a(href="/about") about me + | > + a(href="/feeds") feeds + + main + ul + li + a(href="/rss/all") RSS blog and notes + li + a(href="/rss/blog") RSS blog + li + a(href="/rss/notes") RSS notes diff --git a/views/foss.pug b/views/foss.pug index 3adaca4..994a26e 100644 --- a/views/foss.pug +++ b/views/foss.pug @@ -1,42 +1,42 @@ extends templates/main mixin foss_contribution($item) - p - a(href="{$item['url-repo']}") !{$item['repo']} - | — - a(href="{$item['url-item']}") #!{$item['id']} - br - | !{$item['title']} - + p + a(href="{$item['url-repo']}") !{$item['repo']} + | — + a(href="{$item['url-item']}") #!{$item['id']} + br + | !{$item['title']} + block content - header - nav - a(href="/about") about me - | > foss - h1 - | FOSS - - main - h2 >> VCS accounts - - .wrapper-table - table - tbody - tr - td Codeberg - td - a(href="https://codeberg.org/yarmo" rel="me") @yarmo - tr - td GitLab - td - a(href="https://gitlab.com/yarmo" rel="me") @yarmo - tr - td Github - td - a(href="https://github.com/YarmoM" rel="me") @YarmoM - - h2 >> Contributions - - each $item in $foss - +foss_contribution($item) - + header + nav + a(href="/about") about me + | > foss + h1 + | FOSS + + main + h2 >> VCS accounts + + .wrapper-table + table + tbody + tr + td Codeberg + td + a(href="https://codeberg.org/yarmo" rel="me") @yarmo + tr + td GitLab + td + a(href="https://gitlab.com/yarmo" rel="me") @yarmo + tr + td Github + td + a(href="https://github.com/YarmoM" rel="me") @YarmoM + + h2 >> Contributions + + each $item in $foss + +foss_contribution($item) + diff --git a/views/id.pug b/views/id.pug index dc2fb4b..92d79a6 100644 --- a/views/id.pug +++ b/views/id.pug @@ -1,47 +1,47 @@ .id-card - img(src="/static/img/profile.png", alt="Yarmo's profile picture").profile-picture.u-photo - h1 - a(href="https://yarmo.eu", rel="me", title="yarmo.eu").u-url.u-uid - span(style="display:none").p-honorific-prefix Mr. - span.p-name - span.p-given-name Yarmo - | - span.p-additional-name Mackenbach - br - p.p-note - | Developer of - a(href="https://keyoxide.org") Keyoxide.org - | . - br - | Finished a PhD in neurosciences. - p - | Pronouns: - a(href="https://pronoun.is/he").u-pronoun he/him/his - p - | PGP: - a(href="https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d", rel="me", title="Keyoxide profile").u-url Keyoxide profile - | / - a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", rel="pgpkey publickey authn", type="text/plain", title="PGP public key").u-key public.asc - | / - a(href="/static/img/qr_fp.png", title="PGP fingerprint QR") QR - p - | Topics: - | #FOSS - | #privacy - | #encryption - | #decentralization - | #music - p - | Links: - a(href="mailto:yarmo@yarmo.eu", rel="me", title="Email").u-email Email - | / - a(href="xmpp:yarmo@snopyta.org", rel="me", title="XMPP").u-xmpp XMPP - | / - a(href="https://fosstodon.org/@yarmo", rel="me", title="Fediverse").u-url Fediverse - | / - a(href="https://git.yarmo.eu/yarmo", rel="me", title="Gitea").u-url Gitea - p - | Location: - span.p-country-name The Netherlands - pre(style="display:none").key - include ../keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc + img(src="/static/img/profile.png", alt="Yarmo's profile picture").profile-picture.u-photo + h1 + a(href="https://yarmo.eu", rel="me", title="yarmo.eu").u-url.u-uid + span(style="display:none").p-honorific-prefix Mr. + span.p-name + span.p-given-name Yarmo + | + span.p-additional-name Mackenbach + br + p.p-note + | Developer of + a(href="https://keyoxide.org") Keyoxide.org + | . + br + | Finished a PhD in neurosciences. + p + | Pronouns: + a(href="https://pronoun.is/he").u-pronoun he/him/his + p + | PGP: + a(href="https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d", rel="me", title="Keyoxide profile").u-url Keyoxide profile + | / + a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", rel="pgpkey publickey authn", type="text/plain", title="PGP public key").u-key public.asc + | / + a(href="/static/img/qr_fp.png", title="PGP fingerprint QR") QR + p + | Topics: + | #FOSS + | #privacy + | #encryption + | #decentralization + | #music + p + | Links: + a(href="mailto:yarmo@yarmo.eu", rel="me", title="Email").u-email Email + | / + a(href="xmpp:yarmo@snopyta.org", rel="me", title="XMPP").u-xmpp XMPP + | / + a(href="https://fosstodon.org/@yarmo", rel="me", title="Fediverse").u-url Fediverse + | / + a(href="https://git.yarmo.eu/yarmo", rel="me", title="Gitea").u-url Gitea + p + | Location: + span.p-country-name The Netherlands + pre(style="display:none").key + include ../keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc diff --git a/views/music.pug b/views/music.pug index a23da9b..5ccfbb0 100644 --- a/views/music.pug +++ b/views/music.pug @@ -1,50 +1,50 @@ extends templates/main block content - header - h1 Yarmo's music - nav - | >> - a(href="/about") about me - | > - a(href="/music") music - nav - | Go to: - a(href="/vinyl") vinyl + header + h1 Yarmo's music + nav + | >> + a(href="/about") about me + | > + a(href="/music") music + nav + | Go to: + a(href="/vinyl") vinyl + + main + h3 Instruments + ul + li Piano / keyboards + li Organs + li Synths - main - h3 Instruments - ul - li Piano / keyboards - li Organs - li Synths - - h3 Releases - .wrapper-table - table.music - thead - tr - th Years - th Band - th Title - tbody - tr - td 2013 - td Sir Jupiter - td - a(href="https://song.link/album/nl/i/979132997") Sir Jupiter - tr - td 2015 - td Sir Jupiter - td - a(href="https://song.link/album/nl/i/1041392608") EP Roots - tr - td 2016 - td Sir Jupiter - td - a(href="https://song.link/album/nl/i/1151887625") EP Wings - tr - td 2018 - td Sir Jupiter - td - a(href="https://song.link/album/nl/i/1454734101") EP Covered In Snow + h3 Releases + .wrapper-table + table.music + thead + tr + th Years + th Band + th Title + tbody + tr + td 2013 + td Sir Jupiter + td + a(href="https://song.link/album/nl/i/979132997") Sir Jupiter + tr + td 2015 + td Sir Jupiter + td + a(href="https://song.link/album/nl/i/1041392608") EP Roots + tr + td 2016 + td Sir Jupiter + td + a(href="https://song.link/album/nl/i/1151887625") EP Wings + tr + td 2018 + td Sir Jupiter + td + a(href="https://song.link/album/nl/i/1454734101") EP Covered In Snow diff --git a/views/notes.pug b/views/notes.pug index a8c5d98..f903143 100644 --- a/views/notes.pug +++ b/views/notes.pug @@ -1,33 +1,33 @@ extends templates/main mixin entry(item) - article.longform_list__item.h-entry - p - a(href=item['urlrel']).p-nameu-url !{item['title']} - br - | Posted on - time(datetime=item['date']).dt-published !{item['date_formatted']} + article.longform_list__item.h-entry + p + a(href=item['urlrel']).p-nameu-url !{item['title']} + br + | Posted on + time(datetime=item['date']).dt-published !{item['date_formatted']} block content - header - //nav - a(href="/about") about me - | > notes - h1 Yarmo's notes - nav - | >> - a(href="/notes") notes - nav - | Go to: - a(href="/about") about me - | | - a(href="/") blog - | | - a(href="/feeds") feeds - | | - a(href="/contact") contact - - main - .longform_list - each item in notes - +entry(item) + header + //nav + a(href="/about") about me + | > notes + h1 Yarmo's notes + nav + | >> + a(href="/notes") notes + nav + | Go to: + a(href="/about") about me + | | + a(href="/") blog + | | + a(href="/feeds") feeds + | | + a(href="/contact") contact + + main + .longform_list + each item in notes + +entry(item) diff --git a/views/now.pug b/views/now.pug index 4694626..4cd6887 100644 --- a/views/now.pug +++ b/views/now.pug @@ -1,26 +1,26 @@ extends templates/main block content - header - h1 - | Now - nav - | >> - a(href="/about") about me - | > - a(href="/now") now - - main - h3 Working on - ul - li - a(href="https://keyoxide.org") Keyoxide.org - li finding a job - li finishing a scientific publication - li numerous FOSS projects - li new music - - h3 Enjoying - ul - li room renovations - li modular synthesis + header + h1 + | Now + nav + | >> + a(href="/about") about me + | > + a(href="/now") now + + main + h3 Working on + ul + li + a(href="https://keyoxide.org") Keyoxide.org + li finding a job + li finishing a scientific publication + li numerous FOSS projects + li new music + + h3 Enjoying + ul + li room renovations + li modular synthesis diff --git a/views/pgp.pug b/views/pgp.pug index 85b1af4..7304740 100644 --- a/views/pgp.pug +++ b/views/pgp.pug @@ -1,30 +1,30 @@ extends templates/main block content - header - h1 - | PGP public key - nav - | >> - a(href="/about") about me - | > - a(href="/pgp") pgp + header + h1 + | PGP public key + nav + | >> + a(href="/about") about me + | > + a(href="/pgp") pgp + + main + h3#pgp-fingerprint Fingerprint + p 9f0048ac0b23301e1f77e994909f6bd6f80f485d - main - h3#pgp-fingerprint Fingerprint - p 9f0048ac0b23301e1f77e994909f6bd6f80f485d - - h3 Key servers - p - a(href="https://keys.openpgp.org/") OpenPGP key server - - h3 Files - p - a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp", rel="pgpkey", type="application/pgp-keys", title="PGP (binary)") Binary format - br - a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", rel="pgpkey", type="text/plain", title="PGP (text)") Text format - - h3#pgp-public-key Plaintext - pre.select-all - code - include ../keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc + h3 Key servers + p + a(href="https://keys.openpgp.org/") OpenPGP key server + + h3 Files + p + a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.pgp", rel="pgpkey", type="application/pgp-keys", title="PGP (binary)") Binary format + br + a(href="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", download="/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc", rel="pgpkey", type="text/plain", title="PGP (text)") Text format + + h3#pgp-public-key Plaintext + pre.select-all + code + include ../keys/9F0048AC0B23301E1F77E994909F6BD6F80F485D.asc diff --git a/views/post.pug b/views/post.pug index 1fa9cd5..e7e9679 100644 --- a/views/post.pug +++ b/views/post.pug @@ -1,72 +1,72 @@ extends templates/main mixin webmention(item) - if (!('type' in item)) - p - if ('title' in item) - a(href=item.source) !{item.title} - else - a(href=item.source) !{item.source} - if ('author_name' in item) - | by !{item.author_name} - if ('date' in item) - | on !{item.date} - if ('time' in item) - | at !{item.time} UTC - else if (item.type == "comment") - .comment - p.quote - if ('title' in item) - strong !{item.title} - br - if ('content' in item) - | !{item.content} - p.sub - a(href=item.source) Commented - if ('author_name' in item) - | by !{item.author_name} - if ('date' in item) - | on !{item.date} - if ('time' in item) - | at !{item.time} UTC + if (!('type' in item)) + p + if ('title' in item) + a(href=item.source) !{item.title} + else + a(href=item.source) !{item.source} + if ('author_name' in item) + | by !{item.author_name} + if ('date' in item) + | on !{item.date} + if ('time' in item) + | at !{item.time} UTC + else if (item.type == "comment") + .comment + p.quote + if ('title' in item) + strong !{item.title} + br + if ('content' in item) + | !{item.content} + p.sub + a(href=item.source) Commented + if ('author_name' in item) + | by !{item.author_name} + if ('date' in item) + | on !{item.date} + if ('time' in item) + | at !{item.time} UTC mixin discussionLink(item) - p - a(href=item) !{item} + p + a(href=item) !{item} block content - header - nav - | >> - if post.type == 'blog' - a(href="/") blog - if post.type == 'note' - a(href="/notes") notes - | > - a(href=post.url)= post.slug - - main - article.longform.h-entry - h1.p-name !{post.title} - p.longform__header - | Posted on - a(href=post.url datetime="{post.date}").u-url.dt-published !{post.date_formatted} - | by - a(href="/" rel="author").p-author.h-card !{post.author} - - .longform__content.e-content - | !{post.content} + header + nav + | >> + if post.type == 'blog' + a(href="/") blog + if post.type == 'note' + a(href="/notes") notes + | > + a(href=post.url)= post.slug + + main + article.longform.h-entry + h1.p-name !{post.title} + p.longform__header + | Posted on + a(href=post.url datetime="{post.date}").u-url.dt-published !{post.date_formatted} + | by + a(href="/" rel="author").p-author.h-card !{post.author} + + .longform__content.e-content + | !{post.content} + + if ('discussion' in post && post.discussion) + .discussion.subsection + h2 Join the discussion + each item in post.discussion + +discussionLink(item) - if ('discussion' in post && post.discussion) - .discussion.subsection - h2 Join the discussion - each item in post.discussion - +discussionLink(item) - - .webmentions.subsection - h2 Webmentions - if post.hasWebmentions - each item in post.webmentions - +webmention(item) - else - p This post has not been mentioned yet. + .webmentions.subsection + h2 Webmentions + if post.hasWebmentions + each item in post.webmentions + +webmention(item) + else + p This post has not been mentioned yet. diff --git a/views/projects.pug b/views/projects.pug index 7d07df8..24e48c6 100644 --- a/views/projects.pug +++ b/views/projects.pug @@ -1,20 +1,20 @@ extends templates/main mixin entry($item) - article.longform_list__item - p - a(href="{$item['urlrel']}") !{$item['title']} - br - | Status: !{$item['status']} + article.longform_list__item + p + a(href="{$item['urlrel']}") !{$item['title']} + br + | Status: !{$item['status']} block content - header - nav - a(href="/about") about me - | > projects - h1 Yarmo's projects - - main - .longform_list - each $item in $projects - +entry($item) + header + nav + a(href="/about") about me + | > projects + h1 Yarmo's projects + + main + .longform_list + each $item in $projects + +entry($item) diff --git a/views/projects_details.pug b/views/projects_details.pug index e97daa8..cbc58ba 100644 --- a/views/projects_details.pug +++ b/views/projects_details.pug @@ -1,32 +1,32 @@ extends templates/main mixin webmention($item) - p - a(href="{$item['source']}") !{$item['title']} - | by !{$item['author_name']} on !{$item['date']} at !{$item['time']} + p + a(href="{$item['source']}") !{$item['title']} + | by !{$item['author_name']} on !{$item['date']} at !{$item['time']} block content - header - nav - a(href="/about") about me - | > - a(href="/projects") projects - | > !{$project['slug']} - - main - article.longform - h1 !{$project['title']} - p - | Got an idea or a comment? - a(href="/contact") Feel free to contact me! - p.longform__header - .longform__content - | !{$project['content']} - - .webmentions.subsection - h2 Webmentions - if ($project['hasWebmentions']) - each $item in $project["webmentions"] - +webmention($item) - else - p This project has not been mentioned yet. + header + nav + a(href="/about") about me + | > + a(href="/projects") projects + | > !{$project['slug']} + + main + article.longform + h1 !{$project['title']} + p + | Got an idea or a comment? + a(href="/contact") Feel free to contact me! + p.longform__header + .longform__content + | !{$project['content']} + + .webmentions.subsection + h2 Webmentions + if ($project['hasWebmentions']) + each $item in $project["webmentions"] + +webmention($item) + else + p This project has not been mentioned yet. diff --git a/views/reply.pug b/views/reply.pug index ab80420..688e35a 100644 --- a/views/reply.pug +++ b/views/reply.pug @@ -1,61 +1,61 @@ extends templates/main mixin webmention($item) - if (!array_key_exists('type', $item)) - p - if (array_key_exists('title', $item)) - a(href="{$item['source']}") !{$item['title']} - else - a(href="{$item['source']}") !{$item['source']} - if (array_key_exists('author_name', $item)) - | by !{$item['author_name']} - if (array_key_exists('date', $item)) - | on !{$item['date']} - if (array_key_exists('time', $item)) - | at !{$item['time']} UTC - else if ($item['type'] == "comment") - .comment - p.quote - if (array_key_exists('title', $item)) - strong !{$item['title']} - br - if (array_key_exists('content', $item)) - | !{$item['content']} - p.sub - a(href="{$item['source']}") Commented - if (array_key_exists('author_name', $item)) - | by !{$item['author_name']} - if (array_key_exists('date', $item)) - | on !{$item['date']} - if (array_key_exists('time', $item)) - | at !{$item['time']} UTC + if (!array_key_exists('type', $item)) + p + if (array_key_exists('title', $item)) + a(href="{$item['source']}") !{$item['title']} + else + a(href="{$item['source']}") !{$item['source']} + if (array_key_exists('author_name', $item)) + | by !{$item['author_name']} + if (array_key_exists('date', $item)) + | on !{$item['date']} + if (array_key_exists('time', $item)) + | at !{$item['time']} UTC + else if ($item['type'] == "comment") + .comment + p.quote + if (array_key_exists('title', $item)) + strong !{$item['title']} + br + if (array_key_exists('content', $item)) + | !{$item['content']} + p.sub + a(href="{$item['source']}") Commented + if (array_key_exists('author_name', $item)) + | by !{$item['author_name']} + if (array_key_exists('date', $item)) + | on !{$item['date']} + if (array_key_exists('time', $item)) + | at !{$item['time']} UTC block content - header - nav - a(href="/about") about me - | > !{$reply['slug']} - - main - article.longform.h-entry - h1.p-name !{$reply['title']} - p.longform__header - | Posted on - a(href="{$reply['url']}" datetime="{$reply['date']}").u-url.dt-published !{$reply['date_formatted']} - | by - a(href="/" rel="author").p-author.h-card !{$reply['author']} - - .longform__content.e-content - | Reply to - a(href="{$reply['reply-url']}").in-reply-to !{$reply['reply-title']} - | : - br - | !{$reply['content']} - - .webmentions.subsection - h2 Webmentions - if ($reply['hasWebmentions']) - each $item in $reply["webmentions"] - +webmention($item) - else - p This post has not been mentioned yet. + header + nav + a(href="/about") about me + | > !{$reply['slug']} + + main + article.longform.h-entry + h1.p-name !{$reply['title']} + p.longform__header + | Posted on + a(href="{$reply['url']}" datetime="{$reply['date']}").u-url.dt-published !{$reply['date_formatted']} + | by + a(href="/" rel="author").p-author.h-card !{$reply['author']} + + .longform__content.e-content + | Reply to + a(href="{$reply['reply-url']}").in-reply-to !{$reply['reply-title']} + | : + br + | !{$reply['content']} + + .webmentions.subsection + h2 Webmentions + if ($reply['hasWebmentions']) + each $item in $reply["webmentions"] + +webmention($item) + else + p This post has not been mentioned yet. diff --git a/views/templates/main.pug b/views/templates/main.pug index a7e61be..2e92d56 100644 --- a/views/templates/main.pug +++ b/views/templates/main.pug @@ -1,35 +1,35 @@ html - head - meta(http-equiv="Content-Type", content="text/html;charset=UTF-8") - meta(name="viewport", content="width=device-width, initial-scale=1.0") - meta(name="theme-color", content="#4ab4ab") - meta(http-equiv="X-UA-Compatible", content="ie=edge") - title #{title} - link(rel="stylesheet", href="/static/dank-mono.css") - link(rel="stylesheet", href="/static/norm.css") - link(rel="stylesheet", href="/static/style.css") - link(rel="shortcut icon", href="/favicon.png") - link(rel="alternate", href="/rss/all", title="RSS blog feed for yarmo.eu", type="application/rss+xml") - link(rel="webmention", href="https://webm.yarmo.eu/receive") - script(asyc, defer, data-domain="yarmo.eu", src="https://plausible.io/js/plausible.js") - body - .container - block content + head + meta(http-equiv="Content-Type", content="text/html;charset=UTF-8") + meta(name="viewport", content="width=device-width, initial-scale=1.0") + meta(name="theme-color", content="#4ab4ab") + meta(http-equiv="X-UA-Compatible", content="ie=edge") + title #{title} + link(rel="stylesheet", href="/static/dank-mono.css") + link(rel="stylesheet", href="/static/norm.css") + link(rel="stylesheet", href="/static/style.css") + link(rel="shortcut icon", href="/favicon.png") + link(rel="alternate", href="/rss/all", title="RSS blog feed for yarmo.eu", type="application/rss+xml") + link(rel="webmention", href="https://webm.yarmo.eu/receive") + script(asyc, defer, data-domain="yarmo.eu", src="https://plausible.io/js/plausible.js") + body + .container + block content - footer - p - | Ads: no. - br - | Analytics: - a(href="https://plausible.io") Plausible - |. - br - | Open source: - a(href="https://git.yarmo.eu/yarmo/yarmo.eu") source code - | and - a(href="https://drone.yarmo.eu/yarmo/yarmo.eu/") CI/CD pipelines - |. - br - | All content licensed under - a(href="https://creativecommons.org/licenses/by-nc-sa/4.0/") CC BY-NC-SA 4.0 - | unless otherwise stated. + footer + p + | Ads: no. + br + | Analytics: + a(href="https://plausible.io") Plausible + |. + br + | Open source: + a(href="https://git.yarmo.eu/yarmo/yarmo.eu") source code + | and + a(href="https://drone.yarmo.eu/yarmo/yarmo.eu/") CI/CD pipelines + |. + br + | All content licensed under + a(href="https://creativecommons.org/licenses/by-nc-sa/4.0/") CC BY-NC-SA 4.0 + | unless otherwise stated. diff --git a/views/uses.pug b/views/uses.pug index 8597b2d..2bc3547 100644 --- a/views/uses.pug +++ b/views/uses.pug @@ -1,114 +1,114 @@ extends templates/main block content - header - h1 - | Uses - nav - | >> - a(href="/about") about me - | > - a(href="/uses") uses + header + h1 + | Uses + nav + | >> + a(href="/about") about me + | > + a(href="/uses") uses + + main + h2 Hardware - main - h2 Hardware - + ul + li Main dev computer + ul + li MODEL: custom built + li CPU: AMD Ryzen 5 3600 + li GPU: AMD RX580 + li RAM: 16GB + li OS: Solus & W10 + li Homelab + ul + li MODEL: Intel NUC8i5BEK + li CPU: Intel Core i5-8259U + li RAM: 16GB + li OS: Ubuntu 18.04 + li Laptop + ul + li MODEL: Lenovo Thinkpad x201i + li CPU: Intel Core i3-330M + li OS: Solus + li Phone + ul + li MODEL: OnePlus 5T + li OS: LineageOS + li Network + ul + li + a(href="https://www.asus.com/Networking/Blue-Cave/") ASUS Blue Cave + li HiFi + ul + li + a(href="https://www.project-audio.com/en/product/primary-e/") Pro-Ject Primary E + li + a(href="https://www.wharfedale.co.uk/diamond-11-2/") Wharfedale Diamond 11.2 + li Music + ul + li + a(href="https://usa.yamaha.com/products/proaudio/speakers/hs_series/index.html") Yamaha HS8 + li + a(href="https://www.zoom.co.jp/products/multi-track-recorder/r16-recorder-interface-controller") Zoom R16 + li + a(href="https://www.nordkeyboards.com/products/nord-electro-5") Nord Electro 5D + li + a(href="https://www.arturia.com/microbrute-se/overview") Arturia Minibrute SE Pastel Orange + li + a(href="https://www.arturia.com/drumbrute/overview") Arturia DrumBrute + li Custom modular synth ul - li Main dev computer - ul - li MODEL: custom built - li CPU: AMD Ryzen 5 3600 - li GPU: AMD RX580 - li RAM: 16GB - li OS: Solus & W10 - li Homelab - ul - li MODEL: Intel NUC8i5BEK - li CPU: Intel Core i5-8259U - li RAM: 16GB - li OS: Ubuntu 18.04 - li Laptop - ul - li MODEL: Lenovo Thinkpad x201i - li CPU: Intel Core i3-330M - li OS: Solus - li Phone - ul - li MODEL: OnePlus 5T - li OS: LineageOS - li Network - ul - li - a(href="https://www.asus.com/Networking/Blue-Cave/") ASUS Blue Cave - li HiFi - ul - li - a(href="https://www.project-audio.com/en/product/primary-e/") Pro-Ject Primary E - li - a(href="https://www.wharfedale.co.uk/diamond-11-2/") Wharfedale Diamond 11.2 - li Music - ul - li - a(href="https://usa.yamaha.com/products/proaudio/speakers/hs_series/index.html") Yamaha HS8 - li - a(href="https://www.zoom.co.jp/products/multi-track-recorder/r16-recorder-interface-controller") Zoom R16 - li - a(href="https://www.nordkeyboards.com/products/nord-electro-5") Nord Electro 5D - li - a(href="https://www.arturia.com/microbrute-se/overview") Arturia Minibrute SE Pastel Orange - li - a(href="https://www.arturia.com/drumbrute/overview") Arturia DrumBrute - li Custom modular synth - ul - li VCO: - a(href="https://www.roland.com/global/products/system-500_512/") Roland System-500 512 - li VCF-VCA: - a(href="https://www.dreadbox-fx.com/eudemonia/") Dreadbox Eudemonia - li LFO-MOD: - a(href="https://www.dreadbox-fx.com/ataxia/") Dreadbox Ataxia - li CV PROC: - a(href="https://www.dreadbox-fx.com/utopia/") Dreadbox Utopia - li NOISE: - a(href="https://www.dreadbox-fx.com/dystopia/") Dreadbox Dystopia - li DELAY: - a(href="https://www.dreadbox-fx.com/nostalgia/") Dreadbox Nostalgia - li LFO: - a(href="http://www.doepfer.de/a146.htm") Doepfer A146 - li CLK DIVIDER: - a(href="http://www.doepfer.de/a160.htm") Doepfer A160-1 - li RM-S&H-SLEW: - a(href="http://www.doepfer.de/a1841.htm") Doepfer A184-1 - - h2 Software - - ul - li General - ul - li - a(href="https://pandoc.org/") Pandoc - li Dev - ul - li - a(href="https://atom.io/") Atom - li nano - li Homelab & selfhosting - ul - li - a(href="https://www.docker.com/") Docker - li - a(href="https://containo.us/traefik/") Traefik v2 - li - a(href="https://caddyserver.com/") Caddy v2 - li - a(href="https://www.plex.tv/") Plex - li - a(href="https://mailcow.email/") Mailcow - li Science - ul - li - a(href="https://www.mathworks.com/products/matlab.html") Matlab R2010B - li Music - ul - li - a(href="https://new.steinberg.net/cubase/") Cubase - + li VCO: + a(href="https://www.roland.com/global/products/system-500_512/") Roland System-500 512 + li VCF-VCA: + a(href="https://www.dreadbox-fx.com/eudemonia/") Dreadbox Eudemonia + li LFO-MOD: + a(href="https://www.dreadbox-fx.com/ataxia/") Dreadbox Ataxia + li CV PROC: + a(href="https://www.dreadbox-fx.com/utopia/") Dreadbox Utopia + li NOISE: + a(href="https://www.dreadbox-fx.com/dystopia/") Dreadbox Dystopia + li DELAY: + a(href="https://www.dreadbox-fx.com/nostalgia/") Dreadbox Nostalgia + li LFO: + a(href="http://www.doepfer.de/a146.htm") Doepfer A146 + li CLK DIVIDER: + a(href="http://www.doepfer.de/a160.htm") Doepfer A160-1 + li RM-S&H-SLEW: + a(href="http://www.doepfer.de/a1841.htm") Doepfer A184-1 + + h2 Software + + ul + li General + ul + li + a(href="https://pandoc.org/") Pandoc + li Dev + ul + li + a(href="https://atom.io/") Atom + li nano + li Homelab & selfhosting + ul + li + a(href="https://www.docker.com/") Docker + li + a(href="https://containo.us/traefik/") Traefik v2 + li + a(href="https://caddyserver.com/") Caddy v2 + li + a(href="https://www.plex.tv/") Plex + li + a(href="https://mailcow.email/") Mailcow + li Science + ul + li + a(href="https://www.mathworks.com/products/matlab.html") Matlab R2010B + li Music + ul + li + a(href="https://new.steinberg.net/cubase/") Cubase + diff --git a/views/work.pug b/views/work.pug index 707faf3..de0952d 100644 --- a/views/work.pug +++ b/views/work.pug @@ -1,37 +1,37 @@ extends templates/main - + block content header - h1 - | Work - nav - | >> - a(href="/about") about me - | > - a(href="/work") work - + h1 + | Work + nav + | >> + a(href="/about") about me + | > + a(href="/work") work + main - h2 >> Open Source developer - - h3 Projects - p - | Currently working on - a(href="https://keyoxide.org") Keyoxide - | . - - h3 VCS accounts - .wrapper-table - table - tbody - tr - td Codeberg - td - a(href="https://codeberg.org/yarmo" rel="me") @yarmo - tr - td GitLab - td - a(href="https://gitlab.com/yarmo" rel="me") @yarmo - tr - td Github - td - a(href="https://github.com/YarmoM" rel="me") @YarmoM + h2 >> Open Source developer + + h3 Projects + p + | Currently working on + a(href="https://keyoxide.org") Keyoxide + | . + + h3 VCS accounts + .wrapper-table + table + tbody + tr + td Codeberg + td + a(href="https://codeberg.org/yarmo" rel="me") @yarmo + tr + td GitLab + td + a(href="https://gitlab.com/yarmo" rel="me") @yarmo + tr + td Github + td + a(href="https://github.com/YarmoM" rel="me") @YarmoM From c6aa20ce3f9f3dc97782d56fda43ee2adeb67831 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 15:28:34 +0200 Subject: [PATCH 08/14] Reindent --- public/style.css | 261 +++++++++++++++++++++++------------------------ 1 file changed, 130 insertions(+), 131 deletions(-) diff --git a/public/style.css b/public/style.css index aec424b..bdbda0e 100644 --- a/public/style.css +++ b/public/style.css @@ -24,31 +24,31 @@ } :root { - --clr-bg: hsl(0,0%,95%); - --clr-bg-alt: hsl(0,0%,85%); + --clr-bg: hsl(0,0%,95%); + --clr-bg-alt: hsl(0,0%,85%); - --clr-border: hsl(0,0%,80%); + --clr-border: hsl(0,0%,80%); - --clr-text: hsl(0,0%,15%); - --clr-text-long: hsl(0,0%,10%); - --clr-text-highlight: hsl(0,50%,40%); - --clr-header: hsl(0,0%,15%); - --clr-subheader: hsl(0,0%,15%); - --clr-link: hsl(175,50%,40%); - --clr-link-alt: hsl(175,38%,60%); - --clr-code: hsl(0,0%,15%); + --clr-text: hsl(0,0%,15%); + --clr-text-long: hsl(0,0%,10%); + --clr-text-highlight: hsl(0,50%,40%); + --clr-header: hsl(0,0%,15%); + --clr-subheader: hsl(0,0%,15%); + --clr-link: hsl(175,50%,40%); + --clr-link-alt: hsl(175,38%,60%); + --clr-code: hsl(0,0%,15%); } * { box-sizing: border-box; } body { - font-family: 'dm', 'Courier New', Courier, monospace; - color: var(--clr-text); - line-height: 1.4em; - font-size: 1.1em; - background-color: var(--clr-bg); - margin: 24px; + font-family: 'dm', 'Courier New', Courier, monospace; + color: var(--clr-text); + line-height: 1.4em; + font-size: 1.1em; + background-color: var(--clr-bg); + margin: 24px; } header { margin: 0 0 48px; @@ -56,32 +56,32 @@ header { border-bottom: 3px dashed rgba(0,0,0,0.5); } footer { - margin: 64px 0 0; - text-align: center; + margin: 64px 0 0; + text-align: center; border-top: 3px dashed rgba(0,0,0,0.5); } .container { - width: 100%; - max-width: 720px; - margin: 64px auto 128px; - overflow: hidden; + width: 100%; + max-width: 720px; + margin: 64px auto 128px; + overflow: hidden; } .select-all { - user-select: all; - -ms-user-select: all; - -moz-user-select: all; - -webkit-user-select: all; + user-select: all; + -ms-user-select: all; + -moz-user-select: all; + -webkit-user-select: all; } a { - color: var(--clr-link); - font-weight: bold; - text-decoration: underline; + color: var(--clr-link); + font-weight: bold; + text-decoration: underline; } a:hover { - color: var(--clr-text); - background-color: var(--clr-link-alt); - text-decoration: none; + color: var(--clr-text); + background-color: var(--clr-link-alt); + text-decoration: none; } a.header-anchor { text-decoration: none; @@ -91,57 +91,57 @@ h2:hover a.header-anchor { opacity: 1; } h1 { - line-height: 1.2em; + line-height: 1.2em; margin: 8px 0 12px 0; } h2 { - color: var(--clr-header); - font-weight: bold; - margin: 64px 0 0; - line-height: 1.2em; + color: var(--clr-header); + font-weight: bold; + margin: 64px 0 0; + line-height: 1.2em; } h3 { - margin: 32px 0 0; - color: var(--clr-subheader); - line-height: 1.2em; + margin: 32px 0 0; + color: var(--clr-subheader); + line-height: 1.2em; } .small { - font-size: 0.75em !important; + font-size: 0.75em !important; } pre { - padding: 0 4px; - background-color: var(--clr-bg-alt); - border: 2px solid var(--clr-border); - overflow-x: auto; + padding: 0 4px; + background-color: var(--clr-bg-alt); + border: 2px solid var(--clr-border); + overflow-x: auto; } code { - font-family: 'dm', 'Courier New', Courier, monospace; - color: var(--clr-code); - background-color: var(--clr-bg-alt); - border: 2px solid var(--clr-border); - font-size: 1rem !important; + font-family: 'dm', 'Courier New', Courier, monospace; + color: var(--clr-code); + background-color: var(--clr-bg-alt); + border: 2px solid var(--clr-border); + font-size: 1rem !important; line-height: 1.5rem; } pre > code { - border: 0; + border: 0; } p > code, li > code { - padding: 0 2px; + padding: 0 2px; } ul li { - list-style-type: "|> "; + list-style-type: "|> "; } blockquote { - margin-left: 0; - padding-left: 32px; - border-left: 2px solid #4ab4ab; + margin-left: 0; + padding-left: 32px; + border-left: 2px solid #4ab4ab; } blockquote strong em { - color: var(--clr-text-highlight); + color: var(--clr-text-highlight); } .id-card { - margin: 0 0 64px 0; + margin: 0 0 64px 0; } .ellipsis { width: 100%; @@ -150,25 +150,25 @@ blockquote strong em { text-overflow: ellipsis; } .id-card { - /* display: flex; - align-items: top; - flex-wrap: wrap; */ + /* display: flex; + align-items: top; + flex-wrap: wrap; */ position: relative; padding: 24px 24px 0px; background: #f9f9f9; border: 2px solid rgba(0,0,0,0.5); } .id-card .header-image { - /* flex: 1; - flex-basis: auto; */ - /* margin: 8px 32px 8px 0; */ - text-align: center; + /* flex: 1; + flex-basis: auto; */ + /* margin: 8px 32px 8px 0; */ + text-align: center; } .id-card .header-description { width: 100%; - /* flex: 100; - flex-basis: auto; */ - /* margin: 8px 0; */ + /* flex: 100; + flex-basis: auto; */ + /* margin: 8px 0; */ /* border-left: 2px solid var(--clr-border); border-right: 2px solid var(--clr-border); */ } @@ -182,145 +182,144 @@ blockquote strong em { .id-card .profile-picture { /* position: absolute; */ float: right; - width: 128px; + width: 128px; margin: 0 0 12px 12px; /* margin: 8px 0; */ /* margin: 0 1em 0 0; */ - border-radius: 100%; - + border-radius: 100%; } .id-card h1 { font-size: 1.6em; /* margin: 0; */ margin: 0 0 1em; - /* margin: 0 0 16px; */ + /* margin: 0 0 16px; */ } .id-card p { width: 100%; - font-size: 1.1em; - margin: 0 0 1em 0; + font-size: 1.1em; + margin: 0 0 1em 0; } .id-card .social a { - display: inline-block; - width: 20px; - height: 20px; - padding: 8px; - margin: 0 4px; - border: 0; + display: inline-block; + width: 20px; + height: 20px; + padding: 8px; + margin: 0 4px; + border: 0; } .wrapper-table { - display: block; - margin: 24px 0 48px; - overflow-x: auto; + display: block; + margin: 24px 0 48px; + overflow-x: auto; } table { - width: 100%; - min-width: 640px; - border-top: 1px var(--clr-text) solid; - border-bottom: 1px var(--clr-text) solid; - border-collapse: collapse; - line-height: 1.4em; + width: 100%; + min-width: 640px; + border-top: 1px var(--clr-text) solid; + border-bottom: 1px var(--clr-text) solid; + border-collapse: collapse; + line-height: 1.4em; } table thead { - border-bottom: 1px var(--clr-text) solid; + border-bottom: 1px var(--clr-text) solid; } table th { - padding: 8px 12px; + padding: 8px 12px; } table td { - padding: 10px 12px; + padding: 10px 12px; } table.academic-record th:nth-child(1) { - width: 15%; + width: 15%; } table.academic-record th:nth-child(2) { - width: 35%; + width: 35%; } table.academic-record th:nth-child(3) { - width: auto; + width: auto; } table.work-experience th:nth-child(1) { - width: 15%; + width: 15%; } table.work-experience th:nth-child(2) { - width: 35%; + width: 35%; } table.work-experience th:nth-child(3) { - width: auto; + width: auto; } table.publications th:nth-child(1) { - width: 15%; + width: 15%; } table.publications th:nth-child(2) { - width: 35%; + width: 35%; } table.publications th:nth-child(3) { - width: auto; + width: auto; } table.music th:nth-child(1) { - width: 15%; + width: 15%; } table.music th:nth-child(2) { - width: 35%; + width: 35%; } table.music th:nth-child(3) { - width: auto; + width: auto; } /* Longform */ .longform_list { - margin: 2em 0 0; + margin: 2em 0 0; } .longform_list__item { - margin: 2em 0 0; - font-family: 'Lora', Georgia, Times, serif; + margin: 2em 0 0; + font-family: 'Lora', Georgia, Times, serif; } .longform_list__item a { display: inline-block; margin: 4px 0; - font-size: 1.3em; + font-size: 1.3em; } .longform__header { - font-size: 0.9em; - color: var(--clr-subheader); + font-size: 0.9em; + color: var(--clr-subheader); } .longform__content { - margin: 64px 0 0; - font-family: 'Lora', Georgia, Times, serif; - font-size: 1.1em; - line-height: 1.8em; - color: var(--clr-text-long); + margin: 64px 0 0; + font-family: 'Lora', Georgia, Times, serif; + font-size: 1.1em; + line-height: 1.8em; + color: var(--clr-text-long); } .longform__content p { - margin: 1.5em 0; + margin: 1.5em 0; } .longform__content code { - font-size: 0.8em; + font-size: 0.8em; } .longform__content ul li { - list-style-type: "- "; + list-style-type: "- "; } .longform__content img { - display: block; - max-width: 100%; - max-height: 480px; - margin: 0 auto; - text-align: center; + display: block; + max-width: 100%; + max-height: 480px; + margin: 0 auto; + text-align: center; } .longform__content img + br { - display: none; + display: none; } .longform__content img + br + em { - display: block; - text-align: center; - font-style: normal; - font-size: 90%; + display: block; + text-align: center; + font-style: normal; + font-size: 90%; } .comment { padding: 12px; @@ -344,10 +343,10 @@ table.music th:nth-child(3) { /* Lists */ .list { - margin: 64px 0 0; + margin: 64px 0 0; } .list__item p { - margin: 0 0 8px; + margin: 0 0 8px; } @media screen and (max-width: 560px) { From d69492a2e4b8a802eb85f5653a4201537095577d Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 15:34:50 +0200 Subject: [PATCH 09/14] Remove obsolete files --- functions.php | 235 ------------------------ index.php | 413 ------------------------------------------ scripts/minifyCSS.php | 19 -- 3 files changed, 667 deletions(-) delete mode 100644 functions.php delete mode 100644 index.php delete mode 100644 scripts/minifyCSS.php diff --git a/functions.php b/functions.php deleted file mode 100644 index b4739c1..0000000 --- a/functions.php +++ /dev/null @@ -1,235 +0,0 @@ - $entry) { - $time = strtotime($entry["created_at"]); - $data[$id]["date"] = date("Y-m-d",$time); - $data[$id]["time"] = date("H:i:s",$time); - } - - return $data; -} - -function getFOSS() { - return Yaml::parseFile('content/foss/foss.yaml'); -} - -function getVinyl() { - return Yaml::parseFile('content/music/vinyl.yaml'); -} - -function getAOTW() { - return Yaml::parseFile('content/music/aotw.yaml'); -} - -function getRSS($params) { - header("Content-Type: text/xml"); - $feed = new Feed(); - - $channel = new Channel(); - $channel - ->title($params['feed']['title']) - ->description($params['feed']['description']) - ->url($params['feed']['url']) - ->atomLinkSelf($params['feed']['linkself']) - ->appendTo($feed); - - $dates = array_column($params['posts'], 'date'); - array_multisort($dates, SORT_DESC, $params['posts']); - - foreach($params['posts'] as $post) { - $item = new Item(); - $item - ->title($post['title']) - ->creator($post['author']) - // ->content($post['content']) - ->description($post['content']) - ->url($post['url']) - ->guid($post['url'], true) - ->pubDate(strtotime($post['date'])) - ->appendTo($channel); - } - - echo $feed; -} - -function scandirRec($path, $category, $params) { - $Parsedown = new Parsedown(); - $mp = new MetaParsedown(); - $items = array(); - - // If a directory - if(is_dir($path)) { - $files = glob($path . '*', GLOB_MARK); - foreach($files as $file) { - if(is_dir($file)) { - $items = array_merge($items, scandirRec($file, $category, $params)); - } else { - $return = scandirRec($file, $category, $params); - if (!empty($return)) { - $items[] = $return; - } - } - } - return $items; - } - - // If a file - if (($path == '.') || ($path == '..')) { - return; - } - - $content = file_get_contents($path); - $meta = $mp->meta($content); - - switch ($category) { - case 'blog': - $item = array( - "type" => "blog", - "title" => $meta["title"], - "author" => $meta["author"], - "urlrel" => "/post/".$meta["slug"], - "url" => "https://yarmo.eu/post/".$meta["slug"], - "slug" => $meta["slug"], - "date" => $meta["date"], - "published" => $meta["published"], - "discussion" => $meta["discussion"], - "content" => $mp->text($content)); - - $date = new DateTime($item['date']); - $item['date_formatted'] = $date->format('Y-m-d'); - $item['date_rss'] = $date->format('Y-m-d'); - - if (!$item['published'] && !(isset($params['slug']) && $item['slug'] == $params['slug'])) { - return; - } - break; - - case 'notes': - $item = array( - "type" => "note", - "title" => $meta["title"], - "author" => $meta["author"], - "urlrel" => "/post/".$meta["slug"], - "url" => "https://yarmo.eu/post/".$meta["slug"], - "slug" => $meta["slug"], - "date" => $meta["date"], - "published" => $meta["published"], - "discussion" => $meta["discussion"], - "content" => $mp->text($content)); - - $date = new DateTime($item['date']); - $item['date_formatted'] = $date->format('Y-m-d'); - $item['date_rss'] = $date->format('Y-m-d'); - - if (!$item['published'] && !(isset($params['slug']) && $item['slug'] == $params['slug'])) { - return; - } - break; - - case 'projects': - $item = array( - "title" => $meta["title"], - "status" => $meta["status"], - "urlrel" => "/projects/".$meta["slug"], - "url" => "https://yarmo.eu/projects/".$meta["slug"], - "slug" => $meta["slug"], - "date" => $meta["date"], - "listed" => $meta["listed"], - "content" => $mp->text($content)); - - $date = new DateTime($item['date']); - $item['date_formatted'] = $date->format('Y-m-d'); - $item['date_rss'] = $date->format('Y-m-d'); - - if (!$item['listed'] && !(isset($params['slug']) && $item['slug'] == $params['slug'])) { - return; - } - break; - - case 'replies': - $item = array( - "type" => "note", - "title" => $meta["title"], - "reply-url" => $meta["reply-url"], - "reply-title" => $meta["reply-title"], - "author" => $meta["author"], - "urlrel" => "/reply/".$meta["slug"], - "url" => "https://yarmo.eu/reply/".$meta["slug"], - "slug" => $meta["slug"], - "date" => $meta["date"], - "published" => $meta["published"], - "content" => $mp->text($content)); - - $date = new DateTime($item['date']); - $item['date_formatted'] = $date->format('Y-m-d'); - $item['date_rss'] = $date->format('Y-m-d'); - - if (!$item['published'] && !(isset($params['slug']) && $item['slug'] == $params['slug'])) { - return; - } - break; - - default: - return; - break; - } - - if (isset($params['slug']) && $item['slug'] != $params['slug']) { - return; - } - if (isset($params['slug'])) { - $item["webmentions"] = array_merge( - getWebmentions($item["url"]), - getWebmentions("https://yarmo.eu/blog/".$meta["slug"]), - getWebmentions("https://yarmo.eu/notes/".$meta["slug"]) - ); - $item["hasWebmentions"] = count($item["webmentions"]) > 0; - } - - return $item; -} diff --git a/index.php b/index.php deleted file mode 100644 index b882d1e..0000000 --- a/index.php +++ /dev/null @@ -1,413 +0,0 @@ -map('GET', '/', function() {}, 'home'); -$router->map('GET', '/rss', function() {}, 'rss'); -$router->map('GET', '/rss.xml', function() {}, 'rss-xml'); -$router->map('GET', '/rss/all', function() {}, 'rss-all'); -$router->map('GET', '/rss/blog', function() {}, 'rss-blog'); -$router->map('GET', '/rss/notes', function() {}, 'rss-notes'); -$router->map('GET', '/about', function() {}, 'about'); -$router->map('GET', '/feeds', function() {}, 'feeds'); -$router->map('GET', '/uses', function() {}, 'uses'); -$router->map('GET', '/now', function() {}, 'now'); -$router->map('GET', '/blogroll', function() {}, 'blogroll'); -$router->map('GET', '/blog', function() {}, 'blog'); -$router->map('GET', '/blog/[*:slug]', function() {}, 'blog_post'); -$router->map('GET', '/notes', function() {}, 'notes'); -$router->map('GET', '/notes/[*:slug]', function() {}, 'notes_post'); -$router->map('GET', '/post/[*:slug]', function() {}, 'post'); -$router->map('GET', '/reply/[*:slug]', function() {}, 'reply'); -$router->map('GET', '/projects', function() {}, 'projects'); -$router->map('GET', '/projects/[*:slug]', function() {}, 'projects_details'); -$router->map('GET', '/foss', function() {}, 'foss'); -$router->map('GET', '/music', function() {}, 'music'); -$router->map('GET', '/vinyl', function() {}, 'vinyl'); -$router->map('GET', '/aotw', function() {}, 'aotw'); -$router->map('GET', '/pgp', function() {}, 'pgp'); -$router->map('GET', '/contact', function() {}, 'contact'); - -// Router matching -$match = $router->match(); - -// Template engine settings and variables -$basetitle = 'yarmo'; -$environment = getenv('ENVIRONMENT') ?: 'production'; -$options = [ - 'paths' => [ - 'views/', - ], - 'cache_dir' => 'cache/', - 'enable_profiler' => false, - 'profiler' => [ - 'time_precision' => 3, - 'line_height' => 30, - 'display' => true, - 'log' => false, - ], -]; -$variables = [ - 'title' => $basetitle -]; - -// If we are dealing with the home page -if ($match['name'] == 'home') { - $variables['posts'] = getBlogPosts($match['params']); - $variables['title'] = 'Blog — '.$basetitle; - // $variables['icons'] = getIcons(); -} - -// If we are dealing with the about page -if ($match['name'] == 'about') { -} - -// If we are dealing with the rss feed -if ($match['name'] == 'rss' || $match['name'] == 'rss-all' || $match['name'] == 'rss-xml') { - $blogposts = getBlogPosts($match['params']); - $notes = getNotes($match['params']); - $variables['posts'] = array_merge($blogposts, $notes); - $variables['feed']['title'] = "Yarmo's blog and notes"; - $variables['feed']['description'] = "Blog and notes feed for yarmo.eu discussing homelab and selfhosted stuff"; - $variables['feed']['url'] = "https://yarmo.eu"; - $variables['feed']['linkself'] = "https://yarmo.eu/rss/all"; -} -// If we are dealing with the blog rss feed -if ($match['name'] == 'rss-blog') { - $variables['posts'] = getBlogPosts($match['params']); - $variables['feed']['title'] = "Yarmo's blog"; - $variables['feed']['description'] = "Blog feed for yarmo.eu discussing homelab and selfhosted stuff"; - $variables['feed']['url'] = "https://yarmo.eu/blog"; - $variables['feed']['linkself'] = "https://yarmo.eu/rss/blog"; -} -// If we are dealing with the notes rss feed -if ($match['name'] == 'rss-notes') { - $variables['posts'] = getNotes($match['params']); - $variables['feed']['title'] = "Yarmo's blog"; - $variables['feed']['description'] = "Notes feed for yarmo.eu discussing homelab and selfhosted stuff"; - $variables['feed']['url'] = "https://yarmo.eu/notes"; - $variables['feed']['linkself'] = "https://yarmo.eu/rss/notes"; -} - -// If we are dealing with the feeds -if ($match['name'] == 'feeds') { - $variables['title'] = 'Feeds — '.$basetitle; -} - -// If we are dealing with the uses -if ($match['name'] == 'uses') { - $variables['title'] = 'Uses — '.$basetitle; -} - -// If we are dealing with the now -if ($match['name'] == 'now') { - $variables['title'] = 'Now — '.$basetitle; -} - -// If we are dealing with the blogroll -if ($match['name'] == 'blogroll') { - $variables['title'] = 'Blogroll — '.$basetitle; -} - -// If we are dealing with the blog -if ($match['name'] == 'blog') { - $variables['posts'] = getBlogPosts($match['params']); - $variables['title'] = 'Blog — '.$basetitle; -} - -// If we are dealing with the notes -if ($match['name'] == 'notes') { - $variables['posts'] = getNotes($match['params']); - $variables['title'] = 'Notes — '.$basetitle; -} - -// If we are dealing with a post (old format) -if (($match['name'] == 'blog_post') || ($match['name'] == 'notes_post')) { - header('Location: https://yarmo.eu/post/'.$match['params']['slug']); -} - -// If we are dealing with a post -if ($match['name'] == 'post') { - $variables['post'] = getBlogPosts($match['params']); - if (count($variables['post']) == 0) { - $variables['post'] = getNotes($match['params']); - } - if (count($variables['post']) > 0) { - $variables['post'] = $variables['post'][0]; - $variables['title'] = htmlspecialchars_decode(str_replace('·','·',$variables['post']['title'])).' — '.$basetitle; - } else { - $match['name'] = '404'; - } -} - -// If we are dealing with a reply -if ($match['name'] == 'reply') { - $variables['reply'] = getReplies($match['params']); - $variables['reply'] = $variables['reply'][0]; - $variables['title'] = htmlspecialchars_decode(str_replace('·','·',$variables['reply']['title'])).' — '.$basetitle; -} - -// If we are dealing with the projects -if ($match['name'] == 'projects') { - $variables['projects'] = getProjects($match['params']); - $variables['title'] = 'Projects — '.$basetitle; -} - -// If we are dealing with a project's details -if ($match['name'] == 'projects_details') { - $variables['project'] = getProjects($match['params']); - $variables['project'] = $variables['project'][0]; - $variables['title'] = htmlspecialchars_decode(str_replace('·','·',$variables['project']['title'])).' — '.$basetitle; -} - -// If we are dealing with foss -if ($match['name'] == 'foss') { - $variables['foss'] = getFOSS(); - $variables['title'] = 'FOSS — '.$basetitle; -} - -// If we are dealing with vinyl -if ($match['name'] == 'vinyl') { - $variables['vinyl'] = getVinyl(); - $variables['albums'] = $variables['vinyl']['albums']; - $variables['title'] = 'Vinyl — '.$basetitle; -} - -// If we are dealing with Album Of The Week -if ($match['name'] == 'aotw') { - $variables['albums'] = getAOTW(); - $variables['title'] = 'Album Of The Week — '.$basetitle; -} - -// If we are dealing with the pgp page -if ($match['name'] == 'pgp') { - $variables['title'] = 'PGP — '.$basetitle; -} - -// If we are dealing with the contact page -if ($match['name'] == 'contact') { - $variables['title'] = 'Contact me — '.$basetitle; -} - -// Add Phug dyninclude -Phug::addKeyword('dyninclude', function ($args) { - return array( - 'beginPhp' => 'echo file_get_contents(' . $args . ');', - ); -}); - -// PRODUCTION -// Render the appropriate route -if ($environment === 'production') { - if(is_array($match) && is_callable($match['target'])) { - switch ($match['name']) { - case 'home': - // Phug optimizer - \Phug\Optimizer::call('displayFile', ['index', $variables], $options); - // Phug::displayFile('index', $variables, $options); - break; - - case 'about': - // Phug optimizer - \Phug\Optimizer::call('displayFile', ['about', $variables], $options); - // Phug::displayFile('index', $variables, $options); - break; - - case 'rss': - case 'rss-xml': - case 'rss-all': - case 'rss-blog': - case 'rss-notes': - getRSS($variables); - break; - - case 'feeds': - \Phug\Optimizer::call('displayFile', ['feeds', $variables], $options); - break; - - case 'uses': - \Phug\Optimizer::call('displayFile', ['uses', $variables], $options); - break; - - case 'now': - \Phug\Optimizer::call('displayFile', ['now', $variables], $options); - break; - - case 'blogroll': - \Phug\Optimizer::call('displayFile', ['blogroll', $variables], $options); - break; - - case 'blog': - \Phug\Optimizer::call('displayFile', ['blog', $variables], $options); - break; - - case 'blog_post': - \Phug\Optimizer::call('displayFile', ['blog_post', $variables], $options); - break; - - case 'notes': - \Phug\Optimizer::call('displayFile', ['notes', $variables], $options); - break; - - case 'notes_post': - \Phug\Optimizer::call('displayFile', ['notes_post', $variables], $options); - break; - - case 'post': - \Phug\Optimizer::call('displayFile', ['post', $variables], $options); - break; - - case 'reply': - \Phug\Optimizer::call('displayFile', ['reply', $variables], $options); - break; - - case 'projects': - \Phug\Optimizer::call('displayFile', ['projects', $variables], $options); - break; - - case 'projects_details': - \Phug\Optimizer::call('displayFile', ['projects_details', $variables], $options); - break; - - case 'foss': - \Phug\Optimizer::call('displayFile', ['foss', $variables], $options); - break; - - case 'music': - \Phug\Optimizer::call('displayFile', ['music', $variables], $options); - break; - - case 'vinyl': - \Phug\Optimizer::call('displayFile', ['vinyl', $variables], $options); - break; - - case 'aotw': - \Phug\Optimizer::call('displayFile', ['aotw', $variables], $options); - break; - - case 'contact': - \Phug\Optimizer::call('displayFile', ['contact', $variables], $options); - break; - - case 'pgp': - \Phug\Optimizer::call('displayFile', ['pgp', $variables], $options); - break; - - default: - \Phug\Optimizer::call('displayFile', ['404', $variables], $options); - break; - } - } else { - // No route was matched - \Phug\Optimizer::call('displayFile', ['404', $variables], $options); - } - - exit; -} - -# DEVELOPMENT -// Render the appropriate route -if(is_array($match) && is_callable($match['target'])) { - switch ($match['name']) { - case 'home': - Phug::displayFile('index', $variables, $options); - break; - - case 'about': - Phug::displayFile('about', $variables, $options); - break; - - case 'rss': - case 'rss-xml': - case 'rss-all': - case 'rss-blog': - case 'rss-notes': - getRSS($variables); - break; - - case 'feeds': - Phug::displayFile('feeds', $variables, $options); - break; - - case 'uses': - Phug::displayFile('uses', $variables, $options); - break; - - case 'now': - Phug::displayFile('now', $variables, $options); - break; - - case 'blogroll': - Phug::displayFile('blogroll', $variables, $options); - break; - - case 'blog': - Phug::displayFile('blog', $variables, $options); - break; - - case 'blog_post': - Phug::displayFile('blog_post', $variables, $options); - break; - - case 'notes': - Phug::displayFile('notes', $variables, $options); - break; - - case 'notes_post': - Phug::displayFile('notes_post', $variables, $options); - break; - - case 'post': - Phug::displayFile('post', $variables, $options); - break; - - case 'reply': - Phug::displayFile('reply', $variables, $options); - break; - - case 'projects': - Phug::displayFile('projects', $variables, $options); - break; - - case 'projects_details': - Phug::displayFile('projects_details', $variables, $options); - break; - - case 'foss': - Phug::displayFile('foss', $variables, $options); - break; - - case 'music': - Phug::displayFile('music', $variables, $options); - break; - - case 'vinyl': - Phug::displayFile('vinyl', $variables, $options); - break; - - case 'aotw': - Phug::displayFile('aotw', $variables, $options); - break; - - case 'contact': - Phug::displayFile('contact', $variables, $options); - break; - - case 'pgp': - Phug::displayFile('pgp', $variables, $options); - break; - - default: - Phug::displayFile('404', $variables, $options); - break; - } -} else { - // No route was matched - Phug::displayFile('404', $variables, $options); -} diff --git a/scripts/minifyCSS.php b/scripts/minifyCSS.php deleted file mode 100644 index a8754b7..0000000 --- a/scripts/minifyCSS.php +++ /dev/null @@ -1,19 +0,0 @@ -removeImportantComments(); -$compressor->setLineBreakPosition(1000); - -$input_css = file_get_contents('./static/style.css'); -$output_css = $compressor->run($input_css); -file_put_contents('./static/style.css', $output_css); - -$input_css = file_get_contents('./static/norm.css'); -$output_css = $compressor->run($input_css); -file_put_contents('./static/norm.css', $output_css); - -?> From 11b34ddf3eb3602dbe2f12d0b45bf556f58d291d Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 16:03:49 +0200 Subject: [PATCH 10/14] Improve feeds --- index.js | 3 ++- routes/feed.js | 45 ++++++++++++++++++++++++++++++++++++++++ routes/rss.js | 19 ----------------- server/util.js | 26 ++++++++++++++++++++--- views/feeds.pug | 27 +++++++++++++++++++++--- views/templates/main.pug | 4 +++- 6 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 routes/feed.js delete mode 100644 routes/rss.js diff --git a/index.js b/index.js index 038255c..5fdf6d3 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,8 @@ app.set('port', process.env.PORT || 3000) app.use('/', require('./routes/main')) app.use('/', require('./routes/static')) -app.use('/rss', require('./routes/rss')) +app.use('/feed', require('./routes/feed')) +app.use('/rss', require('./routes/feed')) app.listen(app.get('port'), () => { console.log(`Node server listening at http://localhost:${app.get('port')}`) diff --git a/routes/feed.js b/routes/feed.js new file mode 100644 index 0000000..edc98a0 --- /dev/null +++ b/routes/feed.js @@ -0,0 +1,45 @@ +const router = require('express').Router() +const fs = require('fs') +const _ = require('lodash') +const util = require('../server/util') + +router.get('/all', async (req, res) => { + res.setHeader('Content-Type', 'application/rss+xml') + res.end(await util.getRSS({ channel: 'all', format: 'rss' })) +}) +router.get('/all.atom', async (req, res) => { + res.setHeader('Content-Type', 'application/atom+xml') + res.end(await util.getRSS({ channel: 'all', format: 'atom' })) +}) +router.get('/all.json', async (req, res) => { + res.setHeader('Content-Type', 'application/feed+json') + res.end(await util.getRSS({ channel: 'all', format: 'json' })) +}) + +router.get('/blog', async (req, res) => { + res.setHeader('Content-Type', 'application/rss+xml') + res.end(await util.getRSS({ include: ['blog'], channel: 'blog', format: 'rss' })) +}) +router.get('/blog.atom', async (req, res) => { + res.setHeader('Content-Type', 'application/atom+xml') + res.end(await util.getRSS({ include: ['blog'], channel: 'blog', format: 'atom' })) +}) +router.get('/blog.json', async (req, res) => { + res.setHeader('Content-Type', 'application/feed+json') + res.end(await util.getRSS({ include: ['blog'], channel: 'blog', format: 'json' })) +}) + +router.get('/notes', async (req, res) => { + res.setHeader('Content-Type', 'application/rss+xml') + res.end(await util.getRSS({ include: ['notes'], channel: 'notes', format: 'rss' })) +}) +router.get('/notes.atom', async (req, res) => { + res.setHeader('Content-Type', 'application/atom+xml') + res.end(await util.getRSS({ include: ['notes'], channel: 'notes', format: 'atom' })) +}) +router.get('/notes.json', async (req, res) => { + res.setHeader('Content-Type', 'application/feed+json') + res.end(await util.getRSS({ include: ['notes'], channel: 'notes', format: 'json' })) +}) + +module.exports = router diff --git a/routes/rss.js b/routes/rss.js deleted file mode 100644 index ffc9ee5..0000000 --- a/routes/rss.js +++ /dev/null @@ -1,19 +0,0 @@ -const router = require('express').Router() -const fs = require('fs') -const _ = require('lodash') -const util = require('../server/util') - -router.get('/all', async (req, res) => { - res.setHeader('Content-Type', 'application/xml') - res.end(await util.getRSS()) -}) -router.get('/blog', async (req, res) => { - res.setHeader('Content-Type', 'application/xml') - res.end(await util.getRSS({ include: ['blog'] })) -}) -router.get('/notes', async (req, res) => { - res.setHeader('Content-Type', 'application/xml') - res.end(await util.getRSS({ include: ['notes'] })) -}) - -module.exports = router diff --git a/server/util.js b/server/util.js index 9c622fa..94ba534 100644 --- a/server/util.js +++ b/server/util.js @@ -110,8 +110,8 @@ const getWebmentions = async (url) => { const getRSS = async (opts) => { if (!opts) { opts = {} } opts.include = 'include' in opts ? opts.include : ['blog', 'notes'] - // opts.excludeBlogPosts = 'excludeBlogPosts' in opts ? opts.excludeBlogPosts : false - // opts.excludeNotes = 'excludeNotes' in opts ? opts.excludeNotes : false + opts.channel = 'channel' in opts ? opts.channel : 'all' + opts.format = 'format' in opts ? opts.format : 'rss' const feed = new Feed({ title: "Yarmo's blog and notes", @@ -122,6 +122,11 @@ const getRSS = async (opts) => { favicon: "https://yarmo.eu/favicon.png", copyright: "All rights reserved 2020 Yarmo Mackenbach", updated: new Date(Date.now()), + feedLinks: { + rss: `https://yarmo.eu/feed/${opts.channel}`, + json: `https://yarmo.eu/feed/${opts.channel}.json`, + atom: `https://yarmo.eu/feed/${opts.channel}.atom` + }, author: { name: "Yarmo Mackenbach", email: "yarmo@yarmo.eu", @@ -165,7 +170,22 @@ const getRSS = async (opts) => { }) }) - return feed.rss2() + let response + switch (opts.format) { + case 'rss': + case 'xml': + default: + response = feed.rss2() + break; + case 'atom': + response = feed.atom1() + break; + case 'json': + response = feed.json1() + break; + } + + return response } module.exports = { diff --git a/views/feeds.pug b/views/feeds.pug index 369358d..0a19763 100644 --- a/views/feeds.pug +++ b/views/feeds.pug @@ -13,8 +13,29 @@ block content main ul li - a(href="/rss/all") RSS blog and notes + p + | Feed for blog posts and notes ( + a(href="/feed/all") RSS + | - + a(href="/feed/all.atom") ATOM + | - + a(href="/feed/all.") JSON + | ) li - a(href="/rss/blog") RSS blog + p + | Feed for blog posts ( + a(href="/feed/blog") RSS + | - + a(href="/feed/blog.atom") ATOM + | - + a(href="/feed/blog.json") JSON + | ) li - a(href="/rss/notes") RSS notes + p + | Feed for notes ( + a(href="/feed/notes") RSS + | - + a(href="/feed/notes.atom") ATOM + | - + a(href="/feed/notes.json") JSON + | ) diff --git a/views/templates/main.pug b/views/templates/main.pug index 2e92d56..301b14e 100644 --- a/views/templates/main.pug +++ b/views/templates/main.pug @@ -9,7 +9,9 @@ html link(rel="stylesheet", href="/static/norm.css") link(rel="stylesheet", href="/static/style.css") link(rel="shortcut icon", href="/favicon.png") - link(rel="alternate", href="/rss/all", title="RSS blog feed for yarmo.eu", type="application/rss+xml") + link(rel="alternate", href="/feed/all", title="RSS blog feed for yarmo.eu", type="application/rss+xml") + link(rel="alternate", href="/feed/all.atom", title="RSS blog feed for yarmo.eu", type="application/atom+xml") + link(rel="alternate", href="/feed/all.json", title="RSS blog feed for yarmo.eu", type="application/feed+json") link(rel="webmention", href="https://webm.yarmo.eu/receive") script(asyc, defer, data-domain="yarmo.eu", src="https://plausible.io/js/plausible.js") body From a731deec536d77d7792a87b67fc344937cac2425 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 16:05:16 +0200 Subject: [PATCH 11/14] Improve feeds --- views/feeds.pug | 2 -- 1 file changed, 2 deletions(-) diff --git a/views/feeds.pug b/views/feeds.pug index 0a19763..05f01b8 100644 --- a/views/feeds.pug +++ b/views/feeds.pug @@ -6,8 +6,6 @@ block content | Feeds nav | >> - a(href="/about") about me - | > a(href="/feeds") feeds main From 4a9c8b0292758d46910c1469512a76c39a345172 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 16:06:00 +0200 Subject: [PATCH 12/14] Improve feeds --- views/feeds.pug | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/views/feeds.pug b/views/feeds.pug index 05f01b8..f707651 100644 --- a/views/feeds.pug +++ b/views/feeds.pug @@ -7,6 +7,13 @@ block content nav | >> a(href="/feeds") feeds + nav + | Go to: + a(href="/about") about me + | | + a(href="/blog") blog + | | + a(href="/notes") notes main ul From 1279d9307c269247c542d74d2eabcd6da4a83c00 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 19:00:48 +0200 Subject: [PATCH 13/14] Fix time in webmentions --- server/util.js | 12 ++++++++++-- views/post.pug | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/server/util.js b/server/util.js index 94ba534..7c4a08d 100644 --- a/server/util.js +++ b/server/util.js @@ -77,7 +77,7 @@ const getNotes = async (opts) => { url: `https://yarmo.eu/post/${fm.slug}`, slug: fm.slug, date: fm.date, - date_formatted: DateTime.fromFormat(fm.date, 'yyyy-LL-dd hh:mm:ss').setLocale("en").toLocaleString(DateTime.DATE_MED), + date_formatted: DateTime.fromFormat(fm.date, 'yyyy-LL-dd hh:mm:ss').setLocale("en").setZone('utc').toLocaleString(DateTime.DATE_MED), published: fm.published, discussion: fm.discussion, content: md.render(fm.__content) @@ -104,7 +104,15 @@ const getWebmentions = async (url) => { const data_1 = await getJSON(`https://webm.yarmo.eu/get?target=${url}`) const data_2 = await getJSON(`https://webm.yarmo.eu/get?target=${url.replace('/post/', '/blog/')}`) const data_3 = await getJSON(`https://webm.yarmo.eu/get?target=${url.replace('/post/', '/notes/')}`) - return data_1.concat(data_2).concat(data_3) + + const dataRaw = data_1.concat(data_2).concat(data_3) + const data = _.map(dataRaw, (x) => { + x.date = DateTime.fromISO(x.created_at).setLocale("en").setZone('utc').toLocaleString(DateTime.DATE_MED), + x.time = DateTime.fromISO(x.created_at).setLocale("en").setZone('utc').toLocaleString(DateTime.TIME_24_WITH_SHORT_OFFSET) + return x + }) + + return data } const getRSS = async (opts) => { diff --git a/views/post.pug b/views/post.pug index e7e9679..eca6937 100644 --- a/views/post.pug +++ b/views/post.pug @@ -12,7 +12,7 @@ mixin webmention(item) if ('date' in item) | on !{item.date} if ('time' in item) - | at !{item.time} UTC + | at !{item.time} else if (item.type == "comment") .comment p.quote From 66b0b890f20931634b1b7e4aacfd33937b9e12e1 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 25 Sep 2020 19:28:54 +0200 Subject: [PATCH 14/14] Remove drone --- .drone.yml | 87 ------------------------------------------------------ 1 file changed, 87 deletions(-) delete mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 49252d1..0000000 --- a/.drone.yml +++ /dev/null @@ -1,87 +0,0 @@ ---- - -kind: pipeline -type: docker -name: deploy dev - -steps: - - name: composer - image: composer - commands: - - composer install - - composer run-script minifyCSS - - name: rsync to prism - image: drillster/drone-rsync - settings: - hosts: - from_secret: ssh_host - port: - from_secret: ssh_port - user: - from_secret: ssh_user - key: - from_secret: ssh_key - source: ./ - target: ~/web/dev.yarmo.eu - exclude: [ ".git/", ".gitignore", ".drone.yml", "composer.json", "composer.lock" ] - - name: purge cache - image: appleboy/drone-ssh - settings: - host: - from_secret: ssh_host - port: - from_secret: ssh_port - username: - from_secret: ssh_user - key: - from_secret: ssh_key - script: - - rm -rf web/dev.yarmo.eu/cache/* - -trigger: - branch: - - dev - ---- - -kind: pipeline -type: docker -name: deploy prod - -steps: - - name: composer - image: composer - commands: - - composer install - - composer run-script minifyCSS - - name: rsync to prism - image: drillster/drone-rsync - settings: - hosts: - from_secret: ssh_host - port: - from_secret: ssh_port - user: - from_secret: ssh_user - key: - from_secret: ssh_key - source: ./ - target: ~/web/yarmo.eu - exclude: [ ".git/", ".gitignore", ".drone.yml", "composer.json", "composer.lock" ] - - name: purge cache - image: appleboy/drone-ssh - settings: - host: - from_secret: ssh_host - port: - from_secret: ssh_port - username: - from_secret: ssh_user - key: - from_secret: ssh_key - script: - - rm -rf web/yarmo.eu/cache/* - -trigger: - branch: - - main