Compare commits
53 Commits
jekyll
...
gh-actions
Author | SHA1 | Date | |
---|---|---|---|
ca831cec40 | |||
2a2a39f4a7 | |||
fac6f1c2f7 | |||
6cb2442786 | |||
073368e311 | |||
6176227dfa | |||
d807a0407f | |||
4fc8f4c77b | |||
1816f001a3 | |||
0164e25b69 | |||
8b685bca52 | |||
20cd435743 | |||
e7e72727ae | |||
7b900d92b2 | |||
fc40162d5e | |||
2d10c0ca80 | |||
35dd54ca45 | |||
40251a91ba | |||
4f6717ef32 | |||
8e1de3f1ec | |||
78d820858a | |||
996f07c1bf | |||
acf6719ad2 | |||
a7084414b6 | |||
8b0111450b | |||
4e9aacfab8 | |||
02b0c290ae | |||
1d28855a12 | |||
087a185136 | |||
|
d9ca754951 | ||
3bdacc82e6 | |||
97de2db989 | |||
42c316a1fa | |||
051caa7790 | |||
67f0d6c485 | |||
803242dde8 | |||
0e8270cfad | |||
0c5f705b27 | |||
66b6186296 | |||
fcd16cd8cf | |||
e9771f6b7e | |||
325f206d15 | |||
1ace2f62ea | |||
fc140b995c | |||
a66fc37c03 | |||
c5db049494 | |||
2afd947660 | |||
ac0d966308 | |||
af9fde3fa9 | |||
396b7e5683 | |||
eecd97a8d3 | |||
cc1d8047ab | |||
039bac5e09 |
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
vendor
|
@@ -1,31 +1,28 @@
|
||||
---
|
||||
new_page_extension: md
|
||||
auto_deploy: false
|
||||
admin_path: ''
|
||||
webhook_url:
|
||||
admin_path: ""
|
||||
webhook_url:
|
||||
sections:
|
||||
- type: jekyll-posts
|
||||
label: Posts
|
||||
create: documents
|
||||
templates:
|
||||
- blog-post
|
||||
- type: directory
|
||||
path: _pages
|
||||
label: Pages
|
||||
create: documents
|
||||
match: "**/*"
|
||||
upload_dir: _uploads
|
||||
- type: directory
|
||||
path: source/_posts
|
||||
label: Posts
|
||||
create: documents
|
||||
match: "**/*"
|
||||
- type: directory
|
||||
path: source/_pages
|
||||
label: Pages
|
||||
create: documents
|
||||
match: "**/*"
|
||||
upload_dir: source/uploads
|
||||
public_path: "/uploads"
|
||||
front_matter_path: ''
|
||||
front_matter_path: ""
|
||||
use_front_matter_path: false
|
||||
file_template: ":filename:"
|
||||
build:
|
||||
preview_env:
|
||||
- JEKYLL_ENV=staging
|
||||
preview_output_directory: _site
|
||||
install_dependencies_command: bundle install --path vendor/bundle
|
||||
preview_output_directory: public
|
||||
install_dependencies_command: npm i
|
||||
preview_docker_image: forestryio/ruby:2.6
|
||||
mount_path: "/srv"
|
||||
working_dir: "/srv"
|
||||
instant_preview_command: bundle exec jekyll serve --drafts --unpublished --future
|
||||
--port 8080 --host 0.0.0.0 -d _site
|
||||
instant_preview_command: yarn server
|
||||
|
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: monthly
|
||||
time: "20:00"
|
||||
timezone: Asia/Tokyo
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: textlint
|
||||
versions:
|
||||
- 11.7.7
|
||||
- 11.8.1
|
||||
- dependency-name: textlint-rule-no-dropping-the-ra
|
||||
versions:
|
||||
- 2.0.0
|
45
.github/workflows/ci.yml
vendored
Normal file
45
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# https://hexo.io/docs/github-pages.html
|
||||
# https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md#github-cache
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
buildAndPush:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# - name: Set up QEMU
|
||||
# uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ghcr.io/uetchy/uechi.io:latest
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Image digest
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
|
||||
- name: Trigger Watchtower Update
|
||||
run: |
|
||||
curl -s -H "Authorization: Bearer ${{ secrets.WATCHTOWER_TOKEN }}" https://watchtower.uechi.dev/v1/update
|
12
.gitignore
vendored
12
.gitignore
vendored
@@ -1,9 +1,11 @@
|
||||
/.vscode
|
||||
/_site
|
||||
/.sass-cache
|
||||
/node_modules/
|
||||
/npm-debug.log
|
||||
/.jekyll-metadata
|
||||
/images/crushed
|
||||
/.bundle
|
||||
/vendor/bundle/
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
db.json
|
||||
*.log
|
||||
public/
|
||||
.deploy*/
|
||||
yarn.lock
|
2
.prettierignore
Normal file
2
.prettierignore
Normal file
@@ -0,0 +1,2 @@
|
||||
scaffolds/*
|
||||
*.ejs
|
@@ -1 +1 @@
|
||||
{}
|
||||
{}
|
||||
|
@@ -1,10 +1,8 @@
|
||||
{
|
||||
"rules": {
|
||||
"max-ten": true,
|
||||
"no-start-duplicated-conjunction": {
|
||||
"interval": 2
|
||||
},
|
||||
"no-dropping-the-ra": true,
|
||||
"common-misspellings": true,
|
||||
"preset-japanese": {
|
||||
"sentence-length": false
|
||||
@@ -12,9 +10,7 @@
|
||||
},
|
||||
"filters": {
|
||||
"whitelist": {
|
||||
"allow": [
|
||||
"/{%.+?%}/"
|
||||
]
|
||||
"allow": ["/{%.+?%}/"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +0,0 @@
|
||||
language: node_js
|
||||
node_js: stable
|
||||
notifications:
|
||||
email:
|
||||
on_success: never
|
||||
on_failure: change
|
19
Dockerfile
Normal file
19
Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
||||
FROM node:15 as build
|
||||
|
||||
# https://github.com/jgm/pandoc/releases
|
||||
RUN curl -LO https://github.com/jgm/pandoc/releases/download/2.14.0.1/pandoc-2.14.0.1-1-amd64.deb
|
||||
RUN dpkg -i pandoc-2.14.0.1-1-amd64.deb
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json /app/
|
||||
RUN yarn install
|
||||
|
||||
COPY themes /app/themes
|
||||
COPY source /app/source
|
||||
COPY _config.yml /app/
|
||||
RUN yarn build
|
||||
|
||||
FROM nginx:stable-alpine as runtime
|
||||
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
COPY --from=build /app/public /var/www/html/
|
3
Gemfile
3
Gemfile
@@ -1,3 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'github-pages', group: :jekyll_plugins # workaround https://github.com/github/pages-gem#usage
|
258
Gemfile.lock
258
Gemfile.lock
@@ -1,258 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.3.3)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.11.1)
|
||||
colorator (1.1.0)
|
||||
commonmarker (0.17.13)
|
||||
ruby-enum (~> 0.5)
|
||||
concurrent-ruby (1.1.7)
|
||||
dnsruby (1.61.4)
|
||||
simpleidn (~> 0.1)
|
||||
em-websocket (0.5.2)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
ethon (0.12.0)
|
||||
ffi (>= 1.3.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.7.0)
|
||||
faraday (1.0.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.13.1)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.1)
|
||||
github-pages (207)
|
||||
github-pages-health-check (= 1.16.1)
|
||||
jekyll (= 3.9.0)
|
||||
jekyll-avatar (= 0.7.0)
|
||||
jekyll-coffeescript (= 1.1.1)
|
||||
jekyll-commonmark-ghpages (= 0.1.6)
|
||||
jekyll-default-layout (= 0.1.4)
|
||||
jekyll-feed (= 0.13.0)
|
||||
jekyll-gist (= 1.5.0)
|
||||
jekyll-github-metadata (= 2.13.0)
|
||||
jekyll-mentions (= 1.5.1)
|
||||
jekyll-optional-front-matter (= 0.3.2)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
jekyll-readme-index (= 0.3.0)
|
||||
jekyll-redirect-from (= 0.15.0)
|
||||
jekyll-relative-links (= 0.6.1)
|
||||
jekyll-remote-theme (= 0.4.1)
|
||||
jekyll-sass-converter (= 1.5.2)
|
||||
jekyll-seo-tag (= 2.6.1)
|
||||
jekyll-sitemap (= 1.4.0)
|
||||
jekyll-swiss (= 1.0.0)
|
||||
jekyll-theme-architect (= 0.1.1)
|
||||
jekyll-theme-cayman (= 0.1.1)
|
||||
jekyll-theme-dinky (= 0.1.1)
|
||||
jekyll-theme-hacker (= 0.1.1)
|
||||
jekyll-theme-leap-day (= 0.1.1)
|
||||
jekyll-theme-merlot (= 0.1.1)
|
||||
jekyll-theme-midnight (= 0.1.1)
|
||||
jekyll-theme-minimal (= 0.1.1)
|
||||
jekyll-theme-modernist (= 0.1.1)
|
||||
jekyll-theme-primer (= 0.5.4)
|
||||
jekyll-theme-slate (= 0.1.1)
|
||||
jekyll-theme-tactile (= 0.1.1)
|
||||
jekyll-theme-time-machine (= 0.1.1)
|
||||
jekyll-titles-from-headings (= 0.5.3)
|
||||
jemoji (= 0.11.1)
|
||||
kramdown (= 2.3.0)
|
||||
kramdown-parser-gfm (= 1.1.0)
|
||||
liquid (= 4.0.3)
|
||||
mercenary (~> 0.3)
|
||||
minima (= 2.5.1)
|
||||
nokogiri (>= 1.10.4, < 2.0)
|
||||
rouge (= 3.19.0)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.16.1)
|
||||
addressable (~> 2.3)
|
||||
dnsruby (~> 1.60)
|
||||
octokit (~> 4.0)
|
||||
public_suffix (~> 3.0)
|
||||
typhoeus (~> 1.3)
|
||||
html-pipeline (2.14.0)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (3.9.0)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (~> 0.7)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (>= 1.17, < 3)
|
||||
liquid (~> 4.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pathutil (~> 0.9)
|
||||
rouge (>= 1.7, < 4)
|
||||
safe_yaml (~> 1.0)
|
||||
jekyll-avatar (0.7.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-coffeescript (1.1.1)
|
||||
coffee-script (~> 2.2)
|
||||
coffee-script-source (~> 1.11.1)
|
||||
jekyll-commonmark (1.3.1)
|
||||
commonmarker (~> 0.14)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-commonmark-ghpages (0.1.6)
|
||||
commonmarker (~> 0.17.6)
|
||||
jekyll-commonmark (~> 1.2)
|
||||
rouge (>= 2.0, < 4.0)
|
||||
jekyll-default-layout (0.1.4)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-feed (0.13.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-gist (1.5.0)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.13.0)
|
||||
jekyll (>= 3.4, < 5.0)
|
||||
octokit (~> 4.0, != 4.4.0)
|
||||
jekyll-mentions (1.5.1)
|
||||
html-pipeline (~> 2.3)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-optional-front-matter (0.3.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-paginate (1.1.0)
|
||||
jekyll-readme-index (0.3.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-redirect-from (0.15.0)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-relative-links (0.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-remote-theme (0.4.1)
|
||||
addressable (~> 2.0)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
rubyzip (>= 1.3.0)
|
||||
jekyll-sass-converter (1.5.2)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-sitemap (1.4.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-swiss (1.0.0)
|
||||
jekyll-theme-architect (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-cayman (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-dinky (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-hacker (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-leap-day (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-merlot (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-midnight (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-minimal (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-modernist (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-primer (0.5.4)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-github-metadata (~> 2.9)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-slate (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-tactile (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-time-machine (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-titles-from-headings (0.5.3)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
jemoji (0.11.1)
|
||||
gemoji (~> 3.0)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
kramdown (2.3.0)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.2.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.4.0)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.14.2)
|
||||
multipart-post (2.1.1)
|
||||
nokogiri (1.10.10)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
octokit (4.18.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (3.1.1)
|
||||
rb-fsevent (0.10.4)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.4)
|
||||
rouge (3.19.0)
|
||||
ruby-enum (0.8.0)
|
||||
i18n
|
||||
rubyzip (2.3.0)
|
||||
safe_yaml (1.0.5)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
sawyer (0.8.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
simpleidn (0.1.1)
|
||||
unf (~> 0.1.4)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.7)
|
||||
thread_safe (~> 0.1)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
zeitwerk (2.4.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
github-pages
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Yasuaki Uechi (https://uechi.io)
|
||||
Copyright (c) 2021 Yasuaki Uechi (https://uechi.io)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
8
Makefile
Normal file
8
Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
build:
|
||||
docker-compose build --pull
|
||||
|
||||
push:
|
||||
docker-compose push
|
||||
|
||||
deploy: build
|
||||
docker-compose -f docker-compose.production.yml up -d
|
13
README.md
13
README.md
@@ -1,19 +1,12 @@
|
||||
# uechi.io
|
||||
|
||||
[](https://travis-ci.org/uetchy/uechi.io)
|
||||
[](https://github.com/uetchy/uechi.io/actions?query=pages)
|
||||
|
||||
## Build
|
||||
|
||||
```
|
||||
docker-compose run web bundle install
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
```
|
||||
npm install
|
||||
npm test
|
||||
n 15
|
||||
yarn build
|
||||
```
|
||||
|
||||
## Publish
|
||||
|
186
_config.yml
186
_config.yml
@@ -1,47 +1,145 @@
|
||||
---
|
||||
# Hexo Configuration
|
||||
## Docs: https://hexo.io/docs/configuration.html
|
||||
## Source: https://github.com/hexojs/hexo/
|
||||
|
||||
# Site
|
||||
title: uechi.io
|
||||
timezone: Asia/Tokyo
|
||||
collections:
|
||||
posts:
|
||||
title: Posts
|
||||
output: true
|
||||
uploads:
|
||||
title: Uploads
|
||||
output: true
|
||||
defaults:
|
||||
- scope:
|
||||
path: ''
|
||||
type: posts
|
||||
values:
|
||||
layout: post
|
||||
permalink: "/blog/:title"
|
||||
description: Random posts from @uetchy.
|
||||
url: https://uechi.io
|
||||
email: y@uechi.io
|
||||
twitter:
|
||||
username: uechz
|
||||
subtitle: ""
|
||||
description: "Random posts from U"
|
||||
keywords:
|
||||
author: Yasuaki Uechi
|
||||
language: en
|
||||
timezone: "Asia/Tokyo"
|
||||
|
||||
excerpt:
|
||||
depth: 1
|
||||
|
||||
github:
|
||||
username: uetchy
|
||||
logo: "/images/icon.png"
|
||||
excerpt_separator: "#"
|
||||
google_analytics: UA-28919359-12
|
||||
plugins:
|
||||
- jekyll-redirect-from
|
||||
- jekyll-sitemap
|
||||
- jekyll-seo-tag
|
||||
- jekyll-feed
|
||||
- jemoji
|
||||
include:
|
||||
- _pages
|
||||
exclude:
|
||||
- README.md
|
||||
- LICENSE
|
||||
- CNAME
|
||||
- Gemfile
|
||||
- Gemfile.lock
|
||||
- package.json
|
||||
- node_modules
|
||||
- script
|
||||
- vendor
|
||||
- docker-compose.yml
|
||||
- Dockerfile
|
||||
twitter:
|
||||
username: uechz
|
||||
|
||||
umami:
|
||||
host: analytics.uechi.io
|
||||
id: 2739f9aa-b8d5-45fa-8972-07a5bbb87e8a
|
||||
|
||||
node_sass:
|
||||
outputStyle: nested
|
||||
precision: 5
|
||||
sourceComments: false
|
||||
|
||||
# URL
|
||||
## If your site is put in a subdirectory, set url as 'http://example.com/child' and root as '/child/'
|
||||
url: https://uechi.io
|
||||
root: /
|
||||
permalink: /blog/:name/
|
||||
permalink_defaults:
|
||||
pretty_urls:
|
||||
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
|
||||
trailing_html: true # Set to false to remove trailing '.html' from permalinks
|
||||
|
||||
# Directory
|
||||
source_dir: source
|
||||
public_dir: public
|
||||
tag_dir: tags
|
||||
archive_dir: archives
|
||||
category_dir: categories
|
||||
code_dir: downloads/code
|
||||
i18n_dir: :lang
|
||||
skip_render:
|
||||
|
||||
# Writing
|
||||
new_post_name: :title.md # File name of new posts
|
||||
default_layout: post
|
||||
titlecase: false # Transform title into titlecase
|
||||
external_link:
|
||||
enable: true # Open external links in new tab
|
||||
field: site # Apply to the whole site
|
||||
exclude: ""
|
||||
filename_case: 0
|
||||
render_drafts: false
|
||||
relative_link: false
|
||||
future: true
|
||||
post_asset_folder: true
|
||||
marked:
|
||||
prependRoot: true
|
||||
postAsset: true
|
||||
|
||||
# Math
|
||||
mathjax:
|
||||
tags: none # or 'ams' or 'all'
|
||||
single_dollars: true # enable single dollar signs as in-line math delimiters
|
||||
cjk_width: 0.9 # relative CJK char width
|
||||
normal_width: 0.6 # relative normal (monospace) width
|
||||
append_css: true # add CSS to pages rendered by MathJax
|
||||
every_page: true # if true, every page will be rendered by MathJax regardless the `mathjax` setting in Front-matter
|
||||
|
||||
# Highlight
|
||||
highlight:
|
||||
enable: true
|
||||
line_number: false
|
||||
auto_detect: false
|
||||
tab_replace: ""
|
||||
wrap: false
|
||||
hljs: true
|
||||
prismjs:
|
||||
enable: false
|
||||
|
||||
# Home page setting
|
||||
# path: Root path for your blogs index page. (default = '')
|
||||
# per_page: Posts displayed per page. (0 = disable pagination)
|
||||
# order_by: Posts order. (Order by date descending by default)
|
||||
index_generator:
|
||||
path: ""
|
||||
per_page: 20
|
||||
order_by: -date
|
||||
|
||||
# Category & Tag
|
||||
default_category: uncategorized
|
||||
category_map:
|
||||
tag_map:
|
||||
|
||||
# Metadata elements
|
||||
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
|
||||
meta_generator: true
|
||||
|
||||
# Date / Time format
|
||||
## Hexo uses Moment.js to parse and display date
|
||||
## You can customize the date format as defined in
|
||||
## http://momentjs.com/docs/#/displaying/format/
|
||||
date_format: YYYY-MM-DD
|
||||
time_format: HH:mm:ss
|
||||
## updated_option supports 'mtime', 'date', 'empty'
|
||||
updated_option: "mtime"
|
||||
|
||||
# Pagination
|
||||
## Set per_page to 0 to disable pagination
|
||||
per_page: 20
|
||||
pagination_dir: page
|
||||
|
||||
# Include / Exclude file(s)
|
||||
## include:/exclude: options only apply to the 'source/' folder
|
||||
# include:
|
||||
# exclude:
|
||||
ignore:
|
||||
|
||||
# Extensions
|
||||
## Plugins: https://hexo.io/plugins/
|
||||
## Themes: https://hexo.io/themes/
|
||||
theme: uio
|
||||
|
||||
# Feed
|
||||
feed:
|
||||
limit: 20
|
||||
order_by: "-date"
|
||||
tag_dir: "tag"
|
||||
category_dir: "category"
|
||||
rss:
|
||||
enable: false
|
||||
jsonFeed:
|
||||
enable: true
|
||||
output: "feed.json"
|
||||
atom:
|
||||
enable: true
|
||||
output: "feed.xml"
|
||||
|
||||
|
@@ -1,12 +0,0 @@
|
||||
---
|
||||
title: Deconvolutionと呼ぶのはもうやめよう
|
||||
date: 2017-03-05 13:44:00 +09:00
|
||||
---
|
||||
|
||||
深層学習において、Convolutional Layer (畳み込み層)とは、あるシェイプのテンソルをそれ以下のサイズに縮約する性質のレイヤーです。一方で Deconvolution Layer (逆畳み込み層)とは、[Jonathan Long, et al](https://arxiv.org/abs/1411.4038)の論文で提案されたレイヤーで、あるシェイプのテンソルをそれ以上のサイズに拡大する性質を持ちます。
|
||||
|
||||
ところが実際のところ、このレイヤーは Transposed Convolution Layer (転置畳み込み層)と呼ぶべきです。なぜかを以下に示します。
|
||||
|
||||
> Upsampling is backwards strided convolution. (アップサンプリングは
|
||||
|
||||
[Stack Exchange](http://datascience.stackexchange.com/questions/6107/what-are-deconvolutional-layers)での議論を踏まえると
|
@@ -1,11 +0,0 @@
|
||||
---
|
||||
title: 'gst: a powerful pal for ghq'
|
||||
date: 2017-06-02 23:02:00 +09:00
|
||||
---
|
||||
|
||||
[gst](https://github.com/uetchy/gst) is tiny and simple but powerful pal for [ghq](https://github.com/motemen/ghq).
|
||||
|
||||
Have you ever imagined what if you know which commits are unpushed or which changes are uncommitted yet, for all of the repositories you have cloned on your machine?
|
||||
|
||||
You might want to check out my ongoing project `gst`:
|
||||
it might help you to know what ongoing changes are remained to be committed or pushed among entire your local repositories.
|
@@ -1,46 +0,0 @@
|
||||
---
|
||||
date: 2020-03-16 18:19:11 +0900
|
||||
title: pixiv SPRING BOOT CAMP 2020
|
||||
---
|
||||
|
||||
[pixiv SPRING BOOT CAMP 2020](https://www.pixiv.co.jp/news/recruit/article/8728/)に参加した。インターン自体が初めてということもあり、普段とは種類の異なる様々な知見を得ることができたので共有したい。
|
||||
|
||||
## 選考
|
||||
|
||||
選考は Google Hangout Meet を用いたオンラインセッションで実施された。質問内容は以下の通りである。
|
||||
|
||||
- 自己紹介
|
||||
- コースの希望とその理由
|
||||
- 簡単なコーディングテスト
|
||||
|
||||
フロントエンドを希望したため、コーディングテストは JavaScript を用いてフォーム画面を設計するという内容になっていた。
|
||||
React を用いて MVP を実装し、それからインタビュワーのツッコミを打ち返すという形式であった。
|
||||
|
||||
選考結果は次の日に通知された。選考に関するフローは洗練されており、よく設計されているように感じた。
|
||||
|
||||
## オリエンテーション
|
||||
|
||||
- NDA
|
||||
- ラジオ体操
|
||||
- 自己紹介
|
||||
|
||||
## 業務
|
||||
|
||||
- iMac
|
||||
- YubiKey
|
||||
- 課題 1. psd.js の TypeScript 移植
|
||||
- 課題 2. 通知 API の JSON API 化+React 化
|
||||
- 同人誌入稿画面のレスポンシブ化
|
||||
- 新しい入稿フローの提案
|
||||
|
||||
### ランチ
|
||||
|
||||
- タコライス
|
||||
- LINE Pay
|
||||
- PayPay
|
||||
|
||||
## 成果発表
|
||||
|
||||
## 感想
|
||||
|
||||
### 社風
|
@@ -1,14 +0,0 @@
|
||||
---
|
||||
date: 2020-02-13 16:22:05 +0900
|
||||
title: 静寂を得る方法
|
||||
|
||||
---
|
||||
聴覚過敏であったり、そうでなくとも周りの音がパフォーマンスに悪影響となる人のために、静寂を得る方法を紹介します。
|
||||
|
||||
## EARIN M-2
|
||||
|
||||
[EARIN](https://earin.com/) は左右分離型Bluetoothイヤホンです。付属のイヤホンの代わりに自分の耳にフィットするComplyのイヤーチップと付け替えます。
|
||||
|
||||
## Moldex
|
||||
|
||||
Moldex は使い捨て耳栓のメーカーであり、各種遮音レベルに分かれた多様なラインナップを提供しています。
|
@@ -1,25 +0,0 @@
|
||||
<!-- Google Analytics -->
|
||||
<script>
|
||||
;(function(i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r
|
||||
;(i[r] =
|
||||
i[r] ||
|
||||
function() {
|
||||
;(i[r].q = i[r].q || []).push(arguments)
|
||||
}),
|
||||
(i[r].l = 1 * new Date())
|
||||
;(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0])
|
||||
a.async = 1
|
||||
a.src = g
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(
|
||||
window,
|
||||
document,
|
||||
'script',
|
||||
'https://www.google-analytics.com/analytics.js',
|
||||
'ga'
|
||||
)
|
||||
|
||||
ga('create', '{{ site.google_analytics }}', 'auto')
|
||||
ga('send', 'pageview')
|
||||
</script>
|
@@ -1,53 +0,0 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<link rel="shortcut icon" href="{{ site.baseurl }}/images/favicon.ico" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="{{ site.baseurl }}/images/apple-touch-icon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
href="{{ site.baseurl }}/images/favicon-32x32.png"
|
||||
sizes="32x32"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
href="{{ site.baseurl }}/images/favicon-16x16.png"
|
||||
sizes="16x16"
|
||||
/>
|
||||
|
||||
<link
|
||||
rel="mask-icon"
|
||||
href="{{ site.baseurl }}/images/safari-pinned-tab.svg"
|
||||
color="#5bbad5"
|
||||
/>
|
||||
|
||||
{% seo %} {% feed_meta %}
|
||||
|
||||
<!-- Normalize -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css"
|
||||
/>
|
||||
|
||||
<!-- Share -->
|
||||
<script
|
||||
defer
|
||||
src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8"
|
||||
id="facebook-jssdk"
|
||||
></script>
|
||||
<script
|
||||
defer
|
||||
src="https://platform.twitter.com/widgets.js"
|
||||
id="twitter-wjs"
|
||||
></script>
|
||||
|
||||
<!-- Styles -->
|
||||
<link rel="stylesheet" href="{{ site.baseurl }}/css/index.css" />
|
||||
</head>
|
@@ -1,9 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<section>
|
||||
<article class="article">
|
||||
<div class="article__content">{{ content }}</div>
|
||||
</article>
|
||||
</section>
|
@@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
{% include head.html %}
|
||||
|
||||
<body>
|
||||
{% include header.html %}
|
||||
{{ content }}
|
||||
{% include footer.html %}
|
||||
</body>
|
||||
</html>
|
@@ -1,26 +0,0 @@
|
||||
---
|
||||
title: Page Not Found
|
||||
permalink: "/404.html"
|
||||
excerpt: ''
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
{% include head.html %}
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 12em;
|
||||
font-weight: 100;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
{% include header.html %}
|
||||
<section class='page-section error-page'>
|
||||
<div class='container-narrow text-center py-md-8'>
|
||||
<h1>404</h1>
|
||||
<p class="lead">This page could not be found</p>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
@@ -1,53 +0,0 @@
|
||||
---
|
||||
permalink: "/"
|
||||
layout:
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
{% include head.html %}
|
||||
<body>
|
||||
<div class="metro">
|
||||
<h1 class="logo">
|
||||
<img src="{{ site.baseurl }}/images/logo.svg" style="height: 50px" />
|
||||
</h1>
|
||||
<nav>
|
||||
<ul class="menu">
|
||||
<li class="menu__item">
|
||||
<a href="/me">Me</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="https://github.com/{{ site.github.username }}">GitHub</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="https://twitter.com/{{ site.twitter.username }}"
|
||||
>Twitter</a
|
||||
>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="/wallpaper">Wallpaper</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<section>
|
||||
{% for post in site.posts %}
|
||||
<article class="article-list__item">
|
||||
<h2 class="article-list__item__title">
|
||||
<a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
|
||||
</h2>
|
||||
<!-- <time class="article-list__item__pubdate" pubdate>{{ post.date | date: '%B %d, %Y' }}</time> -->
|
||||
<article class="article-list__item__excerpt">
|
||||
{{ post.excerpt | strip_html | truncate: 140, "..." }}
|
||||
</article>
|
||||
<a
|
||||
class="article-list__item__button"
|
||||
href="{{ post.url | prepend: site.baseurl }}"
|
||||
>Read more</a
|
||||
>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% include footer.html %}
|
||||
</body>
|
||||
</html>
|
48
_pages/me.md
48
_pages/me.md
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: Yasuaki Uechi
|
||||
permalink: "/me"
|
||||
layout: article
|
||||
---
|
||||
|
||||
<style>
|
||||
img {
|
||||
width: auto !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
# README
|
||||
|
||||
> I'm **Yasuaki Uechi**, a graduate student studying about recurrent neural networks. I was born in Okinawa, Japan in 1994 and have been living in Kanagawa.
|
||||
|
||||
# Contact
|
||||
|
||||
Reach me at `y@uechi.io` (recommended) or [@uechz](https://twitter.com/uechz) on Twitter. Beware that I'm not a person of quick reply so if you are in urgent need of a lightning response better bomb my inbox with reminders so I can prioritize your email than any other emails.
|
||||
|
||||
## GPG Key
|
||||
|
||||
Get [GPG Key](https://github.com/uetchy.gpg) on GitHub.
|
||||
|
||||
# Facts
|
||||
|
||||
- play violin, tin whistle, piano, and bodhrán. Logic Pro user.
|
||||
- overall interests: ux/graphic design, webdev, machine learning (mainly nlp and generative design), behavioral economics, organization government, irish music, coffee, puzzle game
|
||||
- dev interests: react, nodejs, rust, docker
|
||||
- have confidence in: javascript (incl. nodejs and typescript), python, ux design, baremetal server, english
|
||||
- have no confidence in: normal life stuff
|
||||
- have some experience in: swift, go, ruby, rust, c++, pytorch
|
||||
- language skills:
|
||||
- Japanese: native
|
||||
- English: TOEIC 940, TOEFL 78
|
||||
- Chinese, Korean, Indonesian, German, Russian: current objectives still n00b though
|
||||
- typeface fanatic
|
||||
|
||||
# Publishing
|
||||
|
||||
- [Open Source @ GitHub](https://github.com/uetchy)
|
||||
- [Technical Note (English) @ dev.to](https://dev.to/uetchy)
|
||||
- [Technical Note (Japanese) @ Qiita](https://qiita.com/uetchy)
|
||||
- [Design Portfolio @ Behance](https://www.behance.net/uechi)
|
||||
|
||||
# Current Activity
|
||||
|
||||
- Seeking for a job
|
@@ -1,60 +0,0 @@
|
||||
---
|
||||
title: Pay
|
||||
permalink: "/pay"
|
||||
layout: default
|
||||
---
|
||||
|
||||
<div id="pay">
|
||||
<section>
|
||||
<p>
|
||||
送金方法はオススメ順に並んでいます。いずれか都合の良い方法で送金または請求してください。
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h1>Kyash</h1>
|
||||
<p>
|
||||
QRコードをスキャンするか、Kyash ID
|
||||
<span class="monospace">uechi</span> 宛に送金・請求してください。
|
||||
</p>
|
||||
<img src="/images/payment/kyash.png" width="200" height="200" />
|
||||
<a class="button" href="kyash://qr/u/7175222723044580164">Kyashを開く</a>
|
||||
<br />
|
||||
</section>
|
||||
<section>
|
||||
<h1>LINE Pay</h1>
|
||||
<p>LINE宛に送金・請求してください。</p>
|
||||
<a class="button" href="https://line.me/ja/pay">LINE Payについて</a>
|
||||
</section>
|
||||
<section>
|
||||
<h1>Revolut</h1>
|
||||
<p><span class="monospace">yasuakpnqg</span> 宛にお送りください。</p>
|
||||
<a class="button" href="https://pay.revolut.com/profile/yasuakpnqg"
|
||||
>Revolutを開く</a
|
||||
>
|
||||
</section>
|
||||
<section>
|
||||
<h1>Amazon ギフトカード</h1>
|
||||
<p>
|
||||
メッセージアプリ経由で、または
|
||||
<span class="monospace">y@uechi.io</span> 宛にお送りください。
|
||||
</p>
|
||||
<a class="button" href="https://www.amazon.co.jp/gp/product/B004N3APGO/"
|
||||
>Amazonを開く</a
|
||||
>
|
||||
</section>
|
||||
<section>
|
||||
<h1>PayPay</h1>
|
||||
<p>QRコードをスキャンして送金してください。</p>
|
||||
<img src="/images/payment/paypay.png" width="200" height="200" />
|
||||
<a class="button" href="https://paypay.ne.jp/">PayPayについて</a> <br />
|
||||
</section>
|
||||
<section>
|
||||
<h1>PayPal</h1>
|
||||
<p>
|
||||
PayPalで
|
||||
<span class="monospace">y@uechi.io</span> 宛に送金・請求してください。
|
||||
</p>
|
||||
<a class="button" href="https://paypal.me/uetchy">PayPalを開く</a>
|
||||
<br />
|
||||
</section>
|
||||
</div>
|
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: Wallpapers
|
||||
permalink: "/wallpaper"
|
||||
layout: post
|
||||
---
|
||||
|
||||
Right-click and choose **Save Image** to download my wallpapers. All following pictures are my own work and are published on Creative Commons BY-NC-SA.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<div><img src="{{ site.baseurl }}/images/wallpaper/vertex.png" /></div>
|
||||
<div style="margin-left: 20px"><img src="{{ site.baseurl }}/images/wallpaper/vertex2.png" /></div>
|
||||
</div>
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Monochrome
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
@@ -1,83 +0,0 @@
|
||||
---
|
||||
title: 生活の自動化
|
||||
date: 2018-08-05 00:00:00 +09:00
|
||||
redirect_from: "/blog/2018/08/05/life-automation"
|
||||
---
|
||||
|
||||
生活にオートメーションを上手く取り入れ、本当にやりたいことや、やるべきことに集中できる環境をつくろう。
|
||||
|
||||
# 洗濯の自動化
|
||||
|
||||
Panasonic のドラム洗濯乾燥機を使っている。威力を最大限に享受するため、タンブラー乾燥向けの普段着を揃えておくことも重要だ。
|
||||
洗剤は粉と液体とが一体化したジェルボール洗剤が便利。ドラムの底にひとつ置くだけでよく、計量する必要がない。
|
||||
|
||||
# 食器洗いの自動化
|
||||
|
||||
Panasonic NC-TCR2 という一人暮らし用のコンパクト食洗乾燥機が便利。
|
||||
洗濯機と同じく食洗機専用のジェルボール洗剤を使えば計量する手間を省ける。
|
||||
|
||||
# 照明の自動化
|
||||
|
||||
Hue はインターネット経由で明るさや色相をコントロールすることができる電球である。
|
||||
|
||||
- 「家から離れたら消灯」
|
||||
- 「家に近付いたら点灯」
|
||||
- 「日が暮れたら暖色系に切り替える」
|
||||
- 「23 時になったら消灯」
|
||||
|
||||
など多様なルールを作ることができる。
|
||||
家では外の明るさに合わせて照明の明るさを調整して、概日リズムが崩れにくいようにルールを決めている。
|
||||
|
||||
# 空調の自動化
|
||||
|
||||
Nature Remo でエアコンの操作を自動化した。
|
||||
|
||||
- 「湿度が高ければドライに変更」
|
||||
- 「家から離れたら電源オフ」
|
||||
- 「朝になったら冷房へ切り替え」
|
||||
|
||||
など多様なルールを作ることができる。
|
||||
|
||||
Nature Remo 自体はエアコン専用ではなく、赤外線で操作出来るデバイスであればなんでも操作できる。家ではテレビもこれで操作している。
|
||||
|
||||
ちなみに[Nature Remo を NodeJS で操作することができるライブラリ](https://github.com/uetchy/nature-remo)を作ったので、是非使ってみて欲しい。ライブラリ経由で温度・湿度・明度のセンサー値を取得したり、指定したモードにエアコンを切り替えることができる。
|
||||
|
||||
# 自動施錠・自動開錠
|
||||
|
||||
Qrio Lock をドアに取り付けることでオートロックとオートアンロックができるようになった。
|
||||
|
||||
# 睡眠記録の自動化
|
||||
|
||||
Withings 改め Nokia の Sleep を使っている。
|
||||
睡眠を計測する際、身体にウェアラブルデバイスを身につける必要がないという点で、Nokia Sleep は Apple Watch や Fitbit よりも優れている。
|
||||
|
||||
機能としては、入眠・起床検知、心拍数記録、睡眠深度解析、いびき検出、IFTTT 連携がある。
|
||||
|
||||
# 体重記録の自動化
|
||||
|
||||
Withings の Wi-Fi Scale を使っている。体重と体脂肪率、心拍数、BMI を Wi-Fi 経由でクラウドに自動記録し、Apple Health などで推移を確認できる。
|
||||
|
||||
Wi-Fi Scale には CO2 センサーもついており、部屋の二酸化炭素濃度を記録してくれる。
|
||||
|
||||
# コーヒー豆のサブスクリプション
|
||||
|
||||
珈琲きゃろっとのサブスクリプションを利用している。
|
||||
|
||||
# オンラインスーパー
|
||||
|
||||
イトーヨーカドーのオンラインスーパーを使っている。お気に入りリストへ牛乳、オレンジ、ベーコン、卵など毎回買うものを登録しておくことで、慣れれば 5 分程度で注文が完了する。あとは指定した時間に家へ商品を届けてくれる。
|
||||
|
||||
# 自動家計簿
|
||||
|
||||
MoneyForward を使っている。支出を自動で食費、趣味、日用品などに仕分けてくれる。
|
||||
無現金縛りプレイと相性が良い。
|
||||
|
||||
# 自炊の効率化
|
||||
|
||||
最近 COMP で食事を置き換え始めた。まだ評価は出来ないが少なくとも味は悪くなく(薄いきな粉のような味)、不足しがちなビタミンや鉄分を補える点では良い製品だと思う。
|
||||
|
||||
# 気になる製品
|
||||
|
||||
## ルンバ
|
||||
|
||||
ルンバは気になるが、絨毯を取り除くわけにもいかないので二の足を踏んでいる。ルンバについては[KainokiKaede's diary](http://kainokikaede.hatenablog.com/entry/2018/07/24/185452)の素晴らしい記事を読んで欲しい。
|
15
docker-compose.production.yml
Normal file
15
docker-compose.production.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
version: "3.0"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: ghcr.io/uetchy/uechi.io
|
||||
container_name: uechi.io
|
||||
environment:
|
||||
VIRTUAL_HOST: uechi.io
|
||||
LETSENCRYPT_HOST: uechi.io
|
||||
labels:
|
||||
com.centurylinklabs.watchtower.enable: "true"
|
||||
networks:
|
||||
default:
|
||||
name: webproxy
|
||||
external: true
|
8
docker-compose.yml
Normal file
8
docker-compose.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
version: "3.0"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: ghcr.io/uetchy/uechi.io
|
||||
build: .
|
||||
ports:
|
||||
- "8080:80"
|
46
nginx.conf
Normal file
46
nginx.conf
Normal file
@@ -0,0 +1,46 @@
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
access_log /var/log/nginx/access.log;
|
||||
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
root /var/www/html;
|
||||
error_page 404 /404.html;
|
||||
|
||||
location /404.html {
|
||||
internal;
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location / {
|
||||
index index.html;
|
||||
try_files $uri $uri.html $uri/index.html =404;
|
||||
}
|
||||
|
||||
location = / {
|
||||
if ($http_user_agent ~ curl) {
|
||||
rewrite / /TERMINAL last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
package.json
41
package.json
@@ -1,19 +1,42 @@
|
||||
{
|
||||
"name": "uechi.io",
|
||||
"name": "hexo-site",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"fix-typo": "textlint _posts/*.md _pages/*.md --fix --dry-run -f diff",
|
||||
"build": "bundle exec jekyll build",
|
||||
"start": "bundle exec jekyll serve --host 0.0.0.0 --port 4000 --baseurl '' --force_polling --drafts --unpublished --incremental",
|
||||
"test": "textlint _posts/*.md _pages/*.md -f pretty-error"
|
||||
"build": "hexo generate",
|
||||
"clean": "hexo clean",
|
||||
"deploy": "hexo deploy",
|
||||
"start": "yarn clean && hexo server --debug",
|
||||
"test": "lint-staged"
|
||||
},
|
||||
"dependencies": {
|
||||
"hexo": "^6.0.0",
|
||||
"hexo-excerpt": "^1.2.1",
|
||||
"hexo-feed": "^1.1.0",
|
||||
"hexo-filter-mathjax": "^0.8.0",
|
||||
"hexo-generator-archive": "^1.0.0",
|
||||
"hexo-generator-category": "^1.0.0",
|
||||
"hexo-generator-index": "^2.0.0",
|
||||
"hexo-generator-tag": "^1.0.0",
|
||||
"hexo-renderer-ejs": "^2.0.0",
|
||||
"hexo-renderer-pandoc": "^0.3.0",
|
||||
"hexo-renderer-sass": "^0.4.0",
|
||||
"hexo-renderer-stylus": "^2.0.0",
|
||||
"hexo-server": "^3.0.0",
|
||||
"hexo-theme-landscape": "^0.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"textlint": "^11.7.6",
|
||||
"lint-staged": "^10.5.4",
|
||||
"textlint": "^11.9.0",
|
||||
"textlint-filter-rule-whitelist": "^2.0.0",
|
||||
"textlint-rule-common-misspellings": "^1.0.1",
|
||||
"textlint-rule-max-ten": "^2.0.4",
|
||||
"textlint-rule-no-dropping-the-ra": "^1.1.3",
|
||||
"textlint-rule-no-start-duplicated-conjunction": "^2.0.2",
|
||||
"textlint-rule-preset-japanese": "^5.0.0"
|
||||
"textlint-rule-preset-japanese": "^6.0.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.md": "textlint"
|
||||
},
|
||||
"hexo": {
|
||||
"version": "5.4.0"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
4
scaffolds/draft.md
Normal file
4
scaffolds/draft.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: {{ title }}
|
||||
tags:
|
||||
---
|
3
scaffolds/page.md
Normal file
3
scaffolds/page.md
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
title: {{ title }}
|
||||
---
|
5
scaffolds/post.md
Normal file
5
scaffolds/post.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: {{ title }}
|
||||
date: {{ date }}
|
||||
tags:
|
||||
---
|
7
source/404.md
Normal file
7
source/404.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Page Not Found
|
||||
permalink: "/404"
|
||||
---
|
||||
|
||||
> `404`
|
||||
> This page could not be found
|
8
source/TERMINAL
Normal file
8
source/TERMINAL
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
░█░█░█▀▀░█▀▀░█░█░▀█▀░░░░▀█▀░█▀█
|
||||
░█░█░█▀▀░█░░░█▀█░░█░░░░░░█░░█░█
|
||||
░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░░▀▀▀░▀▀▀
|
||||
|
||||
GitHub: https://github.com/uetchy
|
||||
Twitter: https://twitter.com/uechz
|
||||
Wallpaper: https://uechi.io/wallpaper
|
@@ -132,7 +132,7 @@ Notes.app に移行しました。
|
||||
|
||||
## Flash
|
||||
|
||||
ニコニコ動画が見れなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
|
||||
ニコニコ動画が見られなくなるので泣く泣く導入していましたが、公式で HTML5 に対応したので不要になりました。
|
||||
|
||||
## [VirtualBox](https://www.virtualbox.org)
|
||||
|
@@ -4,9 +4,19 @@ date: 2017-06-16 00:00:00 +09:00
|
||||
redirect_from: "/blog/2017/06/16/x11forward"
|
||||
---
|
||||
|
||||

|
||||

|
||||
|
||||
## Ubuntu 16.04
|
||||
# Installation
|
||||
|
||||
## Remote
|
||||
|
||||
### Arch Linux
|
||||
|
||||
```bash
|
||||
pacman -S xorg-xauth xorg-fonts-100dpi xorg-xeyes
|
||||
```
|
||||
|
||||
### Ubuntu 16.04
|
||||
|
||||
Make sure you have installed SSH, X11 and xAuth on a remote server.
|
||||
|
||||
@@ -16,12 +26,12 @@ sudo sed -i '/ForwardX11/s/.*/ForwardX11 yes/' /etc/ssh/sshd_config
|
||||
sudo service ssh restart
|
||||
```
|
||||
|
||||
## macOS Sierra
|
||||
## Client (macOS Big Sur)
|
||||
|
||||
You also need to have X11 on your local machine.
|
||||
|
||||
```
|
||||
brew cask install xquartz # install X11
|
||||
brew install xquartz # install X11
|
||||
ssh -X <remote>
|
||||
$ xeyes # verify you have X11
|
||||
```
|
@@ -1,7 +1,8 @@
|
||||
---
|
||||
title: 初キャンプに必要な機材
|
||||
date: 2018-04-13 14:26:00 +09:00
|
||||
redirect_from: "/blog/2018/04/13/camping"
|
||||
redirect_from:
|
||||
- "/blog/2018/04/13/camping"
|
||||
---
|
||||
|
||||
先月、大洗で初めてのキャンプ泊をした。
|
@@ -3,11 +3,11 @@ title: Know your deps on package.json in seconds
|
||||
date: 2018-09-02 03:23:00 +09:00
|
||||
---
|
||||
|
||||

|
||||
|
||||
How do you know what packages that project/library depend on and what exactly are that packages doing for?
|
||||
You'll want to quickly survey on them. So [npm-deps-list](https://github.com/uetchy/npm-deps-list) is here for.
|
||||
|
||||

|
||||
|
||||
You can install them using `npm` or `yarn`.
|
||||
|
||||
```bash
|
||||
@@ -18,4 +18,4 @@ Running `ndl`, you will get a detailed list of dependencies for the package on t
|
||||
|
||||
If you are using iTerm2, you can also `Command + Click` on a package name to jump to their homepage.
|
||||
|
||||
If you have any idea on it, please consider submitting an issue or a pull request!
|
||||
If you have any idea on it, please consider submitting an issue or a pull request!
|
84
source/_posts/2018/life-automation.md
Normal file
84
source/_posts/2018/life-automation.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: 生活の自動化
|
||||
date: 2018-08-05 00:00:00 +09:00
|
||||
redirect_from: "/blog/2018/08/05/life-automation"
|
||||
---
|
||||
|
||||
生活にオートメーションを上手く取り入れ、本当にやりたいことに集中できる環境をつくりましょう。
|
||||
|
||||
# 洗濯の自動化
|
||||
|
||||
Panasonic のドラム洗濯乾燥機を使っています。威力を最大限に享受するため、タンブラー乾燥向けの普段着を揃えておくことも重要です。
|
||||
|
||||
洗剤は粉と液体とが一体化したジェルボール洗剤が便利です。ドラムの底にひとつ置くだけでよく、計量する必要がありません。
|
||||
|
||||
# 食器洗いの自動化
|
||||
|
||||
Panasonic の一人暮らし用コンパクト食洗乾燥機を使っています。
|
||||
洗濯機と同じく、食洗機専用のジェルボール洗剤を使えば計量する手間を省けます。
|
||||
|
||||
# 照明の自動化
|
||||
|
||||
Philips Hue はインターネット経由で明るさや色相をコントロールすることができる電球です。
|
||||
|
||||
- 「家から離れたら消灯」
|
||||
- 「家に近付いたら点灯」
|
||||
- 「日が暮れたら暖色系に切り替える」
|
||||
- 「23 時になったら消灯」
|
||||
|
||||
など多様なルールを作ることができます。外の明るさに合わせて照明の明るさを調整して、概日リズムが崩れにくいようルールを決めています。
|
||||
|
||||
# 空調の自動化
|
||||
|
||||
Nature Remo でエアコンの操作を自動化しました。
|
||||
|
||||
- 「湿度が高ければドライに変更」
|
||||
- 「家から離れたら電源オフ」
|
||||
- 「朝になったら冷房へ切り替え」
|
||||
|
||||
など多様なルールを作ることができます。
|
||||
|
||||
Nature Remo 自体はエアコン専用ではなく、赤外線で操作出来るデバイスであればなんでも操作できます。家ではテレビの電源・音量もこれで操作しています。
|
||||
|
||||
[Nature Remo を NodeJS で操作するライブラリ](https://github.com/uetchy/nature-remo)を作ったので触ってみてください。ライブラリ経由で温度・湿度・明度のセンサー値を取得したり、指定したモードにエアコンを切り替えることができます。
|
||||
|
||||
# 自動施錠・自動開錠
|
||||
|
||||
Qrio Lock をドアに取り付けることでオートロック・アンロックができるようになりました。
|
||||
|
||||
エントランスのドアに関しては、インターホンに Switch Bot を貼り付けて Shortcuts で解錠できるようにしておき、それを iPhone の背面トリプルタップで呼び出せるよう設定することでキーレスエントリー化しています。
|
||||
|
||||
# ホームアシスタント
|
||||
|
||||
Raspberry Pi に Home Assistant をインストールし、スマート家電を取りまとめるアシスタントとして使っています。Nature Remo や Hue、Switch Bot に紐づいているデバイスを Home Assistant のアプリからまとめて操作できます。
|
||||
|
||||
Apple Home より柔軟な自動化ルールを作ることができ、例えば「朝になったら照明とエアコンをつける(気温が高くかつ誰かが家にいる場合のみ)」といった気の利いた自動化ができます。
|
||||
|
||||
# 睡眠記録の自動化
|
||||
|
||||
Withings 改め Nokia 改め Withings の Sleep を使っています。
|
||||
寝るとき身体にウェアラブルデバイスを身につけたくないので、マットレスの下に敷いておくだけで自動計測してくれるのはありがたいです。
|
||||
|
||||
機能としては、入眠・起床検知、心拍数記録、睡眠深度解析、いびき検出等があります。
|
||||
|
||||
# 体重記録の自動化
|
||||
|
||||
Withings の Wi-Fi Scale を使っています。体重と体脂肪率、心拍数、BMI を Wi-Fi 経由でクラウドに自動記録し、アプリで推移を確認できます。
|
||||
|
||||
Wi-Fi Scale には CO2 センサーもついており、部屋の二酸化炭素濃度を記録してくれます。
|
||||
|
||||
# オンラインスーパー
|
||||
|
||||
普段は業務スーパーを使いつつ、重くて量のある商品に関してはイトーヨーカドーのオンラインスーパーに頼っています。
|
||||
|
||||
お気に入りリストへ水、米、卵、かぼちゃなど毎回買うものを登録しておくことで、慣れれば 5 分程度で注文が完了します。あとは指定した時間に家へ商品を届けてくれます。
|
||||
|
||||
# 自動家計簿
|
||||
|
||||
Moneytree を使っています。支出を自動で食費、趣味、日用品などに仕分けてくれるため、使いすぎに気付きやすいです。無現金縛りプレイと相性が良いです。
|
||||
|
||||
# 気になる製品
|
||||
|
||||
## ルンバ
|
||||
|
||||
絨毯を取り除くわけにもいかないので二の足を踏んでいます。ルンバについては[KainokiKaede's diary](http://kainokikaede.hatenablog.com/entry/2018/07/24/185452)の記事を読んでください。
|
@@ -2,8 +2,10 @@
|
||||
title: 英語メモ
|
||||
date: 2019-01-17T10:31:00.000+00:00
|
||||
redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
---
|
||||
|
||||
雑多なメモです。
|
||||
|
||||
- spin up - 立ち上げる
|
||||
- woe - 悲しみ
|
||||
- a little too - 少し〜すぎる
|
||||
@@ -27,7 +29,7 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
- three-fold — 三倍
|
||||
- evade — 避ける = avoid
|
||||
- a word that evades definition — 定義しにくい言葉
|
||||
- don't be fooled by A — Aに惑わされるな
|
||||
- don't be fooled by A — A に惑わされるな
|
||||
- thrice — とても
|
||||
- Circuit Judge Joseph Bulone called 49-year-old Michael Drejka a “wanna-be” law enforcement officer and a self-appointed “handicapped parking space monitor.”
|
||||
- encapsulate — 包容している
|
||||
@@ -36,15 +38,15 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
- SMDH — Shaking My Damn Head
|
||||
- micro stutter — プログラム上の細微な遅延
|
||||
- When characters are missing from fonts, it's nice to be able to communicate to the user that this happened. — フォントに文字が欠けている場合、それをユーザーに伝えることができると便利です。
|
||||
- for the sake of A — Aの名のもとに
|
||||
- Firefox has abandoned subpixel-AA for the sake of simplicity — Firefoxはシンプルさの名のもとにサブピクセルAAを棄てました。
|
||||
- for the sake of A — A の名のもとに
|
||||
- Firefox has abandoned subpixel-AA for the sake of simplicity — Firefox はシンプルさの名のもとにサブピクセル AA を棄てました。
|
||||
- The entire idea behind subpixel-AA is that you are abusing how the pixels are laid out in a display. — サブピクセルアンチエイリアスは、ディスプレイにピクセルがどのように配置されているかという知識を基に成り立っています。
|
||||
- a reasonable balance — 適度なバランス
|
||||
- That said, — とはいえ、
|
||||
- A with B on it — Bが乗っているA
|
||||
- can play a bit fast and loose with A — Aを大雑把に扱える
|
||||
- current iteration of A — 現行のA
|
||||
- A doesn't play nice with B — BがためAが上手く動かない
|
||||
- A with B on it — B が乗っている A
|
||||
- can play a bit fast and loose with A — A を大雑把に扱える
|
||||
- current iteration of A — 現行の A
|
||||
- A doesn't play nice with B — B がため A が上手く動かない
|
||||
- our current iteration of search doesn't play nice with CJK characters
|
||||
- Tried out and see what happens — 試して成り行きを見てみた
|
||||
- Losing your shit — the state of being pushed over the edge of sanity and having a complete and utter freak out or mental/emotional breakdown ≒ お前は完全にイッちまうぜ
|
||||
@@ -54,11 +56,11 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
> Have you thought of what you’ll do after you retire? — 引退したらやりたいことについて考えたことある?
|
||||
|
||||
- any of those — これらどれでも (all of, everyと交換可能 | 肯定文)
|
||||
- any of those — これらどれでも (all of, every と交換可能 | 肯定文)
|
||||
|
||||
- there aren't any apples on the floor (否定の場合はanyの後に複数形)
|
||||
- there aren't any apples on the floor (否定の場合は any の後に複数形)
|
||||
|
||||
- you will likely do A — あなたはAすることだろう
|
||||
- you will likely do A — あなたは A することだろう
|
||||
|
||||
- 99% of the time this is what you want to use — 99%これを使えば良い
|
||||
|
||||
@@ -72,13 +74,13 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
- one week cannot and should not define any team
|
||||
|
||||
- it go to show that A — Aということの証明となる
|
||||
- it go to show that A — A ということの証明となる
|
||||
|
||||
- A is to not have B — 「A」とは、Bを持たないことである
|
||||
- A is to not have B — 「A」とは、B を持たないことである
|
||||
|
||||
> wireless charging is kinda funny because it really goes to show that the only way to get the tech industry to agree on a unified connector is to not have a connector
|
||||
|
||||
> me: it’s not that I mind freelancing, I love it. It’s just that the social interaction is pretty minimal and extremely uneven day-to-day and sometimes I wonder how that will affect me long term, you know?
|
||||
> me: it’s not that I mind freelancing, I love it. It’s just that the social interaction is pretty minimal and extremely uneven day-to-day and sometimes I wonder how that will affect me long term, you know?
|
||||
> barista: ok are you going to order
|
||||
|
||||
- constitute, make up
|
||||
@@ -94,8 +96,6 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
> It uses the definite article before "majority of the students", as if referring to a known group.
|
||||
|
||||
> Next piece is gonna be a super mega holy shit giantess 👍👍👍
|
||||
|
||||
> This sentence uses the indefinite article before the "majority of the students". This has the effect of introducing this group of students to the reader or the listener.
|
||||
|
||||
> It may give a hint that the exact number of the students that will vote is uncertain: it could be 51%, but then it could be 88%.
|
||||
@@ -104,7 +104,7 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
- at will — 意思次第で
|
||||
- for asking — 望むなら
|
||||
- fuck A up — Aをボコボコにする
|
||||
- fuck A up — A をボコボコにする
|
||||
- friendly reminder - a euphemism for "this is the last warning"
|
||||
- I feel attached
|
||||
- I feel called out
|
||||
@@ -113,19 +113,19 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
- LRT: My favorite part of this is the upload on Youtube that's titled "Iwata vs Reggie (full fight)" like it was stitched together from multiple episodes of Naruto.
|
||||
- get around to — 先延ばしにしていたことにやっと取り掛かる
|
||||
- Finally got around to writing something on @ThePracticalDev, which was a really great experience!
|
||||
- Finally got around to writing something on @ThePracticalDev, which was a really great experience!
|
||||
- wordy, lengthy — 言葉の多い、冗長な
|
||||
- A teenager not old to buy a six-pack — ビールも買えない年頃の子供
|
||||
- It is likely that 未来形 — 〜になるだろう
|
||||
- It's likely that the affair will come to nothing — どうやら無事に治まりそうだ
|
||||
- We will most likely do A — 我々は必ずAをするでしょう
|
||||
- We will most likely do A — 我々は必ず A をするでしょう
|
||||
- chirring - 虫が鳴く; bugs chirring
|
||||
- what are you waiting for
|
||||
- with a grain of salt — 割り引いて(考えて)
|
||||
|
||||
> learning foreign languages is for me lifelong hobby. knowledge likely to requires much time to acquiring but it never decays.
|
||||
|
||||
> *sees client, whistles loudly*
|
||||
> _sees client, whistles loudly_
|
||||
|
||||
> weston comes out of nowhere running on all fours like a gorilla towards client
|
||||
|
||||
@@ -133,7 +133,7 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
> And what could go wrong, in depending on the internet to keep the child warm
|
||||
|
||||
> the developer advocate in question understands the language barrier, it would seem; he’s not a native English speaker. regardless, his stance puts many who haven’t had a strong English education at a disadvantage. it prioritizes “getting things done” over people...
|
||||
> the developer advocate in question understands the language barrier, it would seem; he’s not a native English speaker. regardless, his stance puts many who haven’t had a strong English education at a disadvantage. it prioritizes “getting things done” over people...
|
||||
|
||||
> save my dying cactus. what's wrong. cactus should have been easy stuff since they barely need water.
|
||||
|
||||
@@ -162,10 +162,10 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
> i feel like i'm most productive when i'm avoiding some other kind of responsibility
|
||||
|
||||
- be more of A — どちらかといえばAである; He is more of a researcher.
|
||||
- be more of A thant B — BというよりむしろAだ
|
||||
- be more of A — どちらかといえば A である; He is more of a researcher.
|
||||
- be more of A thant B — B というよりむしろ A だ
|
||||
- see less pain but also less joy — 痛みを感じることも少ないが喜びも少ない
|
||||
- in term of A — Aの観点から
|
||||
- in term of A — A の観点から
|
||||
|
||||
## Go
|
||||
|
||||
@@ -178,7 +178,7 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
- get over it (障害を)乗り越えろ
|
||||
- get out 出て行く
|
||||
- get down on A for B — Bしたことに大してAを批判し続ける
|
||||
- get down on A for B — B したことに大して A を批判し続ける
|
||||
- get down to [verb.] — やっと始める。
|
||||
- get in — 乗り込む
|
||||
- too much to take - 手に負えない
|
||||
@@ -213,7 +213,7 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
> Because he's the kind of person who likes helping others and is always gentle and kind as you described
|
||||
|
||||
> it was more difficult to get it wrong than guess it right!
|
||||
> XD
|
||||
> XD
|
||||
|
||||
> I'm pretty sure there was a lot of uproar about the Equifax thing
|
||||
|
||||
@@ -224,14 +224,14 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
- just a citation of the law they're overcompensating for — 彼らは濫用している法律の引用ただそれだけしか示してない
|
||||
- repeal — 撤回する
|
||||
- no respect for their users — ユーザーに対する敬意がない
|
||||
- be now going the A route — 今度はA作戦ときた
|
||||
- be now going the A route — 今度は A 作戦ときた
|
||||
- in a blunt fashion — 露骨なやり方で
|
||||
- "DM us, we'll take a look!" faux-friendly route — 偽りの友情作戦「DMで詳しく話を聞かせて!」
|
||||
- "DM us, we'll take a look!" faux-friendly route — 偽りの友情作戦「DM で詳しく話を聞かせて!」
|
||||
- reinstate — (アカウントを)復活させる
|
||||
- shut the whole thing down — 全てを終わらせる
|
||||
- as if, as though — 後者は話者の疑いが現れている. 仮定法過去を取る. It's as if I were a movie star.
|
||||
- predominatly — 大抵は. Your costs are predominantly human labor.
|
||||
- a myriad of A — 無数のA
|
||||
- a myriad of A — 無数の A
|
||||
- funnel toward 狭いところを前へと通る
|
||||
- in a verifiable manner — 検証可能な方法で
|
||||
- in a frigid manner — 冷たい態度で
|
||||
@@ -257,7 +257,7 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
- If you're of the belt-and-suspenders mindset, consider setting UsePAM to 'no' as well. — 心配性な性格のこと
|
||||
- you can cancel it as long as it has not been matched — 〜されていない限りいつでも
|
||||
- By definition — 定義によると
|
||||
- A found B C — AはBがCだと思った
|
||||
- A found B C — A は B が C だと思った
|
||||
- in that — という点において
|
||||
- Iconoclast — 因襲打破主義者
|
||||
|
||||
@@ -282,41 +282,41 @@ redirect_from: "/blog/2019/01/17/english-note"
|
||||
|
||||
- it drives me crazy [nuts] — イライラさせられる
|
||||
- describes the steps that are involved in ~ — ~に関する手順について説明する
|
||||
- 前置詞inは特徴の違いを、ofは程度の違いを表す
|
||||
- A is in proportion to B — AはBに比例している
|
||||
- A is out of proportion to B — AはBに反比例している
|
||||
- 受動態は不自然に手を加えられて発生した結果に付随する、能動態は自然に発生した場合に付随する — our profits were increasedは不正があったかのような表現、our profits increasedが正しい
|
||||
- be collectively known as A — Aと総称されている
|
||||
- 前置詞 in は特徴の違いを、of は程度の違いを表す
|
||||
- A is in proportion to B — A は B に比例している
|
||||
- A is out of proportion to B — A は B に反比例している
|
||||
- 受動態は不自然に手を加えられて発生した結果に付随する、能動態は自然に発生した場合に付随する — our profits were increased は不正があったかのような表現、our profits increased が正しい
|
||||
- be collectively known as A — A と総称されている
|
||||
- Any links to this, as to be honest nobody is providing evidence, just lip-service relying on the ignorance of most readers
|
||||
- in a great hurry - 大急ぎで
|
||||
- gross 名詞 — 明らかな〜, a gross oversimplification - 明らかに過度な簡略化
|
||||
- among — 〜の間で — in, throughで代替可能
|
||||
- throw A away — Aを捨てる、Aを無駄にする
|
||||
- among — 〜の間で — in, through で代替可能
|
||||
- throw A away — A を捨てる、A を無駄にする
|
||||
- throw A up — 急にやめる
|
||||
- be quick to — すぐ〜する。(People are quick to alienate outsiders 人々はすぐよそ者を阻害する)
|
||||
- incredulous at — 〜を容易に信じない
|
||||
- lack of standards for — 〜に対するけじめの無さ
|
||||
- ludicrous, ridiculous — 馬鹿げた
|
||||
- derogatory — 差別的な
|
||||
- A that it was B — Aだったので、B , 便利な接続詞
|
||||
- A that it was B — A だったので、B , 便利な接続詞
|
||||
- After (p.p.), He (p.) — 〜の後、彼は〜した
|
||||
- vicious — 凶悪な
|
||||
- relentless, ruthless — しつこく、inの時は徹底的な
|
||||
- relentless, ruthless — しつこく、in の時は徹底的な
|
||||
- mercilessly — 無慈悲に
|
||||
- reckless — 無謀な
|
||||
- profound — 心理的影響が重大な、深刻な(物理的にはdeepが適切)
|
||||
- profound — 心理的影響が重大な、深刻な(物理的には deep が適切)
|
||||
|
||||
> I felt like a coward hiding this from people — それを隠すことで自分が臆病者に思えた
|
||||
|
||||
> While training for the marathon, she was relentless in following the same schedule — マラソンの練習の間、彼女は同じスケジュールをしつこいほど守った。
|
||||
|
||||
- His history of A led to B — 彼がAを繰り返したせいでBを招いた。
|
||||
- His history of A led to B — 彼が A を繰り返したせいで B を招いた。
|
||||
- hatred — 憎悪
|
||||
- coarse — 粗い
|
||||
- B with A everywhere — Aがいたるところに散乱しているB
|
||||
- B with A everywhere — A がいたるところに散乱している B
|
||||
- people, all, the crowd — 人々
|
||||
|
||||
> A was quick to spot the potential of the Internet — Aはインターネットの可能性をいち早く見出した
|
||||
> A was quick to spot the potential of the Internet — A はインターネットの可能性をいち早く見出した
|
||||
|
||||
- a man who's nice to be around — そばに居てくれると助かる親切な人
|
||||
- His generosity knows no bounds — 彼の寛大さには限りが無い
|
||||
@@ -337,7 +337,7 @@ p.p. the present progressive form, 現在進行系
|
||||
- The antisocial behaviour you are naturing あなたが心に抱いている反社会的行動
|
||||
- have a lot to do with ~によるところが大きい
|
||||
|
||||
一般に前置詞+who(m)は既知の情報を確認する際に, who+前置詞は新しい情報を求める際に好まれる
|
||||
一般に前置詞+ who(m)は既知の情報を確認する際に, who +前置詞は新しい情報を求める際に好まれる
|
||||
|
||||
> This is sure to satisfy those who are into computers. これはコンピュータにはまっている人をきっと満足させるだろう
|
||||
|
||||
@@ -365,9 +365,9 @@ p.p. the present progressive form, 現在進行系
|
||||
|
||||
不定詞は名詞・形容詞・副詞的働きをする動詞ベースの詞のこと
|
||||
|
||||
to不定詞がunrealized(未実現)、-ingがrealized(実現)
|
||||
to 不定詞が unrealized(未実現)、-ing が realized(実現)
|
||||
|
||||
- I want (to eat an apple)←名詞的
|
||||
- I want (to eat an apple)← 名詞的
|
||||
- Thank you for playing the game
|
||||
|
||||
1. She is studying English hard to study abroad.
|
||||
@@ -375,22 +375,22 @@ to不定詞がunrealized(未実現)、-ingがrealized(実現)
|
||||
|
||||
違いは?
|
||||
|
||||
- only to A — 思わぬ悲観的な事実を説明するclause
|
||||
- only to A — 思わぬ悲観的な事実を説明する clause
|
||||
- He returned after the war only to be told that his wife had left him.
|
||||
- I tore open the box, only to discover that some of the parts were missing.
|
||||
- I tore open the box, only to discover that some of the parts were missing.
|
||||
- I arrived only to find that the others had already left.
|
||||
|
||||
## 倒置法
|
||||
|
||||
- So do I — 私も!(I like appleに対して)
|
||||
- So am I — 私も!(I'm twenty years oldに対して)
|
||||
- So do I — 私も!(I like apple に対して)
|
||||
- So am I — 私も!(I'm twenty years old に対して)
|
||||
- Here comes bus — もうバス来たよ
|
||||
- Here we go — ほら行こう
|
||||
- In you go — 中にお入り
|
||||
- What a shitty day — なんて日だ
|
||||
- How beautiful (that is) — なんて綺麗なの
|
||||
- "I'm fine", said he — 大丈夫だと彼は言った
|
||||
- Dark as(though) it was, I found the footprints. — 暗かったが、なんとか足跡を見つけた
|
||||
- Dark as(though) it was, I found the footprints. — 暗かったが、なんとか足跡を見つけた
|
||||
- Hard though she tried, she couldn't make the deadline. — 頑張ったが間に合わなかった
|
||||
- Do what you will, I won't give up — 何をされようとも諦めない
|
||||
- Walk as he would, he couldn't get to the station. — どんなに歩いても駅にたどり着けなかった
|
||||
@@ -400,9 +400,9 @@ to不定詞がunrealized(未実現)、-ingがrealized(実現)
|
||||
|
||||
> I still hate that "atheist" now is code for "bigoted asshole."
|
||||
|
||||
> Life only comes around once. So do whatever makes you happy and be with whoever makes you smile!๑╹◡╹)ノ…
|
||||
> Life only comes around once. So do whatever makes you happy and be with whoever makes you smile!๑╹◡╹)ノ…
|
||||
|
||||
> This is exactly what I thought was gonna happen when I saw those tweets, thank you…
|
||||
> This is exactly what I thought was gonna happen when I saw those tweets, thank you…
|
||||
|
||||
> @Nodejs and @the_jsf have merged to form the #OpenJSFoundation! The OpenJS Foundation is to become the central place to support collaborative development of #JavaScript and web technologies.
|
||||
|
||||
@@ -422,15 +422,15 @@ to不定詞がunrealized(未実現)、-ingがrealized(実現)
|
||||
> — Miriam Huntley
|
||||
> https://twitter.com/iam_mir_iam/status/1108819635959418881?s=12
|
||||
|
||||
> Welcome to the FGO NA Twitter. If you look to your left, you'll see the salty people club that are currently sulling about not pulling Okita. If you look to your right, you'll see the angry weeb club still screeching about Emiya Alter. Please enjoy your stay.…
|
||||
> Welcome to the FGO NA Twitter. If you look to your left, you'll see the salty people club that are currently sulling about not pulling Okita. If you look to your right, you'll see the angry weeb club still screeching about Emiya Alter. Please enjoy your stay.…
|
||||
> — ℭ𝔦𝔫𝔡𝔢𝔯 𝔉𝔞𝔩𝔩
|
||||
> https://twitter.com/zettainverse/status/1109231751019278337?s=12
|
||||
|
||||
> Probably one of the most auto-bookmarkable post I've seen in a while, regardless of skill level with git:
|
||||
> Probably one of the most auto-bookmarkable post I've seen in a while, regardless of skill level with git:
|
||||
> — Ben Halpern 🤗
|
||||
> https://twitter.com/bendhalpern/status/1135319291568562176?s=12
|
||||
|
||||
> Now announcing tsconfig-api 🎉 An experimental microservice for retrieving @typescript compiler option details 🔎 100% open source and hosted by @zeithq Now
|
||||
> Now announcing tsconfig-api 🎉 An experimental microservice for retrieving @typescript compiler option details 🔎 100% open source and hosted by @zeithq Now
|
||||
> — Matterhorn
|
||||
> https://twitter.com/matterhorndev/status/1138610398159147008?s=12
|
||||
|
||||
@@ -440,20 +440,20 @@ to不定詞がunrealized(未実現)、-ingがrealized(実現)
|
||||
> https://twitter.com/dan_abramov/status/1143911059717263360?s=12
|
||||
|
||||
> Yes, assuming something will work like literally every other software that has ever been created will work is subjective.
|
||||
> Super annoying that these people are so insecure about themselves that they have to do that kind of thing.…
|
||||
> Super annoying that these people are so insecure about themselves that they have to do that kind of thing.…
|
||||
> — Kent C. Dodds
|
||||
> https://twitter.com/kentcdodds/status/1147142716280602629?s=12
|
||||
|
||||
> Honest question: how does banning people from an opportunity to build a professional presence and potentially escape an oppressive regime advance human rights?…
|
||||
> Honest question: how does banning people from an opportunity to build a professional presence and potentially escape an oppressive regime advance human rights?…
|
||||
> — Dan Abramov
|
||||
> https://twitter.com/dan_abramov/status/1154871232459956224?s=12
|
||||
|
||||
> The national flag of Japan is a rectangular white banner bearing a crimson-red disc at its center. This flag is officially called Nisshōki (日章旗, the "sun-mark flag"), but is more commonly known in Japan as Hinomaru (日の丸, the "circle of the sun"). It embodies the country's sobriquet: Land of the Rising Sun.
|
||||
> reading this tweet is weird because at first you're like "hahaha they're not used to how gacha works" then you realize you've just been conditioned into being ok with predatory game models
|
||||
> You're offering subjective value assessments, not facts.…
|
||||
> You're offering subjective value assessments, not facts.…
|
||||
> — Levi Roach
|
||||
> https://twitter.com/DrLRoach/status/1172907254892421120?s=17
|
||||
|
||||
> My takeaway is that I'm starting a support group for design systems engineers across the world. 😛 We're all going through different versions of the same challenges at each of our companies and it's always encouraging to share information about where we are in this journey.
|
||||
> — Maja Wichrowska
|
||||
> https://twitter.com/majapw/status/1187891828189589504?s=17
|
||||
> https://twitter.com/majapw/status/1187891828189589504?s=17
|
@@ -4,16 +4,18 @@ date: 2019-01-14 00:00:00 +09:00
|
||||
redirect_from: "/blog/2019/01/14/padsize"
|
||||
---
|
||||
|
||||
padStart における padSize の求め方です。
|
||||
|
||||
$$
|
||||
\textrm{padSize} = \lceil \log_{10}(\mathbf{arraySize} + 1) \rceil
|
||||
$$
|
||||
|
||||
```js
|
||||
const padSize = Math.ceil(Math.log10(arr.length + 1))
|
||||
const padSize = Math.ceil(Math.log10(arr.length + 1));
|
||||
|
||||
arr.forEach((item, index) => {
|
||||
console.log(`${index.padStart(padSize, '0')}: ${item}`)
|
||||
})
|
||||
console.log(`${index.padStart(padSize, "0")}: ${item}`);
|
||||
});
|
||||
```
|
||||
|
||||
結果は以下のようになる。
|
@@ -21,14 +21,14 @@ electron-builder を利用して macOS 向け Electron アプリをコード署
|
||||
コード署名済みのアプリを[electron-notarize](https://github.com/electron-userland/electron-notarize)を使用して Apple Notary Service に提出します。
|
||||
|
||||
```js
|
||||
const { notarize } = require('electron-notarize')
|
||||
const { notarize } = require("electron-notarize");
|
||||
notarize({
|
||||
appBundleId,
|
||||
appPath,
|
||||
appleId,
|
||||
appleIdPassword,
|
||||
ascProvider,
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
- **appBundleId**: アプリの Bundle ID です。`package.json`の`build.appId`と同じものを使います。
|
||||
@@ -44,33 +44,33 @@ electron-builder の afterSign フックを使用して、コード署名が済
|
||||
フックスクリプトを`./scripts/after-sign-mac.js`に置きます。
|
||||
|
||||
```js
|
||||
const path = require('path')
|
||||
const { notarize } = require('electron-notarize')
|
||||
const path = require("path");
|
||||
const { notarize } = require("electron-notarize");
|
||||
|
||||
const appleId = process.env.APPLE_ID
|
||||
const appleIdPassword = process.env.APPLE_PASSWORD
|
||||
const ascProvider = process.env.ASC_PROVIDER
|
||||
const appleId = process.env.APPLE_ID;
|
||||
const appleIdPassword = process.env.APPLE_PASSWORD;
|
||||
const ascProvider = process.env.ASC_PROVIDER;
|
||||
|
||||
const configPath = path.resolve(__dirname, '../package.json')
|
||||
const appPath = path.resolve(__dirname, '../dist/mac/App.app')
|
||||
const config = require(configPath)
|
||||
const appBundleId = config.build.appId
|
||||
const configPath = path.resolve(__dirname, "../package.json");
|
||||
const appPath = path.resolve(__dirname, "../dist/mac/App.app");
|
||||
const config = require(configPath);
|
||||
const appBundleId = config.build.appId;
|
||||
|
||||
async function notarizeApp() {
|
||||
console.log(`afterSign: Notarizing ${appBundleId} in ${appPath}`)
|
||||
console.log(`afterSign: Notarizing ${appBundleId} in ${appPath}`);
|
||||
await notarize({
|
||||
appBundleId,
|
||||
appPath,
|
||||
appleId,
|
||||
appleIdPassword,
|
||||
ascProvider,
|
||||
})
|
||||
console.log('afterSign: Notarized')
|
||||
});
|
||||
console.log("afterSign: Notarized");
|
||||
}
|
||||
|
||||
exports.default = async () => {
|
||||
await notarizeApp()
|
||||
}
|
||||
await notarizeApp();
|
||||
};
|
||||
```
|
||||
|
||||
`package.json`の`build`に`afterSign`を追加してコード署名が終わった後にスクリプトが実行されるようにします。
|
@@ -5,11 +5,9 @@ date: 2019-10-03 17:21:00 +09:00
|
||||
|
||||
**Welch の t 検定**を用いて 2 つのベンチマークの分布の平均が等しい(速度差は誤差の範疇)か、あるいは異なる(=有意な速度改善が成されている)かどうかを判定します。
|
||||
|
||||
ベンチマーク用のTypeScriptプログラムを用意します。
|
||||
ベンチマーク用の TypeScript プログラムを用意します。
|
||||
|
||||
#### `a.ts`
|
||||
|
||||
```ts
|
||||
```ts a.ts
|
||||
function a() {
|
||||
const noise = Math.random() - 0.5;
|
||||
const offset = 1.0;
|
||||
@@ -19,9 +17,7 @@ function a() {
|
||||
a();
|
||||
```
|
||||
|
||||
#### `b.ts`
|
||||
|
||||
```ts
|
||||
```ts b.ts
|
||||
function b() {
|
||||
const noise = Math.random() - 0.5;
|
||||
const offset = 2.0;
|
||||
@@ -34,12 +30,12 @@ b();
|
||||
まず[hyperfine](https://github.com/sharkdp/hyperfine)で 2 つの プログラムのベンチマークを取り、`result.json`に保存します。
|
||||
|
||||
```shell
|
||||
hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json
|
||||
hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json
|
||||
```
|
||||
|
||||
`result.json`の中身以下のようになります。
|
||||
`result.json`の中身は以下のようになります。
|
||||
|
||||
```json
|
||||
```json result.json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
@@ -82,13 +78,13 @@ hyperfine 'ts-node a.ts' 'ts-node b.ts' -r 50 --warmup 3 --export-json ab.json
|
||||
}
|
||||
```
|
||||
|
||||
> t検定はサンプルが正規分布に従っているという仮定を置いているので、大数の法則から本当はもっと試行回数を増やした方が良いです。
|
||||
> t 検定はサンプルが正規分布に従っているという仮定を置いているので、大数の法則から本当はもっと試行回数を増やした方が良いです。
|
||||
|
||||
この`result.json`の`times`配列を受け取り、2 つの分布間に有意差があるかどうかを判定します。
|
||||
|
||||
```ts
|
||||
import fs from 'fs';
|
||||
import {jStat} from 'jstat';
|
||||
import fs from "fs";
|
||||
import { jStat } from "jstat";
|
||||
|
||||
const log = console.log;
|
||||
|
||||
@@ -127,10 +123,10 @@ const Y = result.results[1].times;
|
||||
const p = ttest(X, Y);
|
||||
log(`p = ${p}`);
|
||||
log(`p < 0.05 = ${p < 0.05}`);
|
||||
log(p < 0.05 ? 'Possibly some difference there' : 'No difference');
|
||||
log(p < 0.05 ? "Possibly some difference there" : "No difference");
|
||||
```
|
||||
|
||||
ここで`X_mu`は分布Xの平均、`X_sigma`は分布Xの不偏分散です。
|
||||
ここで`X_mu`は分布 X の平均、`X_sigma`は分布 X の不偏分散です。
|
||||
|
||||
$$
|
||||
\begin{eqnarray}
|
||||
@@ -139,19 +135,19 @@ $$
|
||||
\end{eqnarray}
|
||||
$$
|
||||
|
||||
これをXとY両方に対して求めます。さらに以下のようにしてtを求めます。
|
||||
これを X と Y 両方に対して求めます。さらに以下のようにして t を求めます。
|
||||
|
||||
$$
|
||||
t = \frac{\mu_X - \mu_Y}{\sqrt{\frac{\sigma_X}{n_X} + \frac{\sigma_Y}{n_Y}}}
|
||||
$$
|
||||
|
||||
t分布の累積密度関数 (Cumlative Distribution Function; CDF) を定義します。面倒すぎたので[jstat](https://github.com/jstat/jstat)の`studentt.cdf`を使ってます。コードを見ると、分子の積分は[シンプソンの公式](https://ja.wikipedia.org/wiki/シンプソンの公式)を使って近似していました。
|
||||
t 分布の累積密度関数 (Cumlative Distribution Function; CDF) を定義します。面倒すぎたので[jstat](https://github.com/jstat/jstat)の`studentt.cdf`を使ってます。コードを見ると、分子の積分は[シンプソンの公式](https://ja.wikipedia.org/wiki/シンプソンの公式)を使って近似していました。
|
||||
|
||||
$$
|
||||
\text{CDF} =\frac{\int_0^{\frac{v}{t^2+v}}\frac{r^{\frac{v}{2}-1}}{\sqrt{1-r}}dr{}}{\text{exp}(\ln(\Gamma(\frac{v}{2}))+\ln(\Gamma(0.5))+\ln(\Gamma(\frac{v}{2}+0.5)))}
|
||||
$$
|
||||
|
||||
CDFを用いてp値を求めます。両側検定をするので2を掛けます。t分布の自由度 (degree of freedom; df) は$n-1$なので、両分布の自由度を$n_X+n_Y-2$で与えます。本当は
|
||||
CDF を用いて p 値を求めます。両側検定をするので 2 を掛けます。t 分布の自由度 (degree of freedom; df) は$n-1$なので、両分布の自由度を$n_X+n_Y-2$で与えます。本当は
|
||||
|
||||
$$
|
||||
\text{df} = \frac{(\sigma_X + \sigma_Y)^2}{
|
||||
@@ -166,7 +162,7 @@ $$
|
||||
|
||||
## 結果
|
||||
|
||||
異なる実行時間を示すプログラム`a`,`b`を比較すると、2つの分布の平均が異なることが示唆されました。
|
||||
異なる実行時間を示すプログラム`a`,`b`を比較すると、2 つの分布の平均が異なることが示唆されました。
|
||||
|
||||
```
|
||||
❯ ts-node test.ts ab.json
|
||||
@@ -184,7 +180,7 @@ p < 0.05 = true
|
||||
Possibly some difference there
|
||||
```
|
||||
|
||||
p値が0.05未満となり、帰無仮説「2つの分布は等しい」が棄却されたので「2つの分布は等しくない」ことがわかりました。同じプログラム同士でベンチマークを取るとどうなるでしょうか。
|
||||
p 値が 0.05 未満となり、帰無仮説「2つの分布は等しい」が棄却されたので「2つの分布は等しくない」ことがわかりました。同じプログラム同士でベンチマークを取るとどうなるでしょうか。
|
||||
|
||||
```
|
||||
❯ ts-node test.ts aa.json
|
||||
@@ -202,10 +198,10 @@ p < 0.05 = false
|
||||
No difference
|
||||
```
|
||||
|
||||
p値が0.05未満ではないので、帰無仮説は棄却されず、つまり「2つの分布は等しい」ことがわかりました。
|
||||
p 値が 0.05 未満ではないので、帰無仮説は棄却されず、つまり「2つの分布は等しい」ことがわかりました。
|
||||
|
||||
ウェルチのt検定はスチューデントのt検定と違って等分散性(2つの分布の分散が等しいこと)を仮定しないので、とても取り扱いやすい検定です。もちろん等分散性のある分布でも使用できるので、基本的にはウェルチの方法を使う方針で良さそうです。
|
||||
ウェルチの t 検定はスチューデントの t 検定と違って等分散性(2つの分布の分散が等しいこと)を仮定しないので、とても取り扱いやすい検定です。もちろん等分散性のある分布でも使用できるので、基本的にはウェルチの方法を使う方針で良さそうです。
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [Welch's t-test - Rosetta Code](https://rosettacode.org/wiki/Welch%27s_t-test)
|
||||
- [Welch's t-test - Rosetta Code](https://rosettacode.org/wiki/Welch%27s_t-test)
|
@@ -1,8 +1,8 @@
|
||||
---
|
||||
title: Securing Local Dev Server
|
||||
date: 2020-02-07 00:00:00 +0900
|
||||
|
||||
---
|
||||
|
||||
Sometimes you want to interact with a local webserver with https support because of some browser APIs that are only available in an https environment.
|
||||
|
||||
You can easily create a self-signed TLS cert for development purposes with [`mkcert`](https://github.com/FiloSottile/mkcert).
|
||||
@@ -19,4 +19,4 @@ cd awesome-website
|
||||
mkcert localhost # this will generate ./localhost.pem and ./localhost-key.pem
|
||||
npm install -g serve
|
||||
serve --ssl-cert ./localhost.pem --ssl-key ./localhost-key.pem
|
||||
```
|
||||
```
|
155
source/_posts/2021/affinity-thumbnail.md
Normal file
155
source/_posts/2021/affinity-thumbnail.md
Normal file
@@ -0,0 +1,155 @@
|
||||
---
|
||||
title: Distill Thumbnail from .afphoto and .afdesign
|
||||
date: 2021-02-14T13:30:00
|
||||
---
|
||||
|
||||
Nextcloud does not have support for generating thumbnails from Affinity Photo and Affinity Design. Fine, I'll do it myself.
|
||||
|
||||
# Digging Binary
|
||||
|
||||
Glancing at `.afphoto` and `.afdesign` in Finder, I noticed that it has a QuickLook support and an ability to show the thumbnail image. So these files should have thumbnail image somewhere inside its binary.
|
||||
|
||||
I wrote a piece of Node.js script to seek for [PNG signature](https://www.w3.org/TR/PNG/) inside a binary and save it as an image file.
|
||||
|
||||
```js afthumb.js
|
||||
const fs = require("fs");
|
||||
|
||||
// png spec: https://www.w3.org/TR/PNG/
|
||||
const PNG_SIG = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
||||
const IEND_SIG = Buffer.from([73, 69, 78, 68]);
|
||||
|
||||
function extractThumbnail(buf) {
|
||||
const start = buf.indexOf(PNG_SIG);
|
||||
const end = buf.indexOf(IEND_SIG, start) + IEND_SIG.length * 2; // IEND + CRC
|
||||
return buf.subarray(start, end);
|
||||
}
|
||||
|
||||
function generateThumbnail(input, output) {
|
||||
const buf = fs.readFileSync(input);
|
||||
const thumbBuf = extractThumbnail(buf);
|
||||
fs.writeFileSync(output, thumbBuf);
|
||||
}
|
||||
|
||||
generateThumbnail(process.argv[2], process.argv[3] || "output.png");
|
||||
```
|
||||
|
||||
That's right. This script just scrapes a binary file and distill a portion of which starts with `PNG` signature and ends with `IEND`.
|
||||
|
||||
Now I can generate a thumbnail image from arbitrary `.afphoto` and `.afdesign` file. Let's move on delving into Nextcloud source code.
|
||||
|
||||
# Tweaking Nextcloud
|
||||
|
||||
I have a bit of experience in tweaking Nextcloud source code before, where I implemented thumbnail generator for PDFs, so it should be easier this time, hopefully.
|
||||
|
||||
Long story short, I got Nextcloud generates thumbnail images for Affinity files by implementing `ProviderV2` class.
|
||||
|
||||
```php lib/private/Preview/Affinity.php
|
||||
<?php
|
||||
|
||||
namespace OC\Preview;
|
||||
|
||||
use OCP\Files\File;
|
||||
use OCP\IImage;
|
||||
use OCP\ILogger;
|
||||
|
||||
class Affinity extends ProviderV2 {
|
||||
public function getMimeType(): string {
|
||||
return '/application\/x-affinity-(?:photo|design)/';
|
||||
}
|
||||
|
||||
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
|
||||
$tmpPath = $this->getLocalFile($file);
|
||||
|
||||
$handle = fopen($tmpPath, 'rb');
|
||||
$fsize = filesize($tmpPath);
|
||||
$contents = fread($handle, $fsize);
|
||||
$start = strrpos($contents, "\x89PNG");
|
||||
$end = strrpos($contents, "IEND", $start);
|
||||
$subarr = substr($contents, $start, $end - $start + 8 );
|
||||
|
||||
fclose($handle);
|
||||
$this->cleanTmpFiles();
|
||||
|
||||
$image = new \OC_Image();
|
||||
$image->loadFromData($subarr);
|
||||
$image->scaleDownToFit($maxX, $maxY);
|
||||
|
||||
return $image->valid() ? $image : null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```patch lib/private/PreviewManager.php
|
||||
@@ -363,6 +365,8 @@
|
||||
$this->registerCoreProvider(Preview\Krita::class, '/application\/x-krita/');
|
||||
$this->registerCoreProvider(Preview\MP3::class, '/audio\/mpeg/');
|
||||
$this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/');
|
||||
+ $this->registerCoreProvider(Preview\Affinity::class, '/application\/x-affinity-(?:photo|design)/');
|
||||
|
||||
// SVG, Office and Bitmap require imagick
|
||||
if (extension_loaded('imagick')) {
|
||||
```
|
||||
|
||||
```patch lib/composer/composer/autoload_static.php
|
||||
@@ -1226,6 +1226,7 @@
|
||||
'OC\\OCS\\Result' => __DIR__ . '/../../..' . '/lib/private/OCS/Result.php',
|
||||
'OC\\PreviewManager' => __DIR__ . '/../../..' . '/lib/private/PreviewManager.php',
|
||||
'OC\\PreviewNotAvailableException' => __DIR__ . '/../../..' . '/lib/private/PreviewNotAvailableException.php',
|
||||
+ 'OC\\Preview\\Affinity' => __DIR__ . '/../../..' . '/lib/private/Preview/Affinity.php',
|
||||
'OC\\Preview\\BMP' => __DIR__ . '/../../..' . '/lib/private/Preview/BMP.php',
|
||||
'OC\\Preview\\BackgroundCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Preview/BackgroundCleanupJob.php',
|
||||
'OC\\Preview\\Bitmap' => __DIR__ . '/../../..' . '/lib/private/Preview/Bitmap.php',
|
||||
```
|
||||
|
||||
```patch lib/composer/composer/autoload_classmap.php
|
||||
@@ -1197,6 +1197,7 @@
|
||||
'OC\\OCS\\Result' => $baseDir . '/lib/private/OCS/Result.php',
|
||||
'OC\\PreviewManager' => $baseDir . '/lib/private/PreviewManager.php',
|
||||
'OC\\PreviewNotAvailableException' => $baseDir . '/lib/private/PreviewNotAvailableException.php',
|
||||
+ 'OC\\Preview\\Affinity' => $baseDir . '/lib/private/Preview/Affinity.php',
|
||||
'OC\\Preview\\BMP' => $baseDir . '/lib/private/Preview/BMP.php',
|
||||
'OC\\Preview\\BackgroundCleanupJob' => $baseDir . '/lib/private/Preview/BackgroundCleanupJob.php',
|
||||
'OC\\Preview\\Bitmap' => $baseDir . '/lib/private/Preview/Bitmap.php',
|
||||
```
|
||||
|
||||

|
||||
|
||||
Easy-peasy!
|
||||
|
||||
# Bonus: PDF thumbnail generator
|
||||
|
||||
Install `ghostscript` on your server to make it work.
|
||||
|
||||
```php lib/private/Preview/PDF.php
|
||||
<?php
|
||||
|
||||
namespace OC\Preview;
|
||||
|
||||
use OCP\Files\File;
|
||||
use OCP\IImage;
|
||||
|
||||
class PDF extends ProviderV2 {
|
||||
public function getMimeType(): string {
|
||||
return '/application\/pdf/';
|
||||
}
|
||||
|
||||
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
|
||||
$tmpPath = $this->getLocalFile($file);
|
||||
$outputPath = \OC::$server->getTempManager()->getTemporaryFile();
|
||||
|
||||
$gsBin = \OC_Helper::findBinaryPath('gs');
|
||||
$cmd = $gsBin . " -o " . escapeshellarg($outputPath) . " -sDEVICE=jpeg -sPAPERSIZE=a4 -dLastPage=1 -dPDFFitPage -dJPEGQ=90 -r144 " . escapeshellarg($tmpPath);
|
||||
shell_exec($cmd);
|
||||
|
||||
$this->cleanTmpFiles();
|
||||
|
||||
$image = new \OC_Image();
|
||||
$image->loadFromFile($outputPath);
|
||||
$image->scaleDownToFit($maxX, $maxY);
|
||||
|
||||
unlink($outputPath);
|
||||
|
||||
return $image->valid() ? $image : null;
|
||||
}
|
||||
}
|
||||
```
|
BIN
source/_posts/2021/affinity-thumbnail/afphoto.png
Normal file
BIN
source/_posts/2021/affinity-thumbnail/afphoto.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 437 KiB |
18
source/_posts/2021/braille.md
Normal file
18
source/_posts/2021/braille.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 点字の表現力
|
||||
date: 2021-02-13T01:00:00
|
||||
---
|
||||
|
||||
「n 種類の文字を表現できる点字を作らないといけなくなったらどうしよう」
|
||||
|
||||
例としてドット が 3 つの点字を用意した。
|
||||
|
||||
- 組み合わせ数は 3P3 + 3P2 + 3P1
|
||||
- $f(N) = \sum_{K=N → 1} N P K$
|
||||
- 2 の n 乗っぽい
|
||||
- べき集合の濃度?
|
||||
- 2 進数のブール配列と考えればわかりやすくなった
|
||||
- ということは X 個の表現をするために必要なブール配列の長さは $\lceil\log_2 (X)\rceil$
|
||||
- 例えばアルファベットなら 6 ドットの点字で表現できる
|
||||
- だから英語の点字は 6 つの点で構成されている
|
||||
- 点字を 18 ドットに拡張すれば Unicode 13.0 の文字すべてを表現できる
|
128
source/_posts/2021/human-anatomy-atlas.md
Normal file
128
source/_posts/2021/human-anatomy-atlas.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: 解剖学アトラス
|
||||
date: 2021-06-08T00:00:00
|
||||
---
|
||||
|
||||
いつもの幅優先探索癖。アトラスの用途は美術解剖と消化器系の構造理解。
|
||||
|
||||
# ノート
|
||||
|
||||
肉眼解剖学はアプローチの違いから局所解剖学と系統解剖学に分けられる。
|
||||
|
||||
体表解剖は解剖学的構造と体表の特徴との関連を視覚的に理解するための節。
|
||||
微視的レベルで観察する組織学—又の名を顕微鏡解剖学—が肉眼解剖学に対置する。
|
||||
|
||||
他にも、胚からの成長過程に着目する発生学、部位の機能を明らかにする生理学、物質代謝の機序に興味をおく生化学等が周辺にある。
|
||||
|
||||
テキスト、アトラス、カラーアトラスが一冊ずつあれば事足りそう。
|
||||
個人的には『グレイ解剖学』、『ネッター解剖学アトラス』、『解剖学カラーアトラス』。
|
||||
余裕があれば『プロメテウス解剖学アトラス 胸部/腹部・骨盤部』。
|
||||
|
||||
# 教科書
|
||||
|
||||
## グレイ解剖学 原著第 4 版
|
||||
|
||||
2019(原著 2018)
|
||||
|
||||
- 腹膜と腸間膜の節に限ってみても、筆者の「絶対にわからせる」という強い意志を感じさせる説明によって圧倒的にわからされてしまう
|
||||
- 各章は概観、局所解剖、体表解剖、臨床症例から構成されている、肉眼解剖学に的を絞った本
|
||||
- 腹腔・腹膜・腸間膜関連はプロメテウスより詳しい(特に一部腸管が二次的に腹膜後器官になる過程等)
|
||||
- Meckel 憩室の臨床症例が写真とともに載っている
|
||||
|
||||
# アトラス
|
||||
|
||||
## ネッター解剖学アトラス 原著第 6 版
|
||||
|
||||
2016(原著 2014)
|
||||
|
||||
- 元々ノバルティスの販促のために描かれたイラストをまとめ上げたもの
|
||||
- 組織と筋肉、血管、神経がまとまって描かれており、位置関係がわかりやすい
|
||||
- 断面解剖の CT と図譜両方がある(プロメテウスは CT のみ)
|
||||
- グラントと比べてカラフル
|
||||
|
||||
## グラント解剖学図譜 第 7 版
|
||||
|
||||
2016(原著 2013)
|
||||
|
||||
- イラストは立体感を把握しやすいタッチ
|
||||
|
||||
## プロメテウス解剖学アトラス 解剖学総論/運動器系 第 3 版
|
||||
|
||||
2017(原著 2014)
|
||||
|
||||
- 全身の骨格から筋肉、血管、神経、リンパ系が一通り概説されている
|
||||
- ポージングの参考になる関節力学の知見が豊富
|
||||
- 消化器系は解説なし
|
||||
- 病例と診断方法、その施術指南が特徴
|
||||
|
||||
## プロメテウス解剖学アトラス 口腔・頭頸部 第 2 版
|
||||
|
||||
2018(原著 2015)
|
||||
|
||||
- 脳、頭部、口腔、頸部に絞って解説
|
||||
- 口腔から食道、胃までの部分に関する記述が非常に豊富
|
||||
- 歯科臨床を意識した紙面構成
|
||||
- 口腔・頭頸部以外の部位についての説明もざっくりされている
|
||||
|
||||
## プロメテウス解剖学アトラス 胸部/腹部・骨盤部 第 3 版
|
||||
|
||||
2020(原著 2015)
|
||||
|
||||
- 胸部から腹部にかけて発生学・解剖学の図説が中心
|
||||
- 食道の筋の機能的構造の図解など、グレイ解剖学には載っていない内容も多い
|
||||
|
||||
## プロメテウス解剖学 コアアトラス 第 3 版
|
||||
|
||||
2016
|
||||
|
||||
- プロメテウス 3 巻を一冊にまとめた本で、部位ごとに内容が集約されている
|
||||
- 胃の解説に 2 ページしか割かれていないなど、情報が広く浅い
|
||||
|
||||
# カラーアトラス
|
||||
|
||||
## 解剖学カラーアトラス 第 8 版 A Photographic Atlas
|
||||
|
||||
2016(原著 2016)
|
||||
|
||||
- ほとんどがリアルな解剖写真
|
||||
- 写真と共に図解イラストが対照されており理解が捗る
|
||||
- 図とアノテーションしか無いため、機能理解は他の本に頼る必要がある
|
||||
- ユニークな点として、胎児の矢状断面図が掲載されている
|
||||
|
||||
## 人体解剖カラーアトラス 原著第 8 版 Clinical Atlas of Human Anatomy
|
||||
|
||||
- こちらも基本的にアノテーションのみだが、注釈的説明が若干多め
|
||||
- 解剖学カラーアトラスと比べて 140 ページ少ない
|
||||
- 腹膜のヒダの写真はこちらにしか載っていない
|
||||
|
||||
# アプリ
|
||||
|
||||
## Human Anatomy Atlas
|
||||
|
||||
https://apps.apple.com/jp/app/human-anatomy-atlas-2021/id1117998129?l=en
|
||||
|
||||
- 毎年 11 月から 12 月頃にセールをしている
|
||||
|
||||
# Web サイト
|
||||
|
||||
- 1 年生の解剖学辞典 - https://anatomy1.net/
|
||||
- 医学生の教科書 - https://store.isho.jp/
|
||||
|
||||
# 知見
|
||||
|
||||
- 食道は腰椎と胸大動脈の前方、気管と心臓の後方を通る
|
||||
- 横隔膜のすぐ上方に心臓、すぐ下方に胃がある
|
||||
- 食道の正常な内径は 20mm
|
||||
- 食道には縦走ヒダが走っているが、Z 線を超えると胃底となり模様が変化する
|
||||
- 噴門括約筋は横隔膜食道裂孔の筋肉が代行しており、ジグザグ状であるので Z 線と呼ばれている(リング状に筋肉が縮まるのではなく、ジグザグ状の縦筋が縮まることで噴門を締め上げている)→ プロメテウス胸部 p. 168
|
||||
- 心臓はわずかに左にずれているため、左肺は右肺より小さい
|
||||
- 憩室といえば大腸だと思っていたが、食道にも発生する → プロメテウス胸部 p. 169
|
||||
- 「滑り説」筋収縮のメカニズムの学説のひとつ
|
||||
|
||||
# 用語
|
||||
|
||||
- 翻転(ほんてん) - 組織をひっくりかえすこと
|
||||
- 腋窩(えきか)
|
||||
- 網嚢孔(もうのうこう)
|
||||
- 横紋筋(おうもんきん)と平滑筋(へいかつきん)
|
||||
- 蠕動運動(ぜんどう—)
|
869
source/_posts/2021/installing-arch-linux.md
Normal file
869
source/_posts/2021/installing-arch-linux.md
Normal file
@@ -0,0 +1,869 @@
|
||||
---
|
||||
title: Comprehensive Guide for Setting Up Arch Linux
|
||||
date: 2021-02-12T00:00:00
|
||||
---
|
||||
|
||||
This note includes all commands I typed when I set up Arch Linux on my new server.
|
||||
|
||||
> PSA: I published a toolchain for building AUR packages in a clean-room docker container
|
||||
> <https://github.com/uetchy/archpkgs>
|
||||
|
||||
# Setup
|
||||
|
||||
## Wipe whole disk
|
||||
|
||||
```bash
|
||||
wipefs -a /dev/sda
|
||||
```
|
||||
|
||||
## Create partition
|
||||
|
||||
```bash
|
||||
parted
|
||||
```
|
||||
|
||||
```bash
|
||||
select /dev/sda
|
||||
mktable gpt
|
||||
mkpart EFI fat32 0 512MB # EFI
|
||||
mkpart Arch ext4 512MB 100% # Arch
|
||||
set 1 esp on # flag partition 1 as ESP
|
||||
quit
|
||||
```
|
||||
|
||||
## Install file-system
|
||||
|
||||
```bash
|
||||
mkfs.vfat -F 32 /dev/sda1 # EFI
|
||||
mkfs.ext4 /dev/sda2 # Arch
|
||||
|
||||
e2fsck -cc -C 0 /dev/sda2 # fsck
|
||||
```
|
||||
|
||||
## Mount disk
|
||||
|
||||
```bash
|
||||
mkdir -p /mnt/boot
|
||||
mount /dev/sda2 /mnt
|
||||
mount /dev/sda1 /mnt/boot
|
||||
```
|
||||
|
||||
## Install base & Linux kernel
|
||||
|
||||
```bash
|
||||
# choose between 'linux' or 'linux-lts'
|
||||
pacstrap /mnt base linux-lts linux-firmware
|
||||
genfstab -U /mnt >> /mnt/etc/fstab
|
||||
arch-chroot /mnt
|
||||
```
|
||||
|
||||
```bash
|
||||
pacman -S reflector
|
||||
reflector --protocol https --latest 30 --sort rate --save /etc/pacman.d/mirrorlist --verbose # optimize mirror list
|
||||
```
|
||||
|
||||
## Install essentials
|
||||
|
||||
```bash
|
||||
pacman -S vim man-db man-pages git base-devel
|
||||
```
|
||||
|
||||
## Locales
|
||||
|
||||
```bash
|
||||
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
|
||||
hwclock --systohc
|
||||
vim /etc/locale.gen & locale-gen
|
||||
echo "LANG=en_US.UTF-8" > /etc/locale.conf
|
||||
```
|
||||
|
||||
## add fstab entries
|
||||
|
||||
```ini /etc/fstab
|
||||
# backup
|
||||
UUID=<UUID> /mnt/backup ext4 defaults 0 2
|
||||
|
||||
# archive (do not prevent boot even if fsck fails)
|
||||
UUID=<UUID> /mnt/archive ext4 defaults,nofail,x-systemd.device-timeout=4 0 2
|
||||
```
|
||||
|
||||
Find `<UUID>` from the output of `lsblk -f`.
|
||||
|
||||
```bash
|
||||
findmnt --verify --verbose # verify fstab
|
||||
```
|
||||
|
||||
## Install bootloader
|
||||
|
||||
```bash
|
||||
pacman -S \
|
||||
grub \
|
||||
efibootmgr \
|
||||
amd-ucode # AMD microcode
|
||||
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB
|
||||
|
||||
vim /etc/default/grub
|
||||
# GRUB_TIMEOUT=3
|
||||
# GRUB_DISABLE_SUBMENU=y
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
```
|
||||
|
||||
- [GRUB/Tips and tricks - ArchWiki](https://wiki.archlinux.org/title/GRUB/Tips_and_tricks)
|
||||
|
||||
## Setup network
|
||||
|
||||
```bash
|
||||
hostnamectl set-hostname takos
|
||||
hostnamectl set-chassis server
|
||||
```
|
||||
|
||||
```ini /etc/hosts
|
||||
127.0.0.1 localhost
|
||||
::1 localhost
|
||||
127.0.0.1 takos
|
||||
```
|
||||
|
||||
See https://systemd.network/systemd.network.html and https://wiki.archlinux.org/title/Systemd-networkd, and <https://blog.ivansmirnov.name/set-up-pihole-using-docker-macvlan-network/>.
|
||||
|
||||
```ini /etc/systemd/network/wired.network
|
||||
[Match]
|
||||
Name=enp5s0
|
||||
|
||||
[Network]
|
||||
#DHCP=yes
|
||||
Address=10.0.1.2/24
|
||||
Gateway=10.0.1.1
|
||||
DNS=10.0.1.100 # self-hosted DNS resolver
|
||||
DNS=1.1.1.1 # Cloudflare for the fallback DNS server
|
||||
MACVLAN=dns-shim # to handle local dns lookup to 10.0.1.100 which is managed by Docker macvlan driver
|
||||
```
|
||||
|
||||
```ini /etc/systemd/network/dns-shim.netdev
|
||||
# to handle local dns lookup to 10.0.1.100
|
||||
[NetDev]
|
||||
Name=dns-shim
|
||||
Kind=macvlan
|
||||
|
||||
[MACVLAN]
|
||||
Mode=bridge
|
||||
```
|
||||
|
||||
```ini /etc/systemd/network/dns-shim.network
|
||||
# to handle local dns lookup to 10.0.1.100
|
||||
[Match]
|
||||
Name=dns-shim
|
||||
|
||||
[Network]
|
||||
IPForward=yes
|
||||
|
||||
[Address]
|
||||
Address=10.0.1.103/32
|
||||
Scope=link
|
||||
|
||||
[Route]
|
||||
Destination=10.0.1.100/30
|
||||
```
|
||||
|
||||
`ip` equivalent to the above config:
|
||||
|
||||
```bash
|
||||
ip link add dns-shim link enp5s0 type macvlan mode bridge # add macvlan shim interface
|
||||
ip a add 10.0.1.103/32 dev dns-shim # assign the interface an ip address
|
||||
ip link set dns-shim up # enable the interface
|
||||
ip route add 10.0.1.100/30 dev dns-shim # route macvlan subnet (.100 - .103) to the interface
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl enable --now systemd-networkd
|
||||
networkctl status
|
||||
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
||||
|
||||
# for self-hosted dns resolver
|
||||
sed -r -i -e 's/#?DNSStubListener=yes/DNSStubListener=no/g' -e 's/#DNS=/DNS=10.0.1.100/g' /etc/systemd/resolved.conf
|
||||
|
||||
systemctl enable --now systemd-resolved
|
||||
resolvectl status
|
||||
resolvectl query ddg.gg
|
||||
drill ddg.gg
|
||||
```
|
||||
|
||||
If `networkctl` keep showing `enp5s0` as `degraded`, then run `ip addr add 10.0.1.2/24 dev enp5s0 ` to manually assign static IP address for the workaround.
|
||||
|
||||
## Finalize
|
||||
|
||||
```bash
|
||||
exit # leave chroot
|
||||
umount -R /mnt
|
||||
reboot
|
||||
```
|
||||
|
||||
## NTP
|
||||
|
||||
```bash
|
||||
timedatectl set-ntp true
|
||||
timedatectl status
|
||||
```
|
||||
|
||||
## Shell
|
||||
|
||||
```bash
|
||||
pacman -S zsh
|
||||
chsh -s /bin/zsh
|
||||
git clone https://github.com/uetchy/dotfiles ~/.dotfiles
|
||||
yay -S ruby pyenv exa antibody direnv fd ripgrep fzy peco ghq-bin hub neofetch tmux git-delta lazygit jq lostfiles ncdu htop rsync youtube-dl prettier tree age informant
|
||||
usermod -aG informant <user>
|
||||
cd ~/.dotfiles
|
||||
./dot link zsh -f
|
||||
reload
|
||||
```
|
||||
|
||||
## Setup operator user (i.e. user without superuser privilege)
|
||||
|
||||
```bash
|
||||
passwd # change root passwd
|
||||
|
||||
useradd -m -s /bin/zsh <user> # add local user
|
||||
passwd <user> # change local user password
|
||||
|
||||
userdbctl # verify users
|
||||
userdbctl group # verify groups
|
||||
|
||||
pacman -S sudo
|
||||
echo "%sudo ALL=(ALL) NOPASSWD:/usr/bin/pacman" > /etc/sudoers.d/pacman # allow users in sudo group to run pacman without password (optional)
|
||||
groupadd sudo
|
||||
usermod -aG sudo <user> # add local user to sudo group
|
||||
visudo -c
|
||||
```
|
||||
|
||||
## SSH
|
||||
|
||||
```bash
|
||||
pacman -S openssh
|
||||
vim /etc/ssh/sshd_config
|
||||
systemctl enable --now sshd
|
||||
```
|
||||
|
||||
on the host machine:
|
||||
|
||||
```bash
|
||||
ssh-copy-id <user>@<ip>
|
||||
```
|
||||
|
||||
```bash:$HOME/.ssh/rc
|
||||
if [ ! -S ~/.ssh/ssh_auth_sock ] && [ -S "$SSH_AUTH_SOCK" ]; then
|
||||
ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
|
||||
fi
|
||||
```
|
||||
|
||||
See also: [Happy ssh agent forwarding for tmux/screen · Reboot and Shine](https://werat.dev/blog/happy-ssh-agent-forwarding/)
|
||||
|
||||
## AUR
|
||||
|
||||
```bash
|
||||
git clone https://aur.archlinux.org/yay.git
|
||||
cd yay
|
||||
makepkg -si
|
||||
```
|
||||
|
||||
## S.M.A.R.T.
|
||||
|
||||
```bash
|
||||
pacman -S smartmontools
|
||||
systemctl enable --now smartd
|
||||
|
||||
smartctl -t short /dev/sda
|
||||
smartctl -l selftest /dev/sda
|
||||
```
|
||||
|
||||
## NVIDIA drivers
|
||||
|
||||
```bash
|
||||
pacman -S nvidia-lts # 'nvidia' for 'linux' package
|
||||
reboot
|
||||
nvidia-smi # test runtime
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/arch-overview.html
|
||||
|
||||
```bash
|
||||
pacman -S docker docker-compose
|
||||
yay -S nvidia-container-runtime
|
||||
systemctl enable --now docker
|
||||
```
|
||||
|
||||
```json /etc/docker/daemon.json
|
||||
{
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "10m", // default: -1 (unlimited)
|
||||
"max-file": "3" // default: 1
|
||||
},
|
||||
"runtimes": {
|
||||
// for docker-compose
|
||||
"nvidia": {
|
||||
"path": "/usr/bin/nvidia-container-runtime",
|
||||
"runtimeArgs": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl restart docker
|
||||
|
||||
usermod -aG docker <user>
|
||||
|
||||
# to create mandatory device files on /dev
|
||||
docker run --gpus all nvidia/cuda:10.2-cudnn7-runtime nvidia-smi
|
||||
|
||||
GPU_OPTS=(--gpus all --device /dev/nvidia0 --device /dev/nvidiactl --device /dev/nvidia-modeset --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools)
|
||||
docker run --rm -it ${GPU_OPTS} nvidia/cuda:10.2-cudnn7-runtime nvidia-smi
|
||||
docker run --rm -it ${GPU_OPTS} tensorflow/tensorflow:1.14.0-gpu-py3 bash
|
||||
|
||||
docker create network webproxy
|
||||
```
|
||||
|
||||
### Use `journald` log driver in Docker Compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
web:
|
||||
logging:
|
||||
driver: "journald"
|
||||
options:
|
||||
tag: "{{.ImageName}}/{{.Name}}/{{.ID}}" # default: "{{.ID}}"
|
||||
```
|
||||
|
||||
- [Configure logging drivers | Docker Documentation](https://docs.docker.com/config/containers/logging/configure/)
|
||||
|
||||
# Additional setup
|
||||
|
||||
## Fail2ban
|
||||
|
||||
```
|
||||
pacman -S fail2ban
|
||||
```
|
||||
|
||||
```ini /etc/fail2ban/filter.d/bad-auth.conf
|
||||
[INCLUDES]
|
||||
before = common.conf
|
||||
|
||||
[Definition]
|
||||
failregex = .* client login failed: .+ client:\ <HOST>
|
||||
ignoreregex =
|
||||
```
|
||||
|
||||
```ini /etc/fail2ban/jail.local
|
||||
[DEFAULT]
|
||||
ignoreip = 127.0.0.1/8 10.0.1.0/24
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = 22,10122
|
||||
bantime = 1h
|
||||
mode = aggressive
|
||||
|
||||
# https://github.com/Mailu/Mailu/blob/master/docs/faq.rst#do-you-support-fail2ban
|
||||
[mailu]
|
||||
enabled = true
|
||||
backend = systemd
|
||||
journalmatch = CONTAINER_NAME=mail_front_1
|
||||
filter = bad-auth
|
||||
findtime = 1h
|
||||
maxretry = 3
|
||||
bantime = 1w
|
||||
chain = DOCKER-USER
|
||||
banaction = iptables-allports
|
||||
```
|
||||
|
||||
```patch /etc/systemd/system/fail2ban.service
|
||||
- After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service
|
||||
+ After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service docker.service
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl enable --now fail2ban
|
||||
fail2ban-client status sshd
|
||||
```
|
||||
|
||||
## Telegraf
|
||||
|
||||
```bash
|
||||
yay -S telegraf
|
||||
```
|
||||
|
||||
```ini /etc/telegraf/telegraf.conf
|
||||
# Global tags can be specified here in key="value" format.
|
||||
[global_tags]
|
||||
|
||||
# Configuration for telegraf agent
|
||||
[agent]
|
||||
interval = "15s"
|
||||
round_interval = true
|
||||
metric_batch_size = 1000
|
||||
metric_buffer_limit = 10000
|
||||
collection_jitter = "0s"
|
||||
flush_interval = "10s"
|
||||
flush_jitter = "0s"
|
||||
precision = ""
|
||||
hostname = ""
|
||||
omit_hostname = false
|
||||
|
||||
# Read InfluxDB-formatted JSON metrics from one or more HTTP endpoints
|
||||
[[outputs.influxdb]]
|
||||
urls = ["http://127.0.0.1:8086"]
|
||||
database = "<db>"
|
||||
username = "<user>"
|
||||
password = "<password>"
|
||||
|
||||
# Read metrics about cpu usage
|
||||
[[inputs.cpu]]
|
||||
percpu = true
|
||||
totalcpu = true
|
||||
collect_cpu_time = false
|
||||
report_active = false
|
||||
|
||||
# Read metrics about disk usage by mount point
|
||||
[[inputs.disk]]
|
||||
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]
|
||||
|
||||
# Read metrics about disk IO by device
|
||||
[[inputs.diskio]]
|
||||
|
||||
# Get kernel statistics from /proc/stat
|
||||
[[inputs.kernel]]
|
||||
|
||||
# Read metrics about memory usage
|
||||
[[inputs.mem]]
|
||||
|
||||
# Get the number of processes and group them by status
|
||||
[[inputs.processes]]
|
||||
|
||||
# Read metrics about system load & uptime
|
||||
[[inputs.system]]
|
||||
|
||||
# Read metrics about network interface usage
|
||||
[[inputs.net]]
|
||||
interfaces = ["enp5s0"]
|
||||
|
||||
# Read metrics about docker containers
|
||||
[[inputs.docker]]
|
||||
endpoint = "unix:///var/run/docker.sock"
|
||||
perdevice = false
|
||||
total = true
|
||||
|
||||
[[inputs.fail2ban]]
|
||||
interval = "15m"
|
||||
use_sudo = true
|
||||
|
||||
# Pulls statistics from nvidia GPUs attached to the host
|
||||
[[inputs.nvidia_smi]]
|
||||
timeout = "30s"
|
||||
|
||||
[[inputs.http_response]]
|
||||
interval = "5m"
|
||||
urls = [
|
||||
"https://example.com"
|
||||
]
|
||||
|
||||
# Monitor sensors, requires lm-sensors package
|
||||
[[inputs.sensors]]
|
||||
interval = "60s"
|
||||
remove_numbers = false
|
||||
|
||||
# Run executable as long-running input plugin
|
||||
[[inputs.execd]]
|
||||
interval = "15s"
|
||||
command = ["/metrics.sh"]
|
||||
name_override = "metrics"
|
||||
signal = "STDIN"
|
||||
restart_delay = "20s"
|
||||
data_format = "logfmt"
|
||||
```
|
||||
|
||||
```ini /etc/sudoers.d/telegraf
|
||||
Cmnd_Alias FAIL2BAN = /usr/bin/fail2ban-client status, /usr/bin/fail2ban-client status *
|
||||
telegraf ALL=(root) NOEXEC: NOPASSWD: FAIL2BAN
|
||||
Defaults!FAIL2BAN !logfile, !syslog, !pam_session
|
||||
```
|
||||
|
||||
```bash
|
||||
chmod 440 /etc/sudoers.d/telegraf
|
||||
usermod -aG docker telegraf
|
||||
telegraf -config /etc/telegraf/telegraf.conf -test
|
||||
systemctl enable --now telegraf
|
||||
```
|
||||
|
||||
## cfddns
|
||||
|
||||
Dynamic DNS for Cloudflare.
|
||||
|
||||
> Start [the GitHub repo](https://github.com/uetchy/cfddns) if you like :)
|
||||
|
||||
```
|
||||
yay -S cfddns sendmail
|
||||
```
|
||||
|
||||
```yml /etc/cfddns/cfddns.yml
|
||||
token: <token>
|
||||
notification:
|
||||
enabled: true
|
||||
from: cfddns@localhost
|
||||
to: me@example.com
|
||||
```
|
||||
|
||||
```ini /etc/cfddns/domains
|
||||
example.com
|
||||
dev.example.com
|
||||
example.org
|
||||
```
|
||||
|
||||
```
|
||||
systemctl enable --now cfddns
|
||||
```
|
||||
|
||||
## Backup
|
||||
|
||||
```bash
|
||||
pacman -S restic
|
||||
```
|
||||
|
||||
```ini /etc/backup/restic.service
|
||||
[Unit]
|
||||
Description=Daily Backup Service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Nice=19
|
||||
IOSchedulingClass=2
|
||||
IOSchedulingPriority=7
|
||||
ExecStart=/etc/backup/run.sh
|
||||
```
|
||||
|
||||
```ini /etc/backup/restic.timer
|
||||
[Unit]
|
||||
Description=Daily Backup Timer
|
||||
|
||||
[Timer]
|
||||
WakeSystem=false
|
||||
OnCalendar=*-*-* 14:00
|
||||
RandomizedDelaySec=5min
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
```
|
||||
|
||||
```bash /etc/backup/run.sh
|
||||
#!/bin/bash -ue
|
||||
# usage: run.sh
|
||||
# https://restic.readthedocs.io/en/latest/040_backup.html#
|
||||
|
||||
export RESTIC_REPOSITORY=/path/to/backup
|
||||
export RESTIC_PASSWORD=<passphrase>
|
||||
export RESTIC_PROGRESS_FPS=1
|
||||
|
||||
# system
|
||||
restic backup --tag system -v \
|
||||
--one-file-system \
|
||||
--exclude .cache \
|
||||
--exclude .venv \
|
||||
--exclude .vscode-server \
|
||||
--exclude .vscode-server-insiders \
|
||||
--exclude TabNine \
|
||||
--exclude node_modules \
|
||||
--exclude /var/lib/docker/overlay2 \
|
||||
/ /boot
|
||||
|
||||
# data
|
||||
restic backup --tag data -v \
|
||||
--exclude 'appdata_*/preview' \ # nextcloud cache
|
||||
--exclude 'appdata_*/dav-photocache' \ # nextcloud cache
|
||||
/mnt/data
|
||||
|
||||
# prune
|
||||
restic forget --prune --group-by tags \
|
||||
--keep-within-daily 7d \
|
||||
--keep-within-weekly 1m \
|
||||
--keep-within-monthly 3m
|
||||
|
||||
# verify
|
||||
restic check
|
||||
```
|
||||
|
||||
```bash /etc/backup/show.sh
|
||||
#!/bin/bash
|
||||
# usage: show.sh <file|directory>
|
||||
# https://restic.readthedocs.io/en/latest/050_restore.html
|
||||
|
||||
export RESTIC_REPOSITORY=/path/to/backup
|
||||
export RESTIC_PASSWORD=<passphrase>
|
||||
export RESTIC_PROGRESS_FPS=1
|
||||
|
||||
TARGET=${1:-$(pwd)}
|
||||
MODE="ls -l"
|
||||
if [[ -f $TARGET ]]; then
|
||||
TARGET=$(realpath ${TARGET})
|
||||
MODE=dump
|
||||
fi
|
||||
|
||||
TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique| .[]' | fzy)
|
||||
ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
|
||||
|
||||
>&2 echo "Command: restic ${MODE} ${ID} ${TARGET}"
|
||||
|
||||
restic $MODE $ID ${TARGET}
|
||||
```
|
||||
|
||||
```bash /etc/backup/restore.sh
|
||||
#!/bin/bash
|
||||
|
||||
# https://restic.readthedocs.io/en/latest/050_restore.html
|
||||
|
||||
export RESTIC_REPOSITORY=/path/to/backup
|
||||
export RESTIC_PASSWORD=<passphrase>
|
||||
export RESTIC_PROGRESS_FPS=1
|
||||
|
||||
TARGET=${1:?Specify TARGET}
|
||||
TARGET=$(realpath ${TARGET})
|
||||
|
||||
TAG=$(restic snapshots --json | jq -r '[.[].tags[0]] | unique | .[]' | fzy)
|
||||
ID=$(restic snapshots --tag $TAG --json | jq -r ".[] | [.time, .short_id] | @tsv" | fzy | awk '{print $2}')
|
||||
|
||||
>&2 echo "Command: restic restore ${ID} -i ${TARGET} -t /"
|
||||
|
||||
read -p "Press enter to continue"
|
||||
|
||||
restic restore $ID -i ${TARGET} -t /
|
||||
```
|
||||
|
||||
```bash
|
||||
chmod 700 /etc/backup/{run,show}.sh
|
||||
ln -sf /etc/backup/restic.{service,timer} /etc/systemd/system/
|
||||
systemctl enable --now restic
|
||||
```
|
||||
|
||||
## Kubernetes
|
||||
|
||||
```bash
|
||||
pacman -S minikube kubectl
|
||||
minikube start --cpus=max
|
||||
kubectl taint nodes --all node-role.kubernetes.io/master- # to allow allocating pods to the master node
|
||||
|
||||
minikube ip
|
||||
kubectl cluster-info
|
||||
kubectl get cm -n kube-system kubeadm-config -o yaml
|
||||
```
|
||||
|
||||
- [Kubernetes - ArchWiki](https://wiki.archlinux.org/index.php/Kubernetes)
|
||||
- [Kubernetes Ingress Controller with NGINX Reverse Proxy and Wildcard SSL from Let's Encrypt - Shogan.tech](https://www.shogan.co.uk/kubernetes/kubernetes-ingress-controller-with-nginx-reverse-proxy-and-wildcard-ssl-from-lets-encrypt/)
|
||||
|
||||
## Audio
|
||||
|
||||
```bash
|
||||
pacman -S alsa-utils # maybe requires rebooting system
|
||||
usermod -aG audio <user>
|
||||
|
||||
# list devices as root
|
||||
aplay -l
|
||||
arecord -L
|
||||
cat /proc/asound/cards
|
||||
|
||||
# test speaker
|
||||
speaker-test -c2
|
||||
|
||||
# test mic
|
||||
arecord -vv -Dhw:2,0 -fS32_LE mic.wav
|
||||
aplay mic.wav
|
||||
|
||||
# gui mixer
|
||||
alsamixer
|
||||
|
||||
# for Mycroft.ai
|
||||
pacman -S pulseaudio pulsemixer
|
||||
pulseaudio --start
|
||||
pacmd list-cards
|
||||
```
|
||||
|
||||
```conf /etc/pulse/default.pa
|
||||
# INPUT/RECORD
|
||||
load-module module-alsa-source device="default" tsched=1
|
||||
# OUTPUT/PLAYBACK
|
||||
load-module module-alsa-sink device="default" tsched=1
|
||||
# Accept clients -- very important
|
||||
load-module module-native-protocol-unix
|
||||
load-module module-native-protocol-tcp
|
||||
```
|
||||
|
||||
```conf /etc/asound.conf
|
||||
pcm.mic {
|
||||
type hw
|
||||
card M96k
|
||||
rate 44100
|
||||
format S32_LE
|
||||
}
|
||||
|
||||
pcm.speaker {
|
||||
type plug
|
||||
slave {
|
||||
pcm "hw:1,0"
|
||||
}
|
||||
}
|
||||
|
||||
pcm.!default {
|
||||
type asym
|
||||
capture.pcm "mic"
|
||||
playback.pcm "speaker"
|
||||
}
|
||||
|
||||
#defaults.pcm.card 1
|
||||
#defaults.ctl.card 1
|
||||
```
|
||||
|
||||
- [PulseAudio as a minimal unintrusive dumb pipe to ALSA](https://wiki.archlinux.org/title/PulseAudio/Examples#PulseAudio_as_a_minimal_unintrusive_dumb_pipe_to_ALSA)
|
||||
- [SoundcardTesting - AlsaProject](https://www.alsa-project.org/main/index.php/SoundcardTesting)
|
||||
- [Advanced Linux Sound Architecture/Troubleshooting - ArchWiki](https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture/Troubleshooting#Microphone)
|
||||
- [ALSA project - the C library reference: PCM (digital audio) plugins](https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html)
|
||||
- [Asoundrc - AlsaProject](https://www.alsa-project.org/wiki/Asoundrc)
|
||||
|
||||
## Firewall
|
||||
|
||||
```bash
|
||||
pacman -S firewalld
|
||||
systemctl enable --now firewalld
|
||||
```
|
||||
|
||||
See [Introduction to Netfilter – To Linux and beyond !](https://home.regit.org/netfilter-en/netfilter/).
|
||||
|
||||
# Maintenance
|
||||
|
||||
## Quick checkups
|
||||
|
||||
```bash
|
||||
htop # show task overview
|
||||
systemctl --failed # show failed units
|
||||
free -h # show memory usage
|
||||
lsblk -f # show disk usage
|
||||
networkctl status # show network status
|
||||
userdbctl # show users
|
||||
nvidia-smi # verify nvidia cards
|
||||
ps aux | grep "defunct" # find zombie processes
|
||||
```
|
||||
|
||||
## Delve into system logs
|
||||
|
||||
```bash
|
||||
journalctl -p err -b-1 -r # show error logs from previous boot in reverse order
|
||||
journalctl -u sshd -f # tail logs from sshd unit
|
||||
journalctl --no-pager -n 25 -k # show latest 25 logs from the kernel without pager
|
||||
journalctl --since=yesterday --until "2020-07-10 15:10:00" # show logs within specific time range
|
||||
journalctl CONTAINER_NAME=service_web_1 # show error from docker container named 'service_web_1'
|
||||
journalctl _PID=2434 -e # filter logs based on PID and jump to the end of the logs
|
||||
journalctl -g 'timed out' # filter logs based on regular expression. if the pattern is all lowercase, matching is case insensitive
|
||||
```
|
||||
|
||||
- g - go to the first line
|
||||
- G - go to the last line
|
||||
- / - search for the string
|
||||
|
||||
## Force overriding installation
|
||||
|
||||
```bash
|
||||
pacman -S <pkg> --overwrite '*'
|
||||
```
|
||||
|
||||
## Check memory modules
|
||||
|
||||
```bash
|
||||
pacman -S lshw dmidecode
|
||||
|
||||
lshw -short -C memory # lists installed mems
|
||||
dmidecode # shows configured clock speed
|
||||
```
|
||||
|
||||
## File-system related issues checklist
|
||||
|
||||
```bash
|
||||
smartctl -H /dev/sdd
|
||||
|
||||
# umount the drive before this ops
|
||||
e2fsck -C 0 -p /dev/sdd1 # preen
|
||||
e2fsck -C 0 -cc /dev/sdd1 # badblocks
|
||||
```
|
||||
|
||||
# Common issues
|
||||
|
||||
## Longer SSH login (D-bus glitch)
|
||||
|
||||
```bash
|
||||
systemctl restart systemd-logind
|
||||
systemctl restart polkit
|
||||
```
|
||||
|
||||
- [A comprehensive guide to fixing slow SSH logins – JRS Systems: the blog](https://jrs-s.net/2017/07/01/slow-ssh-logins/)
|
||||
|
||||
## Annoying `systemd-homed is not available` log messages
|
||||
|
||||
Move `pam_unix` before `pam_systemd_home`.
|
||||
|
||||
```ini /etc/pam.d/system-auth
|
||||
#%PAM-1.0
|
||||
|
||||
auth required pam_faillock.so preauth
|
||||
# Optionally use requisite above if you do not want to prompt for the password
|
||||
# on locked accounts.
|
||||
auth [success=2 default=ignore] pam_unix.so try_first_pass nullok
|
||||
-auth [success=1 default=ignore] pam_systemd_home.so
|
||||
auth [default=die] pam_faillock.so authfail
|
||||
auth optional pam_permit.so
|
||||
auth required pam_env.so
|
||||
auth required pam_faillock.so authsucc
|
||||
# If you drop the above call to pam_faillock.so the lock will be done also
|
||||
# on non-consecutive authentication failures.
|
||||
|
||||
account [success=1 default=ignore] pam_unix.so
|
||||
-account required pam_systemd_home.so
|
||||
account optional pam_permit.so
|
||||
account required pam_time.so
|
||||
|
||||
password [success=1 default=ignore] pam_unix.so try_first_pass nullok shadow
|
||||
-password required pam_systemd_home.so
|
||||
password optional pam_permit.so
|
||||
|
||||
session required pam_limits.so
|
||||
session required pam_unix.so
|
||||
session optional pam_permit.so
|
||||
```
|
||||
|
||||
- [[solved] pam fails to find unit dbus-org.freedesktop.home1.service / Newbie Corner / Arch Linux Forums](https://bbs.archlinux.org/viewtopic.php?id=258297)
|
||||
|
||||
## Annoying systemd-journald-audit log
|
||||
|
||||
```ini /etc/systemd/journald.conf
|
||||
Audit=no
|
||||
```
|
||||
|
||||
## Missing `/dev/nvidia-{uvm*,modeset}`
|
||||
|
||||
This occurs after updating linux kernel.
|
||||
|
||||
- Run `docker run --rm --gpus all --device /dev/nvidia0 --device /dev/nvidiactl --device /dev/nvidia-modeset --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools -it nvidia/cuda:10.2-cudnn7-runtime nvidia-smi` once.
|
||||
|
||||
## `[sudo] Incorrect password` while password is correct
|
||||
|
||||
```bash
|
||||
faillock --reset
|
||||
```
|
||||
|
||||
# Useful links
|
||||
|
||||
- [General recommendations](https://wiki.archlinux.org/index.php/General_recommendations#Users_and_groups)
|
||||
- [System maintenance](https://wiki.archlinux.org/index.php/System_maintenance)
|
||||
- [Improving performance](https://wiki.archlinux.org/index.php/Improving_performance#Know_your_system)
|
||||
- [General troubleshooting - ArchWiki](https://wiki.archlinux.org/title/General_troubleshooting)
|
||||
- [Stress testing - ArchWiki](https://wiki.archlinux.org/title/Stress_testing#Stressing_memory)
|
||||
- [udev - ArchWiki](https://wiki.archlinux.org/title/Udev#Debug_output)
|
||||
- [[HOWTO] Repair Broken system, system without a kernel / Forum & Wiki discussion / Arch Linux Forums](https://bbs.archlinux.org/viewtopic.php?id=18066)
|
||||
- [Archboot - ArchWiki](https://wiki.archlinux.org/title/Archboot)
|
||||
- [Restic Documentation — restic 0.12.1 documentation](https://restic.readthedocs.io/en/stable/)
|
102
source/_posts/2021/oauth-jwt-rfcs.md
Normal file
102
source/_posts/2021/oauth-jwt-rfcs.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: OAuth 2.0 と JWT 関連 RFC
|
||||
date: 2021-02-11
|
||||
---
|
||||
|
||||
個人的な調査のために OAuth 2.0 と JWT 関連 RFC を発行日順に並べた。
|
||||
|
||||
## [RFC6749](https://tools.ietf.org/html/rfc6749) — The OAuth 2.0 Authorization Framework
|
||||
|
||||
2012 年 10 月
|
||||
|
||||
OAuth 1.0a に代わる新たな認証基盤 OAuth 2.0 のコアを規定しており、特筆すべき点がいくつかある。
|
||||
|
||||
- `access_token` の内容は規定されておらず、ベンダーに委ねられている
|
||||
- JWS でもなんでもいい
|
||||
- リソースサーバーに `access_token` を渡す方法は規定されていない(同月発行の RFC6750 で規定された)
|
||||
|
||||
### Authorization Grant
|
||||
|
||||
トークンエンドポイントで`access_token`を発行してもらう際に使用できる Grant (許可証)は、提案中の拡張仕様を含めて 5 つある。
|
||||
|
||||
1. Authorization Code Grant: [RFC6749 – Section 1.3.1](https://tools.ietf.org/html/rfc6749#section-1.3.1)
|
||||
1. `grant_type=authorization_code`
|
||||
2. Authorization Code Grant with PKCE
|
||||
2. Implicit Flow: [RFC6749 – Section 1.3.2](https://tools.ietf.org/html/rfc6749#section-1.3.2)
|
||||
1. もともと CORS (Cross Origin Resource Sharing) が登場する以前の SPA で、POST リクエストを回避しつつ Access Token を得る"妥協案"として策定された
|
||||
2. CSRF 耐性が無い ([RFC6819 - Section 4.4.2.5](https://tools.ietf.org/html/rfc6819#section-4.4.2.5))ため、使うべきではない
|
||||
3. Resource Owner Password Credentials Grant: [RFC6749 – Section 1.3.3](https://tools.ietf.org/html/rfc6749#section-1.3.3)
|
||||
1. 直接パスワードで認証する形式
|
||||
4. Client Credentials Grant: [RFC6749 – Section 1.3.4](https://tools.ietf.org/html/rfc6749#section-1.3.4)
|
||||
1. クライアントシークレットでトークンを取得する形式。
|
||||
5. Device Grant: [RFC Draft — OAuth 2.0 Device Authorization Grant](https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15)
|
||||
1. 入力機器が無い場合もある組み込みデバイス向けの認証フロー
|
||||
|
||||
## [RFC6750](https://tools.ietf.org/html/rfc6750) — The OAuth 2.0 Authorization Framework: Bearer Token Usage
|
||||
|
||||
2012 年 10 月
|
||||
|
||||
OAuth 2.0 において、`access_token`をリソースサーバーに渡す手法を規定する。OAuth 2.0 JWT Bearer Token Flow**ではない**。
|
||||
|
||||
手法として 3 つが挙げられている。
|
||||
|
||||
1. Bearer Token (**SHOULD**)
|
||||
2. Form Encoded Parameters (SHOULD NOT)
|
||||
3. URI Query Parameters (SHOULD NOT)
|
||||
|
||||
## [OICD](https://openid.net/specs/openid-connect-core-1_0.html) — OpenID Connect Core 1.0
|
||||
|
||||
2014 年 11 月
|
||||
|
||||
OAuth 2.0 の上にいくつか仕様を足したサブセット。
|
||||
|
||||
## [RFC7515](https://tools.ietf.org/html/rfc7515) — JSON Web Signature (JWS)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JSON ベースの署名プロトコル。
|
||||
|
||||
## [RFC7516](https://tools.ietf.org/html/rfc7516) — JSON Web Encryption (JWE)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JSON ベースの暗号化プロトコル。
|
||||
|
||||
## [RFC7517](https://tools.ietf.org/html/rfc7517) — JSON Web Key (JWK)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JWT の署名チェックに用いる公開鍵を配信するためのプロトコル。
|
||||
|
||||
## [RFC7518](https://tools.ietf.org/html/rfc7518) — JSON Web Algorithms (JWA)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JWS、JWE、JWK で利用されるアルゴリズム (alg)やその他プロパティを規定する。
|
||||
|
||||
## [RFC7519](https://tools.ietf.org/html/rfc7519) — JSON Web Token (JWT)
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
JWT は JSON を利用して Assertion を生成するための仕様。
|
||||
|
||||
## [RFC7521](https://tools.ietf.org/html/rfc7521) — Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
|
||||
|
||||
2015 年 5 月
|
||||
|
||||
任意の Assertion を OAuth 2.0 Client Authentication の Client Credentials として使ったり、あるいは Authorization Grant として Access Token と交換するための仕様。
|
||||
|
||||
トークンエンドポイントに強化されたクライアント認証を付与する。続く RFC で、それぞれ SAML と JWT を使用したパターンを規定している。
|
||||
|
||||
**OAuth 2.0 JWT Bearer Token Flow**とも呼ばれている。
|
||||
|
||||
- [RFC7522](https://tools.ietf.org/html/rfc7522) — Security Assertion Markup Language (**SAML**) 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)
|
||||
- [RFC7523](https://tools.ietf.org/html/rfc7523) — JSON Web Token (**JWT**) Profile for OAuth 2.0 Client Authentication and Authorization Grants (2015 年 5 月)
|
||||
|
||||
2015 年 5 月 https://tools.ietf.org/html/rfc7523
|
||||
|
||||
## [RFC Draft](https://tools.ietf.org/html/draft-ietf-oauth-access-token-jwt-02) — JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
|
||||
|
||||
2019 年 7 月
|
||||
|
||||
リソースサーバーへ渡す Access Token に JWT を使用することを定めている。
|
26
source/_posts/2021/parseint-magic.md
Normal file
26
source/_posts/2021/parseint-magic.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: "[].map(parseInt)"
|
||||
date: 2021-02-14T11:30:00
|
||||
---
|
||||
|
||||
Fun fact: `[0xa, 0xa, 0xa].map(parseInt)` yields `[10, NaN, 2]`.
|
||||
|
||||
# Why
|
||||
|
||||
```js
|
||||
parseInt(0xa, 0, [0xa, 0xa, 0xa]);
|
||||
```
|
||||
|
||||
The second argument is `0` so the first argument going to be treated as decimal number becoming `10`.
|
||||
|
||||
```js
|
||||
parseInt(0xa, 1, [0xa, 0xa, 0xa]);
|
||||
```
|
||||
|
||||
The second argument is `1` which is invalid as a radix, so the result ends up with `NaN`.
|
||||
|
||||
```js
|
||||
parseInt(0xa, 2, [0xa, 0xa, 0xa]);
|
||||
```
|
||||
|
||||
The second argument is `2` meaning the first argument going to be handled as a binary number. `0xa` is `10` in binary, which results in `2` in decimal form.
|
70
source/_posts/2021/server-2020.md
Normal file
70
source/_posts/2021/server-2020.md
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: 新しい自宅サーバーの構成
|
||||
date: 2021-02-13T00:00:00
|
||||
---
|
||||
|
||||
10 年ぶりにサーバーを更新した。初めての AMD、初めての DDR4、初めての NVM Express!
|
||||
|
||||
# 用途
|
||||
|
||||
- 各種セルフホスト (Docker)
|
||||
- Docker Swarm / K8s のマスター
|
||||
- 計算実験
|
||||
- VS Code Remote SSH のホストマシン
|
||||
- VPN 他
|
||||
|
||||
# スペック
|
||||
|
||||
重いタスクを並列してやらせたいので最優先は CPU とメモリ。メモリは[DDR4-3200 32GBx2](https://shop.tsukumo.co.jp/goods/4582353591719/) を、CPU は昨今のライブラリのマルチコア対応を勘案して [Ryzen 9 3950X](https://www.amd.com/en/products/cpu/amd-ryzen-9-3950x) を選んだ。CPU クーラーは静音性を考えて Noctua の [NH-D15 Black](https://noctua.at/en/nh-d15) 。
|
||||
|
||||
> 結果から言うとメモリは 64GB では足りなかった。巨大な Pandas データフレームを並列処理したり、DeepSpeed でモデルの重みをオフロードするたびに OOM が発動してしまう。最終的に 128GB まで増やす羽目になった。
|
||||
|
||||
> 追記: メモリ異常を起因とするシステム誤動作により、`/sbin` 以下がゼロ上書きされカーネルが起動しなくなる災害が起きた。後日 ECC 付きのメモリに交換してからは、現在に至るまでメモリ関連の異常は発生していない。常時稼働するサーバーには最初から ECC メモリを選ぼう。
|
||||
|
||||
GPU は古いサーバーに突っ込んでいた NVIDIA GeForce GTX TITAN X (Maxwell)を流用した。グラフィックメモリが 12GB ちょっとしかないが、最大ワークロード時でも 5GB は残るので今のところ十分。
|
||||
|
||||
> 結果から言うと GPT-J や Megatron-LM を始めとした億パラメータ級のモデルを学習・推論させるには、DeepSpeed の助けがあったとしても最低 16GB の VRAM が必要だった。
|
||||
|
||||
記憶装置は WD HDD 3TB 2 台と Samsung 970 EVO Plus 500GB M.2 PCIe、そして古いサーバーから引っこ抜いた Samsung 870 EVO Plus 500GB SSD 。NVMe メモリは OS 用、SSD/HDD はデータとバックアップ用にする。
|
||||
|
||||
マザーボードは、X570 と比較して実装されているコンデンサーやパーツがサーバー向きだと感じた[ASRock B550 Taichi](https://www.asrock.com/mb/AMD/B550%20Taichi/) にした。
|
||||
|
||||
電源は今後 GPU を追加することを考えて [Seasonic PRIME TX 850](https://seasonic.com/prime-tx) を選んだ。実際にサーバーを稼働させながら使用電力を計測したところ、アイドル時に 180W 前後、フル稼働時でも 350W を超えない程度だった。
|
||||
|
||||
ケースは Fractal Design の [Meshify 2](https://www.fractal-design.com/products/cases/meshify/meshify-2/Black/) 。
|
||||
|
||||
OS は長年付き合ってきた Ubuntu と袂を分かち、[Arch Linux](https://archlinux.org/) を選んだ。ミニマルと実用の間のバランスが取れていて好み。
|
||||
|
||||
Arch Linux のセットアップは[個別に記事](https://uechi.io/blog/installing-arch-linux/)を書いた。
|
||||
|
||||
また、AUR (Arch User Repository)にパッケージを公開したい人向けに、Docker 自動ビルド・テストツールを[GitHub で公開](https://github.com/uetchy/archpkgs)した。
|
||||
|
||||
# パーツ選定時のポイント
|
||||
|
||||
- [WikiChip](https://en.wikichip.org/wiki/WikiChip)で CPU のモデルやスペックを調査する
|
||||
- [PCPartPicker](https://jp.pcpartpicker.com/)でパーツのコスト計算をする
|
||||
- [Bottleneck Calculator](https://pc-builds.com/calculator/)で CPU と GPU の組み合わせを選び、そのうちどちらが性能のボトルネックになるか調べる
|
||||
- [UserBenchmark](https://www.userbenchmark.com/)でユーザーが投稿したベンチマーク結果を眺める
|
||||
- [Linux Hardware Database](https://linux-hardware.org/) を見て、インストールする予定の Linux ディストリとパーツの相性をチェックする
|
||||
- CPU クーラーは大口径の方が静か
|
||||
- PSU は Seasonic が評判良い
|
||||
- 東芝 D01 が HGST の系譜
|
||||
- [B550](https://www.amd.com/en/chipsets/b550) は長期運用に向いている(らしい)
|
||||
- B520 は廉価版
|
||||
- TSUKUMO eX. の自作 PC コーナーのスタッフはガチ勢なので信頼できる
|
||||
- 不明な部分があれば根掘り葉掘り聞く
|
||||
|
||||
# 組立ての勘所
|
||||
|
||||
- 少なくとも 1 年間はすべての箱・書類を取っておく(特にメモリは箱自体が保証書代わりになっている場合がある)
|
||||
- 筐体は無視してまずマザボ、CPU、クーラー、(オンボードグラフィックが無い CPU なら)グラボ、そして電源を繋いで通電・動作テストをする
|
||||
- [MemTest86](https://www.memtest86.com/)でメモリの動作テストを最後までやる(エラーが出たら交換依頼)
|
||||
- USB ブートで OS の起動確認
|
||||
- Ethernet が死んでいる場合は USB-Ethernet アダプターでまずネットを確保する
|
||||
- ほとんどの場合 Linux カーネルのバージョンを上げると(デバイスドライバーも新しくなり)直る
|
||||
- Arch Linux の場合: `linux-lts`が駄目なら`linux`に切り替えて試す
|
||||
- Ubuntu の場合: [kernel.ubuntu.com](https://kernel.ubuntu.com/~kernel-ppa/mainline/?C=N;O=D) から探してアップデートする([https://itsfoss.com/upgrade-linux-kernel-ubuntu/](https://itsfoss.com/upgrade-linux-kernel-ubuntu/))
|
||||
- 駄目ならマザボまたはアダプターメーカーからアップデートを探す
|
||||
- 安い筐体のネジは柔いことがあるため、強く押し込みながら少しずつ回す
|
||||
- 山が潰れてきたらゴムシートを挟む
|
||||
- すべて動いたら、[Linux Hardware Database に Probe を送信](https://linux-hardware.org/index.php?view=howto)して貢献
|
148
source/_posts/2021/split-bill.md
Normal file
148
source/_posts/2021/split-bill.md
Normal file
@@ -0,0 +1,148 @@
|
||||
---
|
||||
title: 最小送金回数で精算する割り勘アルゴリズム
|
||||
date: 2021-02-14T00:00:00
|
||||
---
|
||||
|
||||
大人数で旅行を楽しんだあとに待っているのは耐え難き精算・送金処理だ。
|
||||
次回から楽をするためにも、送金回数を最小化する制約で精算表を作る方法を考えよう。
|
||||
|
||||
# tl;dr
|
||||
|
||||
アイディアは「最も支払わなかった人が最も支払った人に払えるだけ払う ⇢ 債権を再計算して繰り返す」
|
||||
|
||||
1. 全員の出費を算出(払い過ぎは正、払わなさすぎは負の数)
|
||||
2. 降順でソート(出費過多が先頭)
|
||||
3. リストの最後(最大債務者, 出費=L)がリストの最初(最大債権者, F)に $\min(F, |L|)$ を支払ってバランスを再計算
|
||||
4. 全員のバランスが 0 になるまで 2-3 を繰り返す
|
||||
|
||||
# 実験
|
||||
|
||||
実際にコードを書いて本当に望んでいる結果が得られるのかを検証する。
|
||||
|
||||
```js split-bill.js
|
||||
const history = [
|
||||
{
|
||||
amount: 121,
|
||||
payer: "A",
|
||||
involves: ["A", "B", "C"],
|
||||
},
|
||||
{
|
||||
amount: 98,
|
||||
payer: "B",
|
||||
involves: ["A", "B", "C"],
|
||||
},
|
||||
{
|
||||
amount: 10,
|
||||
payer: "C",
|
||||
involves: ["A", "B", "C"],
|
||||
},
|
||||
{
|
||||
amount: 10,
|
||||
payer: "C",
|
||||
involves: ["A", "B"],
|
||||
},
|
||||
{
|
||||
amount: 50,
|
||||
payer: "C",
|
||||
involves: ["A"], // meaning C lent A 50
|
||||
},
|
||||
];
|
||||
|
||||
// calculate balance sheet
|
||||
const init = { balance: 0, consumption: 0 };
|
||||
Map.prototype.fetch = function (id) {
|
||||
return (
|
||||
this.get(id) || this.set(id, Object.assign({ name: id }, init)).get(id)
|
||||
);
|
||||
};
|
||||
|
||||
const data = new Map();
|
||||
|
||||
for (const { payer, amount, involves } of history) {
|
||||
const record = data.fetch(payer);
|
||||
record.balance += amount;
|
||||
const debt = Math.ceil(amount / involves.length);
|
||||
// actual payer should not owe extra debt coming from rounded up numbers
|
||||
const payerDebt = amount - debt * (involves.length - 1);
|
||||
for (const debtor of involves.map((i) => data.fetch(i))) {
|
||||
const cost = Math.round(amount / involves.length);
|
||||
debtor.balance -= cost;
|
||||
debtor.consumption += cost;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
|
||||
// calculate transaction table
|
||||
const transaction = [];
|
||||
let paidTooMuch, paidLess;
|
||||
while (true) {
|
||||
for (const [_, tbl] of data) {
|
||||
if (tbl.balance >= (paidTooMuch?.balance || 0)) {
|
||||
paidTooMuch = tbl;
|
||||
}
|
||||
if (tbl.balance <= (paidLess?.balance || 0)) {
|
||||
paidLess = tbl;
|
||||
}
|
||||
}
|
||||
|
||||
if (paidLess.balance == 0 || paidTooMuch.balance == 0) break;
|
||||
|
||||
const amount = Math.min(paidTooMuch.balance, Math.abs(paidLess.balance));
|
||||
|
||||
transaction.push({
|
||||
sender: paidLess.name,
|
||||
receiver: paidTooMuch.name,
|
||||
amount,
|
||||
});
|
||||
|
||||
paidTooMuch.balance -= amount;
|
||||
paidLess.balance += amount;
|
||||
}
|
||||
|
||||
console.log("Settled");
|
||||
|
||||
console.log("\n# Transaction table");
|
||||
for (const ev of transaction) {
|
||||
console.log(`${ev.sender} owes ${ev.receiver} ¥${ev.amount}`);
|
||||
}
|
||||
|
||||
console.log("\n# History");
|
||||
for (const { payer, amount, involves } of history) {
|
||||
if (involves.length === 1) {
|
||||
console.log(`${payer} lent ¥${amount} to ${involves[0]}`);
|
||||
} else {
|
||||
console.log(`${payer} paid ¥${amount} for ${involves.join(", ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("\n# Expenses");
|
||||
for (const [_, { name, consumption }] of data) {
|
||||
console.log(`${name} virtually paid ¥${consumption} in total`);
|
||||
}
|
||||
```
|
||||
|
||||
`history`に支払い履歴を書き込んで実行すると、「送金表」「履歴」「実質支払総額」が得られる。
|
||||
|
||||
```md
|
||||
# Transaction table
|
||||
|
||||
A owes B ¥10
|
||||
C owes B ¥6
|
||||
|
||||
# History
|
||||
|
||||
A paid ¥121 for A, B, C
|
||||
B paid ¥98 for A, B, C
|
||||
C paid ¥10 for A, B, C
|
||||
C paid ¥10 for A, B
|
||||
C lent ¥50 to A
|
||||
|
||||
# Expenses
|
||||
|
||||
A virtually paid ¥131 in total
|
||||
B virtually paid ¥81 in total
|
||||
C virtually paid ¥76 in total
|
||||
```
|
||||
|
||||
プログラムに落とし込むことができたら、あとはスプレッドシートのマクロにするなり自由だ。面倒なことは全部コンピューターにやらせよう!
|
77
source/_posts/2021/uco-oil-lantern.md
Normal file
77
source/_posts/2021/uco-oil-lantern.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: 手のひらサイズのオイルランタン
|
||||
date: 2021-06-08T00:00:00
|
||||
---
|
||||
|
||||
UCO キャンドルランタンを改造して手のひらサイズのオイルランタンを作った。
|
||||
|
||||

|
||||
|
||||
# 特徴
|
||||
|
||||
- 手のひらサイズのオイルランタン
|
||||
- ロウソクより大きい炎
|
||||
- 暗所でもオイル残量が見やすい
|
||||
- 揺らしてもオイルが漏れない
|
||||
- 瓶を入れたまま仕舞える
|
||||
|
||||
# 材料
|
||||
|
||||
ほとんどのパーツはドラッグストアやホームセンターで調達できる。
|
||||
|
||||
1. 大正漢方胃腸薬(30 ml)
|
||||

|
||||
2. C タイプアンカー M8(ステンレス)
|
||||
3. 袋ナット M8(ステンレス)
|
||||
4. ハードロックボルト M8(ステンレス)
|
||||
5. [ゴムパッキン 直径 28x 内径 23x 厚さ 2mm](https://www.amazon.co.jp/gp/product/B003PHKRZS)(耐熱ではないけど今のところ耐えている)
|
||||
6. [3mm グラスファイバー芯](https://www.amazon.co.jp/gp/product/B07X1VZFGB)
|
||||
7. 隙間テープ(ダイソー)
|
||||
|
||||
# 手順
|
||||
|
||||
1. M8 アンカーのネジ部分を金属ノコギリで切断して断面をヤスリで整える
|
||||
2. キャップに印字されているラベルをヤスリで削りとる(任意)
|
||||
3. キャップの裏に張り付いている液漏れ防止シールを剥がす(熱で溶解するため)
|
||||
4. キャップの内側からドリルで穴をあけ、棒やすりでネジが入るサイズまで広げる
|
||||
5. ネジをキャップに差し込む
|
||||
6. ゴムパッキンをキャップの裏にはめ込む
|
||||
7. ハードロックボルトでネジの両側を固定する(レンチ等を使用して強く固定する)
|
||||
8. 芯をボルトの中に通す(テープで芯の先を固定するとやりやすい)
|
||||
9. 袋ネジで封をする
|
||||
10. 切断した隙間テープをランタンの底面キャップに巻きつける
|
||||
11. 瓶をランタンに差し込み底面キャップを締める
|
||||
|
||||
# 使用法
|
||||
|
||||
1. パラフィンオイルを 4/5 ほど入れてキャップを締め、オイルが芯の先に浸透するまで 15 分以上放置する
|
||||
2. 芯の焦げている部分を 1mm 前後、それ以外の部分を 1mm ほど露出させてほぐす
|
||||
3. 芯に火を付けてホヤを上げる
|
||||
4. 使わないときはオイルを抜く(オイルが入ったままだと毛細管現象で染み出してくる)
|
||||
|
||||
## 🔥 燃焼時間
|
||||
|
||||
- 3-4cm の炎で 2-3 時間
|
||||
- 最大 3 時間 47 分
|
||||
|
||||

|
||||
|
||||
# 製作メモ
|
||||
|
||||
## UCO キャンドルランタンの寸法 (mm)
|
||||
|
||||
| 筒の経 | 筒の長さ | 筒口(上) | 土台経 | キャップ内径 | 筒露出長 |
|
||||
| ------ | -------- | ---------- | ------ | ------------ | -------- |
|
||||
| 35.0 | 92.45 | 20.0 | 32.5 | 41.7 | 9.0 |
|
||||
|
||||
## やってみたい
|
||||
|
||||
- **内径が 18 ~ 21、太さが 2mm 程度**で耐油性のあるパッキンを試す
|
||||
- M8 ボルトが通り、外径がガラス内径に近い低めの瓶を探す
|
||||
- ガスケットで密封?
|
||||
|
||||
## 失敗例: M6 ボルトは微妙
|
||||
|
||||
ネットで広く紹介されている M6 ボルトを使う方法だと、炎がロウソク並に小さくなってしまった。あまりオススメできない。
|
||||
|
||||

|
BIN
source/_posts/2021/uco-oil-lantern/comparison.jpeg
Executable file
BIN
source/_posts/2021/uco-oil-lantern/comparison.jpeg
Executable file
Binary file not shown.
After Width: | Height: | Size: 838 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user