OmniAICreator/Qiita-1.07M huggingface dataset:
Homebrew2.0.0にバージョン上げたらCaskが動かなくなった。Error: Cask 'google-photos-backup' definition is invalid: invalid 'depends_on macos' value: ":lion"

```bash
brew cask list                                                                                                                                                                                                                                                                                 (16s 578ms) 
Error: Cask 'google-photos-backup' definition is invalid: invalid 'depends_on macos' value: ":lion"
```

こんな感じでエラーが出る。`uninstall`コマンドも同様のエラーが出るので削除できない。2.0.0からOS X Mountain Lion (10.8)が動かなくなるらしい。

> Homebrew does not run on OS X Mountain Lion (10.8) and below. For 10.4 - 10.6 support, see Tigerbrew. This has allowed us to remove large amounts of legacy code.

https://brew.sh/2019/02/02/homebrew-2.0.0/

インストールファイルの中身を見てみる。

```/usr/local/Caskroom/google-photos-backup/.metadata/latest/20161229135825.871/Casks/google-photos-backup.rb
cask 'google-photos-backup' do
  version :latest
  sha256 :no_check

  url 'https://dl.google.com/dl/picasa/gpautobackup_setup.dmg'
  name 'Google Photos Backup'
  homepage 'https://www.google.com/photos/about/'

  depends_on macos: '>= :lion'

  app 'Google Photos Backup.app'

  zap delete: [
                '~/Library/Application Support/Google/Google Photos Backup',
                '~/Library/Caches/com.google.gpautobackup',
                '~/Library/Preferences/com.google.gpautobackup.plist',
              ],
      rmdir:  '~/Library/Application Support/Google'
end
```

それっぽい箇所があったのでコメントアウトしてみる。

```ruby
# depends_on macos: '>= :lion'
```

```bash
brew cask list
...
```

動くようになった！
動いたので問題だったアプリを`uninstall`。

```bash
brew cask uninstall google-photos-backup
```

動くようになった。
楽天RSSから日経平均採用225社の株価をPythonで取得しDataFrame化（約20秒）

#概要

- 手順１: 事前準備：（225社分の株式コードを用意する）
- 手順２:楽天RSSを利用し、225社の始値を取得 (約２０秒）


##手順１: 事前準備：

CSVファイルから日経２２５社のコードを取得しておく
[参考](https://qiita.com/zaq9/items/13562a5b78e4822801bc)

```python

import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/zaq9/nk225_list/master/nk225_list.csv')

```

##手順２:楽天RSSを利用し、225社の始値を取得 (約２０秒）
モジュール「rakuten_rss」を利用する
#####参考
[楽天RSSから株価情報取得するPythonモジュールのα版を作成しPyPIに登録してみた](https://qiita.com/zaq9/items/8cbcb04e6f9480077cc0)

```python

from rakuten_rss import fetch_open
df['open'] = df.code.apply(lambda x: fetch_open(x))

```

以上。
楽天RSSから株価情報取得するPythonモジュール α版を作成＆PyPIへの登録

#概要:
楽天RSSから株価情報等を取得するPython用のモジュール（rakuten_rss) を作成
([PyPI](https://pypi.org/project/rakuten-rss/)からインストール可能な状態）

[利用例：github上のjupyter notebook](https://github.com/zaq9/rakuten_rss/blob/master/docs/test_rakten_rss.ipynb)

- 楽天RSSの起動が必要（Windows専用？）　⇒　[RSS起動は赤いアイコンから](https://www.rakuten-sec.co.jp/MarketSpeed/onLineHelp/msman1_11_3.html)
- 日経平均採用の225社の全株価取得時間は約20秒前後: [参考](https://qiita.com/zaq9/items/cdbefd7ef4e62b4488af)）
- 現状、DDE通信の情報がうまく集められず、強引に[PYDDE](https://github.com/indranilsinharoy/PyZDDE)という光学機器用らしき？モジュール（MITライセンス）から、一部ソースコード拝借して、とりあえず動いている状態。ちゃんとしたモジュール情報お持ちの方、またはソースコード改善できる方等がいらっしゃいましたら、教えていただけると大変嬉しいです。
 

![rss.JPG](https://qiita-image-store.s3.amazonaws.com/0/351020/263ae936-74e1-f4db-eb03-5520411ede5d.jpeg)


##楽天RSSとは…：
楽天RSSとは、楽天マーケットスピード付属のソフトウェアです。今回作成したモジュールは、マーケットスピード内の投資情報ページ「市況情報（先物OP市況情報）」に表示される値を日頃より使い慣れた？Python上に値を取り込むことで、自在に編集が可能となります。

[参考：楽天公式のExcel版説明](https://www.rakuten-sec.co.jp/MarketSpeed/onLineHelp/msman1_11_1.html)
-----------------


##インストール方法:

```python

pip install rakuten_rss

```

##Usage(使い方概要):


###使える関数１：rss(code, item): 
Excel のRSS関数と互換する形式の関数(楽天RSSから情報を取得)

```python


from rakuten_rss import rss,rss_dict,fetch_open

rss('9501.T' , '始値')
#output'668.00'

rss('9501.T' , '現在値')
#output:'669.00'

rss('9501.T' , '銘柄名称')
#output:'東京電力ＨＤ'

"""

	item : 
"""
```

使えるパラメータは
現在値,銘柄、売り＆買い気配値等の板情報、各種会社情報等100項目以上。
詳細は楽天公式ページの情報を読み替えてください。

[使えるパラメータ一覧（楽天）](https://www.rakuten-sec.co.jp/MarketSpeed/onLineHelp/msman1_11_6a.html)


###使える関数２：rss_dict(code, *args):
　楽天RSSからPython辞書形式で情報を取り出す(複数の詳細情報問い合わせ可）


```python

rss_dict('9502.T', '始値','銘柄名称','現在値')

#output:
#{'始値': '1739.50', '現在値': '1661.50', '銘柄名称': '中部電力'}

```

###使える関数３：fetch_open(code):
 始値を返す（SQ算出時用:入力int）

```python

fetch_open(9551)
#output: 50050 (ファーストリテイの株価）

```
いつか使いたかった ESP-WROOM-02

年明ける前から触りたくて買ってましたが，ずっとさわれずに積んでいました．
今回は，年末年始の休暇などに合わせて実際に使ったみた備忘録です．

今回は秋月電子でT型のを購入したため，それに合わせた内容です．

## 回路の作成
[こばさんの wakwak 山歩き: ESP8266（ESP-WROOM-02）　直ちに LED と タクトスイッチ 装着](http://d.hatena.ne.jp/wakwak_koba/20150928) にある回路図を参考に回路を作成します．
この記事の回路であれば，書き込みやリスタートはタクトスイッチで制御できて大変便利です！
ちなみに，記事の終わりの方には大変変態チックな繋ぎ方が出ていますが，私は試していませんので誰か報告お待ちしています．

なお，ふとタクトスイッチの取り付け向きを思い出せずに不安になり，[いなぎ電子キット: タクトスイッチの向きについて](https://inagidenshi.shop-pro.jp/?mode=f5) を参考にしました．

## Arduino IDEのセットアップ
まずは，FT231Xのドライバのインストールから行います．
[Qiita: Mac で ESPr Developer: ESP-WROOM-02開発キットのシリアルポートが表示されないとき](https://qiita.com/sutchan/items/7d4b4f06777127be26f5) を参考にしました．

次に Arduino IDE のインストール．
Arduino IDE のインストールは以下のコマンドでできます（要 brew）．

```bash
$ brew cask install arduino
```

Arduino IDE のセットアップの手順は [haibara's workshop: ESP-WROOM-02を導入する](https://haibara-works.hatenablog.com/entry/2018/12/09/232941) の手順を参考にセットアップしました．

## L チカ
とりあえず，電子工作の基本，L チカです．
やり方は [Qiita: ESP-WROOM-02/ESP8266 LEDチカチカ](https://qiita.com/engksk/items/16f1ac61eedcbb4dfaa8) を参考に LED には抵抗を追加して実装しました．
抵抗はいわゆる電流制限抵抗です．オームの法則 ($V = RI$) より，抵抗の値を求めましょう．$V$ は電位差（電圧，ボルト[V]），$R$ は比例定数 (抵抗の値，オーム[Ω])，$I$ は電流 (アンペア[A]) です．
このマイコンでちょっとした Web サーバとして動かしてこんなことができるとは感動です．

## 参考
* [Qiita: Qiitaやブログのタイトルは自分で考える必要なんてなかったんだ](https://qiita.com/YumaInaura/items/0d8427bfe2d7be476d0d)
    * 流行りに乗っかり（もしかしてもう過ぎた？）使ってみました．
* [こばさんの wakwak 山歩き: ESP8266（ESP-WROOM-02）　直ちに LED と タクトスイッチ 装着](http://d.hatena.ne.jp/wakwak_koba/20150928)
* [いなぎ電子キット: タクトスイッチの向きについて](https://inagidenshi.shop-pro.jp/?mode=f5)
* [haibara's workshop: ESP-WROOM-02を導入する](https://haibara-works.hatenablog.com/entry/2018/12/09/232941)
* [Wikipedia: オームの法則](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%A0%E3%81%AE%E6%B3%95%E5%89%87)

---

## 一度は読んでおくと良い記事
* [こじ研: ESP-WROOM-02 を使った「トンペイーノ」の製作](https://www.ei.tohoku.ac.jp/xkozima/lab/espTutorial0.html)
    * 「プログラミング上の注意」が大変参考になる

## 今後参考になりそうな記事
* [mgo-tec電子工作: ESP8266, ESP-WROOM-02, ESPr Developer トラブルシューティングまとめ](https://www.mgo-tec.com/blog-entry-esp8266-wroom-02-espr-developer-trouble-shooting.html)
    * トラブルが発生したらお世話になることでしょう
* [B’Micom: WROOM-02を最新ファームV1.5.4に更新してみる](http://bmicom.dmsk.com/wroom-02/firmware-update)
    * ファームウェアの更新方法について記述あり
* [Qiita: ESP-WROOM-02で複数ある中から接続可能なAPに接続する](https://qiita.com/Kaz_Macintosh/items/72ab17e46a9b2912b8d6)
    * 対応方法としてはシンプルだが，見落としがちなのでメモ
* [なんでも独り言: ArduinoOTAでプログラムの無線書き込み（ESP8266）](https://ehbtj.com/electronics/esp8266-arduino-ota-wireless-programming/)
    * ESP8266 はプログラムを無線で書き込みできる機能（OTA:On The Air）があるらしい
* [Qiita: ESP8266 (ESP-WROOM-02) で消費電力を抑えるには (スリープモードまとめ)](https://qiita.com/exabugs/items/9edf9e2ba8f69800e4c5#modem-sleep--light-sleep)
    * Sleep 機能も使うつもりなのでメモ
【Rails】ER図作成

# RailsでER図を作成する便利なライブラリのインストールと使い方

## 必要な各ライブラリをインストール

- rails-erd 【gem】
- graphviz

必要なのはこの２つ
※ homebrewが必要なので事前にインストール

### rails-erdのインストール
Gemfileに追記

```ruby:Gemfile
group :development do
...
  gem "rails-erd" # 追加
...
end
```

できたら下記コマンドでインストール

```
$ bundle install
```

### graphvizのインストール

```
$ brew install graphviz
```

これで必要なライブラリのインストールは終わり

## ER図出力

下記コマンドを使用するとカレントディレクトリにerd.dotファイルが生成される

```
$ bundle exec erd --inheritance --direct --attributes=foreign_keys,content --filetype=dot
```

### dotファイルを閲覧できる形式に変換

- pngに変換

```
$ dot -Tpng erd.dot -o erd.png
```

- pdfに変換

```
$ dot -Tpdf erd.dot -o erd.pdf
```
VueLoaderPluginのせいでエラーが起きていると言われたら確認したいこと

## 概要
土曜日なので、vueはじめました。
はじめてのwebpackに戸惑いながらもSPAに挑戦しています。

しかし、さっそくのビルドエラーに遭遇してしまいました。
なにやら`vue-loader`が悪さをしているようです。

```
ERROR in ./src/pages/About.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
```

今回はわたしが解決した方法をご紹介します。


### 原因
https://vue-loader.vuejs.org/migrating.html
どうやら`vue-loader`には最近著しい変更があり、v15からプラグインとして読み込んであげてねってことになったようです。

ちなみに、自分の環境だとバージョンは`"vue-loader": "^15.6.2",`。
まさにこれでした。

### 解決方法
https://vue-loader.vuejs.org/migrating.html
以下のようにconstで定義して、module.exportsのなかのpluginsにぽこっとnewしてあげればいいようです。

```js

// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  // ...
  plugins: [
    new VueLoaderPlugin()
  ]
}
```

私はこれで無事に解決できました。
もし、同じエラーが出た場合はお試しくださいね！

#### おまけ
次はcss-loaderを解決しなくては..汗
今までgulp一本な人生だったので、webpackは不思議な感覚です。(かといって、gulpをそんなに高い頻度で使っているわけでもないw)
bitnami redmine の心がけ

1. とにかく楽をしろ
2. 余計なプラグインは入れるなアップデート時に苦労するぞ
3. ポート番号は変更しておけ
4. オプションファイルを使え


え？オプションファイル？


```
$ cat optionfile.ini
 disable-components=subversion,phpmyadmin
 installer-language=en
 prefix=/opt/redmine
 base_user_name=admin
 base_mail=user@example.com
 base_user=admin
 base_password=adminpass
 apache_server_port=8081
 apache_server_ssl_port=10443
 mysql_port=13308
 redmine_language=en
$ ./bitnami-redmine-4.0.1-1-linux-x64-installer.run --mode unattended  --optionfile optionfile.ini

```

便利じゃないですか。一発でいけますわ。
loadしたhtmlにjsを適用させる

#loadしたhtmlにjsを適用させる
##前提：フォルダ階層
```text:階層
┣ static
┃ ┣ css
┃ ┃ ┗ menu.css
┃ ┣ js
┃ ┃ ┣common.js
┃ ┃ ┗menu.js
┃ ┣ html
┃ ┃ ┗ menu.html
┗ templates
  ┗ main.html

```
##やりたかったこと
###機能
現在いるページと対応するメニューの色を変更させたい。
###コード
htmlで複数ページを作る時に、メニューのところのhtmlが長いのでmenu.htmlとして外部ファイルを作った。
それをcommon.jsで読み込み、main.htmlにmenu.htmlを適用させた。
更に今いるページと対応するメニューの色を変更するために
特定のタグをactiveにする処理を書いたmenu.jsをmenu.htmlに適応させたい。

```html:main.html
<body>
	<div id="menu"></div>

	<!--jQueryの読み込みとか-->
	<script type="text/javascript"
		src="/webjars/jquery/3.3.1/jquery.min.js" charset="utf-8">	
	</script>
	<!--javaScriptの読み込み-->
	<script type="text/javascript" src="/js/common.js"></script>
	<script type="text/javascript" src="/js/menu.js"></script>
</body>
```

```html:menu.html
<ul id="nav"> 
   <li><a href="/menu1">MENU1</a></li> 
   <li><a href="/menu2">MENU2</a></li> 
   <li><a href="/menu3">MENU3</a></li> 
   <li><a href="/menu4">MENU4</a></li> 
 </ul> 
```

```javascript:common.js
$(window).on('load', function() {
      //main.htmlのmenu要素についてmenu.htmlを適用させる
	$("#menu").load('/html/menu.html');
});
```

```javascript:menu.js
//現在のページのurlとメニューのurlが同じだったら、そこのタグをactiveにする
$(function() {
	$('#nav li a').each(function() {
		var $href = $(this).attr('href');
		if (location.href.match($href)) {
			$(this).addClass('active');
		} else {
			$(this).removeClass('active');
		}
	});
});
```

```css:menu.css
/*activeになってる要素navの[li a]タグの文字を赤にする*/
#nav li a.active {
	color: red;
}
```

##問題1
menu.jsはちゃんと読み込まれているっぽいけど、activeにならない。
コンソール上のエラーは発生してないが、なんかうまく適用されていない気がする
##実際にやってみたこと
menu.html上で直接jsを呼んでみる

```html:menu.html
<!--変更したところ↓-->
<script type="text/javascript" src="/js/menu.js"></script>
<!--変更したところ↑-->
<ul id="nav"> 
   <li><a href="/menu1">MENU1</a></li> 
   <li><a href="/menu2">MENU2</a></li> 
   <li><a href="/menu3">MENU3</a></li> 
   <li><a href="/menu4">MENU4</a></li> 
 </ul> 
```

##問題2
とりあえず、jsは読み込まれて適用された。が、
コンソールに以下のエラー

```text:error
[[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
```
よくわらかないけどエラーが出るってことはダメな気がする。気持ち悪いし
あと、ググったらエンドユーザーに影響がどうのって書いてたらかダメなんだと思う

##解決方法
menu.htmlをロードする時に一緒にjsもロードしてあげる！

```javascript:common.js
$(window).on('load', function() {
      //main.htmlのmenu要素についてmenu.htmlを適用させる
	$("#menu").load('/html/menu.html');
 	//変更したところ↓
 	$.getScript("/js/menu.js", function() {
	});
 	//変更したところ↑
});
```

これでエラーなくちゃんとactiveにすることができた

##参考にしたサイト
http://mugen00.moo.jp/web/jquery/getscript-2
herokuでOpenCVを利用する [Python3]

# はじめに
requirement.txtにopencv-pythonを加えて, デプロイすると以下のようなlogが…

```terminal
2019-02-01T09:13:56.472857+00:00 app[web.1]: import cv2
2019-02-01T09:13:56.472859+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/cv2/__init__.py", line 3, in <module>
2019-02-01T09:13:56.472861+00:00 app[web.1]: from .cv2 import *
2019-02-01T09:13:56.472874+00:00 app[web.1]: ImportError: libSM.so.6: cannot open shared object file: No such file or directory
```

入らない…

# 結論
libSM.so.6がないようなので, 入れるために以下の手順を踏んでいきます.
1. buildpacksにhttps://github.com/heroku/heroku-buildpack-apt を追加
2. Aptfileをプロジェクトフォルダに追加

以下に詳細を書いていきます.

## 1. buildpacksへ追記
自分の知る限り, 以下の二つの方法のどちらでも追加できます.
### Herokuのページから追加する
Herokuのページのsettings>buildpacksで https://github.com/heroku/heroku-buildpack-apt を追加する. 

### terminalから追加する
以下のコマンドをたたきます.

```terminal
$ heroku buildpacks:add --index 1 https://github.com/heroku/heroku-buildpack-apt
```

## 2. Aptfileをプロジェクトフォルダに追加
requirements.txtやProcfileなどがある階層に以下のAptfileを追加します.

```Aptfile:Aptfile
libsm6
libxrender1
libfontconfig1
libice6
```

以上です!
Azure Automation 作成時の注意点

# はじめに
Azure Automation を使ったデモの準備をした際に、ちょっとはまりましたので
メモとして残しておきます。

# Azure Automation とは
プロセス自動化および構成管理などを提供してくれるサービスです。
日々の運用作業を自動化することができます。
ただし、自動化するには自動化したい作業を PowerShell なり、スクリプト化しないといけません。
一応グラフィカルに設定できる GUI もあるようですが、どうなんでしょうか。
使ったことないので未知数です。。
詳しいことは以下のドキュメントを参照ください。

https://docs.microsoft.com/ja-jp/azure/automation/automation-intro

# ハマった点
Runbook 実行時に Azure への認証がうまくいきませんでした。
原因は、Azure Automation アカウント作成時に、Azure 実行アカウント (サービスプリンシパル) を作成していなかったためでした...
Azure Automation を利用するには、専用のサービスプリンシパルが必要のようです。
Azure Automation アカウント作成時に忠告してくれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/224712/64e10d9a-355b-7180-fac9-d19ab4d01398.png)

サービスプリンシパルは、所有者相当の権限がないとサービスプリンシパルは作れませんので注意が必要です。

ちゃんと警告メッセージは読みましょう！
Railsチュートリアルのherokuにデプロイ(git push heroku master)でremote rejectedってなった時

# Railsチュートリアルの1.5.2章
https://railstutorial.jp/chapters/beginning?version=5.1#sec-heroku_step_one

# エラーメッセージ
```
❯ git push heroku master
Enumerating objects: 94, done.
Counting objects: 100% (94/94), done.
Delta compression using up to 4 threads.
Compressing objects: 100% (77/77), done.
Writing objects: 100% (94/94), 20.94 KiB | 765.00 KiB/s, done.
Total 94 (delta 6), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote:  !     Warning: Multiple default buildpacks reported the ability to handle this app. The first buildpack in the list below will be used.
remote:                         Detected buildpacks: Ruby,Node.js
remote:                         See https://devcenter.heroku.com/articles/buildpacks#buildpack-detect-order
remote: -----> Ruby app detected
remote:
remote:  !
remote:  !     You must use Bundler 2 or greater with this lockfile.
remote:  !

〜〜〜〜　省略　〜〜〜〜

 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/アプリ名.git'
```

# 解決方法
```
❯ bundle version
Bundler version 2.0.1 (2019-01-04 commit d7ad2192f)

❯ gem uninstall bundler -v 2.0.1
Successfully uninstalled bundler-2.0.1

❯ rm -f Gemfile.lock

❯ bundle install

❯ git add Gemfile.lock

❯ git add commit

❯ git push

❯ git push heroku master  # 成功
```
Django内でのパスの指定

# はじめに
Djangoのファイル内でファイルを利用したいとき

```python
cv2.imread('相対パス')
```
みたいな感じで相対パスで指定したところ, herokuにデプロイした時にエラーが出てしまいました.
だけど絶対パスで指定するのもよくわからなかったので, 調べてみました.

# 結論
settings.pyから`BASE_DIR`をimport, プロジェクトフォルダからの位置を記す.

例えば以下のようなディレクトリ構成の時, 

```python
project
  ├app1
  ├app2
  ├project
  │  ├settings.py
  │  ├urls.py
  │  ︙
  │
  └data
    └img.png
```

```python
from [プロジェクト名].settings import BASE_DIR
︙
cv2.imread('BASE_DIR' + /data/img.png)
```
のように参照することができる.

# BASE_DIRの設定
デフォルトではsettings.py内で以下のように定義されているはずです.

```python
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
```
ようはsettings.pyの2個上のディレクトリ, つまり一番上のプロジェクトディレクトリがBASE_DIRとして設定されています.
Djangoで同一名のパラメータをリストで取得する方法

単純なのに少し詰まったのでメモ。

リクエストパラメータに同一名のものが複数あるとき、

```
http://fclef.jp/?id=1&id=2&id=3
```
こう書いて

```python
ids = request.GET['id']
```
こうなった。

```python
print(ids)
>>> '3'
```
思ってたんと違う。
恒例の書き方だと最後の要素しか取得しない。

全ての要素をリストで取得したいときはこう書く。

```python
ids = request.GET.getlist('id')
print(ids)
>>>['1','2','3']
```
API GatewayからDynamoDBの読み書きを行う

#はじめに
AWSのAPI Gatewayから前回作ったLambda関数を起動することによりDynamoDBを読み書きする方法です。Lambdaでは書き込み専用、読み込み専用として別々の関数を作りましたが、今回は一つのAPI Gateway中にGET機能とPOST機能を持たせます。

・ API Gatewayの管理画面にアクセスします。
・ RESTプロトコルを選択します。
・ 適当なAPI名をつけます。
・ エンドポイントタイプはリージョンを選択します。
・ APIの作成を押すとメソッド画面が開きます。

#GETコマンドの設定
・ アクションからリソースの作成を選択します。
・ リソース名に[comments]と入力しリソースの作成を押します。
・ アクションからメソッドの作成を選びます。
・ GETを選んでチェックマークを押します。
・ GETセットアップにて、統合タイプはLambda関数、関数名には読み込み用のLambda関数名を入力して保存します。
・「 API GatewayにLambda関数を呼び出す権限を与えようとしています」のメッセージが出るのでOKを押します。
・ メソッドのリクエストをクリックします。
・ URLクエリ文字列パラメーターを開きます。
・ クエリ文字列の追加をクリックし名前にDBのプライマリーキーである[track]と入力してチェックマークを押します。（全データを呼び出すことになる）
・ メソッドの実行をクリックして前の画面に戻ります。
・ 統合リクエストをクリックします。
・ マッピングテンプレートを選択して開きます。
・ テンプレートが定義されていない場合（推奨）を選んでマッピングプレートの追加をクリックします。
・ [Context-Type]に[application/json]と入力し、右のチェックを押します。
・ [application/json]をクリックし以下をコピーし保存します。

```json
#set($inputRoot = $input.path('$'))
{
  "track": "$input.params('track')"
}
```

・ メソッドの実行をクリックして前の画面に戻リます。
・ これでGET時にLambda関数を介してDynamoDBへQueryを実行できるようになります。
・ テストを押します。
・ クエリ文字列に[track=Test]と入力してテストボタンを押します。
・ 画面右側にDynamoDBの値が出力されれば成功です。
・ メソッドの実行をクリックして前の画面に戻ります。

#POSTコマンドの設定
・ アクションからメソッドの作成を選びます。
・ POSTを選び右側のチェックを押します。
・ POSTセットアップにて、統合タイプはLambda関数、関数名には読み込み用のLambda関数名を入力して保存します。
・ 「API GatewayにLambda関数を呼び出す権限を与えようとしています」のメッセージが出るのでOKを押します。
・ 統合リクエストをクリックします。
・ マッピングテンプレートを選択して開きます。
・　テンプレートが定義されていない場合（推奨）を選んでマッピングプレートの追加をクリックします。
・　[Context-Type]に[application/json]と入力し、右のチェックを押します。
・　[application/json]をクリックし以下をコピーし保存します。

```json
$input.json('$’)
```

・　メソッドの実行をクリックして前の画面に戻ります。
・　テストを押します。
・　リクエスト本文に以下を記入します。

```json
{
    "track": "Test",
    "comment": "Hello API GW",
    "name": "zzzz"
}
```

・　テストを押します。
・　レスポンスに{}と表示されれば成功です。
・　DynamoDBの管理画面でデータが追加されていることを確認します。

以上でREST APIが完成です。

#デプロイとテスト
・　アクションからAPIのデプロイを選択します。
・　デプロイされるステージで新しいステージを選び、ステージ名に[demo]と入力しDeployボタンを押します。
・　画面にURLが表示されるのでコピーします。
・　ブラウザのアドレスバーにペーストし、最後に[/comments?track=Test]を追記します。
・　GETの結果としてQuery結果が表示されます。POSTについては手作業でのテストは行えません。POSTMAN（www.getpostman.com）などでテストを行う必要があります。
ターミナルやREPLからCLHSを参照する

タイトルのまんまです．Common Lispで何かしら書いている人は[CLHS](http://www.lispworks.com/documentation/HyperSpec/Front/Help.htm)を頻繁に見ていることと思います．
Common Lispの有名なライブラリ群を多数開発している深町さんが書かれた[CLHSをターミナルから一発でブラウザで開くスクリプト](https://gist.github.com/fukamachi/3510ea1609c1b52830c2)があって，これが大変便利なのですがブラウザで見なきゃいけないのがやはり煩わしく感じます．このあたりは完全に好みだと思いますが，w3mみたいな端末で動くテキストブラウザも馴染みがなくて使いづらい、みたいな人にだけピンポイントで刺さる内容かと思います．
深町さんのスクリプトを参考にしつつ書いた雑な実装を[github](https://github.com/koji-kojiro/hyperspec)にあげているので興味があれば見てみてください．以下使い方です．

## インストール
roswellでどうぞ．

```
$ ros install koji-kojiro/hyperspec
```

## REPLから使う

```
* (ql:quickload :hyperspec)
* (hs:show 'format)
···
```

## 端末から使う


```
$ clhs format | more
```

以下のような感じで見れます．

![more.png](https://qiita-image-store.s3.amazonaws.com/0/153686/1e641ca0-125b-c832-85c8-0a989cc9669e.png)

単に対応するCLHSのページからテキスト部分だけを抜き出して適当に色を付けて表示しているだけです．もちろんリンク等は動かないので例えば`string`とかを渡したときは悲しい感じになるのでしっかり調べたいときはブラウザで見るのを推奨します．読んでいただきありがとうございました．
アクセス解析タグ実装時、HTMLソース内からパラメータ情報を取得する（CSSセレクタがダメだった場合）

#お困りごと
**アクセス解析のタグを実装する際、解析エンジニア泣かせのこんな経験はないですか？**
> ページ遷移するとURLから必要なパラメータが欠落してしまい、GAの目標到達プロセスが設定できない:relaxed::relaxed:

本来このような場合は、お客さん・ディレクター・フロントエンジニアと調整を図り、ページのソースを変更することが理想です。
ただ、大抵の場合はサイトローンチ後でもうニッチもサッチも変更できないのがよくあるパターンと思います。（特にCMSからページを生成している場合）

そういうときは、解析エンジニアが唯一イジイジできるアクセス解析ツールたちを駆使して状況を打破しましょう！

注：<a href=https://www.ja.advertisercommunity.com/t5/%E3%83%88%E3%83%A9%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%AE%9F%E8%A3%85/form%E9%80%81%E4%BF%A1%E6%99%82%E3%81%ABhidden%E3%81%AE%E5%80%A4%E3%82%92%E3%82%BF%E3%82%B0%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%BC%E3%81%A7%E5%A4%89%E6%95%B0%E3%81%A8%E3%81%97%E3%81%A6%E5%8F%96%E5%BE%97%E3%81%97%E3%81%9F%E3%81%84/td-p/94874>CSSセレクタでパラメータを取得する方法</a>の方が簡単ですが、それすらも困難なケースに当記事をお役立てください

#当記事で解決可能な環境（条件面）
1. 取得したいパラメータがHTMLソース内にsetされていること
2. Google Tag Manager(GTM)タグが実装されており、公開権限、少なくとも編集権限が付与されていること
3. Google Analytics(GA)タグがGTM内に実装されており、GAの編集権限が付与されていること

2と3の権限について、自身でタグ実装時の切り分け不可なロールであった場合、パワポとかに仕様を落として編集権限のあるレイヤーの人にやってもらいましょう。

#必要な道具たち
- ブラウザ：Chrome
- 拡張機能：<a href=https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl>XPath Helper</a>
- XPathチートシート：<a href=http://takuya-1st.hatenablog.jp/entry/2015/07/30/004448>Xpathまとめコマンドとその使用例</a>

#XPathとは
> XML Path Language （XPath（エックスパス）） はXML文書中から必要な要素群（サブセット）を取り出す、などといった用途に使うもの。－ Wikipedia

要は、HTMLのソース構造から必要な情報を抜き出す言語です。厳密には違いますが、HTML版SQLのようなもの。

#実装までの大きな流れ
1. 取得したいパラメータ情報がHTMLソース内に記載されていることを確認する
2. 1をXPathで表現（=記述）する
3. GTM変数画面のカスタムJavaScriptに記述する
4. カスタム変数としてGTMタグに設定する

#実装方法
##1. 取得したいパラメータ情報がHTMLソース内に記載されていることを確認する
Chrome利用想定ですが、ページにパラメータ情報が表示されている/表示されていないによって方法が異なります。

- 表示されている：表示されているパラメータを右クリック→「検証」
- 表示されていない：F12キー押下→「Elements」画面から探す

##2. 1をXPathで表現（=記述）する
上記1のパラメータ情報の状態によって、以下2つのXPath記述方法があります。
1つ目は簡単だけど記述的に汚くなりがち、2つ目はきれい＆応用がきくけどやや難易度高めです。

1. Chromeディベロッパーツールから
右クリック→「Copy」→「Copy XPath」
※かゆいとこに手が届かないのであまりおすすめしません

2. XPathのお作法を調べて記述する
上述した「必要な道具たち」のチートシートをもとに、XPathを自作します。
（拡張機能を使うと検証が捗ります。）

##3. GTM変数画面のカスタムJavaScriptに記述する
GTMのカスタムJavaScript画面で、GAへ渡す変数を作成します。
自分は<a href=https://developer.mozilla.org/ja/docs/Introduction_to_using_XPath_in_JavaScript>mozillaのリファレンス</a>を参考にしました。

```ページURLの整形.js
function(){
  // ドメイン名を取得
  var getDomain = document.location.origin;
  // XPathでHTML内からパラメータ情報を取得
  var getXpath = document.evaluate([ここに上記2で調べたXPathを記述], document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
  // URLにパラメータを付加
  var concatURL = location.href.replace(getDomain + '/', '');
  var concatURL = concatURL + getXpath.singleNodeValue.nodeValue;
  
  return concatURL;
}
```
注：GTMへ実装する前に、ChromeディベロッパーツールのConsole画面で、コードを実行&期待値が出力されることを検証してください

##4. カスタム変数としてGTMタグに設定する
3の変数をGAへURLとして送信すべく、以下のようにGTMタグを設定します。
![GTMタグ.png](https://qiita-image-store.s3.amazonaws.com/0/172589/956e2c36-5fd2-34d1-5f83-7d6291038c8b.png)

#終わりに
GTMはいじり倒す領域もままあるためエンジニアリング的にも面白いですし、色々なデータが取得できるので分析観点からも有用と思います。
ただ、冒頭でも書いたように、ページを作るときに解析サイドの観点をもう少し反映してくれればこのようなちょっとムリ目なデータ取得はしなくてもよくなるわけで、前工程の現場の方々ともっとコミュニケーションが取れるようになれればいいなと願っています。
只今勉強中！機械学習用ライブラリ KerasのK

# Keras モデルの実装
モデルの実装には手軽に実装できるSequentialクラスとコード量は少し増えるがより自由度が高い実装ができるFunctional APIの2つのタイプがある

### SeqentialクラスとFunctional API

#### Sequentialクラスを使った実装例
```python:keras.py
from keras import models
from keras import layers

model = models.Sequential()
model.add(layers.Dense(32, activation='relu', imput_shape=(784,)))
model.add(layers.Dense(10, activation=''softmax))
```

#### Functional APIを使った実装例
```python:keras.py
from keras import models
from keras import layers

# 入力値を定義
input_tensor = layers.Input(shape=(784,))
# レイヤー1 の引数に入力値を渡す、出力値としてxが返却
X = layers.Dense(32, activation='relu')(input_tensor)
# レイヤー2 の引数にxを渡す、出力値としてoutput_tensorが返却
output_tensor = layers.Dense(10, activation='softmax')(x)
# モデルへ入力値と出力層を渡す
model = models.Model(inputs=input_tensor, outputs=output_tensor)
```
RのCSVでエラー

# 事象
DBからデータをCSVに変換したものをもらい、分析をしようとRにてそのまま取り込もうとしたら以下のエラーになった。
1. 「invalid input found on input connection」の警告
2. 「列名よりも列数のほうが多いです」のエラー
3. 取り込めたと思ったら日時のデータがおかしくなっていた

# 前提データ
説明のため簡単なデータとする。

```sample.csv
ID,name,Date,memo,etc
1,田中太郎,2019-1-1 00:00:00.000,hogehogehoge,特になし
2,田中次郎,2019-1-1 00:00:00.000,めもめもめも。,etc
3,田中サブロー,2019-1-1 00:00:00.000,備考1,000,000円使った,その他
4,田中 和江,2019-1-1 00:00:00.000,,ect
5,田中:花子,2019-1-1 00:00:00.000,めもも、もももめものうち,めも
```
※UTF-8のBOM付
また、データを変換する際にはExcel2016を使用

## 1.invalid input found on input connection
setwd()でデータのあるディレクトリに移動し、取り込もうと以下のコードを実行したら「invalid input found on input connection」と警告が出てうまく取り込めず

```
df<-read.csv("sample.csv", fileEncoding = "UTF-8")
```

調べてみると以下の記事にたどり着いた
https://qiita.com/gigamori/items/0152639dc0a68a400525
BOM付の場合は以下のようにしなければならないらしい。

```
df<-read.csv("sample.csv", fileEncoding = "UTF-8-BOM")
```

## 2.「列名よりも列数のほうが多いです」のエラー
BOM付の設定をして警告が消えてうまくいったと思ったら、「列名よりも列数のほうが多いです」のエラーが出た。

実際に使ったデータは、データが多かったので表面的なところしか見ていなかったので後で気づかなかったが、備考やメモのようなカラムのデータにカンマがあるデータがあって邪魔をしていたみたいだったのでエクセルにて一気に変換をかけ保存した。
その後、read.csvをかけたらデータ取り込みに成功！

前提のsample.csvでは

```
3,田中サブロー,2019-1-1 00:00:00.000,備考1,000,000円使った,その他
```
の1,000,000円のところ。これを1000000円とした。

よくわからないのだが実際のデータはエクセルで見たときは列のずれもなくわかりにくかった。
当たり前だが、一応カンマ以外にもスペースやコロンなどを疑ったが、いろいろ試した結果カンマによる影響のみ。

## 3.取り込めたと思ったら日時のデータがおかしくなっていた
取り込めたと思ったら、日時のデータがyyyy-mm-ddの部分が消えて「00:00.0」になっていた...
エクセルにてそのまま変換するとダメらしい。
いろいろ試した結果、カンマなどの処理をしてエクセルに保存する前に、
1. 日時データの列を全体を選択
2. 上のホームタブにて書式を短い日付に変更
3. Ctrl＋１で書式の設定を出して、日付の「yyyy-mm-dd」を選択
をして保存。
そのデータを取り込んでみたらやっとうまくいった。

# 感想
- 初めてデータ分析というものを仕事でしたが、取り込むだけで大変だとは思わなかった
- できることなら変換などに、エクセルは使わないようにしたほうがいいと思った
- 諸事情あり今回は自分でCSVをいじったが、本来ならデータを出力する際に必要に応じてエンコードすべきだと思った。
- Qiita初投稿。記事を書くことがこんなに大変だとは…いつも参考にしてもらっている記事を書いている人に感謝。
Google Cloud Functions Emulatorの備忘録

最近Firebaseでcloud functionsを使用することが多く、Cloud Functions Emulatorで試す際に毎回つまってたのでその備忘録

### インストール
**npm**
`npm install -g @google-cloud/functions-emulator`
**yarn**
`yarn global add @google-cloud/functions-emulator`

インストールができれば`functions`コマンドが使用できるようになるのですがzshの方は競合してしまうので`functions-emulator`に置き換えてください。

**エミュレータの起動**
`functions start`
※起動のエラーで毎回つまる。。

```
ERROR: Error: Emulator crashed! Check the log file...
    at ChildProcess.child.on (/Users/kohei/.npm-global/lib/node_modules/@google-cloud/functions-emulator/src/cli/controller.js:650:24)
    at ChildProcess.emit (events.js:182:13)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:240:12)
```

こちらパーミッションの問題なのでsudoつけて解決

```
sudo functions start
```

**関数**
`index.ts`に関数追加

```index.ts
exports.hoge = functions.https.onRequest((request, response) => {
     console.log("hogehoge"))
     response.status(200).end()
})
```

**ビルド**
`npm run build`

**関数のデプロイ**

`functions deploy デプロイする関数 --trigger-http`

デプロイするとアクセスURLが貼られるのでアクセスして確認

**ログ確認**
`functions logs read`

**エミュレータの停止**
`functions stop`
【Java初心者】 多次元配列の初期化について


java Silverの取得に向けて学習をしていたところ、
多次元配列の初期化の箇所で詰まってしまったのでメモとして残しておきます。

###何が分からなかったか


```
String[][] array = {{"a","b"},{"c","d","e"},{"f","g","h","i"}};
```
配列宣言時に`[][]`と書いているのに`{}{}{}`と括弧の数が対応していないことで混乱し、
何故この配列のコンパイルが通るのかが理解ができなかった...

###どう読み取ればよいか

単純な話でした。

```
String[][] array = {{"array[0][]"},{"array[1][]"},{"array[2][0]"}};
```
3つの{}は1次元目の配列の添え字部分に対応しており、
{}内で記述しているa~iの値は1次元目の配列が参照している2次元目の配列の値であるということでした。

```
public class Main{
	public static void main(String[] args) {
		String array[][] = {{"a","b"},{"c","d","e"},{"f","g","h","i"}};
		System.out.println(array[0][0]); //a
		System.out.println(array[0][1]); //b
		System.out.println(array[1][0]); //c
		System.out.println(array[1][1]); //d
		System.out.println(array[1][2]); //e
		System.out.println(array[2][0]); //f
		System.out.println(array[2][1]); //g
		System.out.println(array[2][2]); //h
		}
	}
```
実際に各要素をprintlnメソッドで出力してみると、期待した通りの結果が返ってきました。


ちなみに実際に配列の各要素を出力する際は、

```
public class Main {
	public static void main(String[] args) {
		String array[][] = { { "a", "b" }, { "c", "d", "e" }, { "f", "g", "h", "i" } };
		for(String[] tmp : array) {
			for(String s : tmp) {
				System.out.println(s);
			}
		}
	}
}
```
このようにfor文を用いて配列を回す方法の方が一般的。


3次元目以降についても可読性めちゃ悪いですが、ネストさせて下記のように各要素を出力することが可能です。

```
public class Main {
	public static void main(String[] args) {
		String array[][][] = { { { "a", "b" }, { "c", "d", "e" } }, { { "f", "g", "h", "i" }, { "j", "k", "l", "m" } },
				{ { "n", "o", "p" }, { "q" } } };
		for (String[][] s1 : array) {
			for (String[] s2 : s1) {
				for (String s3 : s2) {
					System.out.println(s3);
				}
			}
		}
	}
}
```
ActiveHash (ActiveYaml) を i18n 対応する

ApplicationRecord と同じように i18n できなかったのでメモしておく。

```ruby:config/application.rb
# ...
Bundler.require(*Rails.groups)

class ActiveHash::Base
  extend ActiveModel::Translation
end

module YourAppName
  class Application < Rails::Application
# ...
```

```yaml:config/locales/ja.yml
ja:
  activemodel:
    models:
      model_name: モデル名
```

これをやらずとも、 https://github.com/zilkey/active_hash/pull/170 がマージされれば、ロケールを設定するだけでよくなる。


# 効用

```ruby
class MyModel < ActiveYaml::Base
end

# これで、以下のメソッドたちの返り値をロケールから変更できる
MyModel.model_name.human
MyModel.human_attribute_name(:column_name)
```
プロキシのタンデム化の仕方(プロキシチェイン)

# はじめに

[BurpSuite](https://portswigger.net/burp), [ZAP](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project), [Fiddler](https://www.telerik.com/fiddler) は、SSL の通信を解読しながら転送するプロキシツールで、デバグ/セキュリティ診断で使われている

# タンデムにしてもよいと思う

`Webブラウザ⇔Fiddler/BurpSuite/ZAP⇔上位のHTTPプロキシ⇔Webアプリケーション`

にするための設定。

# BurpSuiteの場合

![burp.png](https://qiita-image-store.s3.amazonaws.com/0/182822/d156920b-f4ad-6aec-9c6c-e5bec08e0cf7.png)

# ZAPの場合

![zap.png](https://qiita-image-store.s3.amazonaws.com/0/182822/ee570ab8-17f3-
a590-c7fb-5c9b38bc8336.png)

# Parosの場合

![paros.png](https://qiita-image-store.s3.amazonaws.com/0/182822/ffe67120-53d3-d43c-63ac-1ca4183616ce.png)

全部 XML ファイル

# Fiddlerの場合

![fiddler.png](https://qiita-image-store.s3.amazonaws.com/0/182822/b8715ca7-c4ae-85fe-5837-1aa1cb91c617.png)

# Index

[Indexへ戻る](https://qiita.com/tomoki0sanaki/items/258d6e77e4b16bc7d1c9)

# 以上
【PowerShell】 IPアドレスの自動取得/手動設定の切り替え 

最近、PCをある機器に接続して使用する際、IPアドレスを自動取得/手動設定を切り替える必要がある。その際、ネットワークの設定～をいちいち開いて手動でアドレスを入力するのはとても面倒なため、自動化を試みた。バッチを使おうとも思ったが、折角powershellというものがあるため、使ってみた。

実行時にダイアログを出して自動取得/手動設定のどちらかを選択する、みたいなものはいちいち入力するのが面倒であるため、実行する度に自動取得/手動設定を切り替えるものとした。

```powershell

# 管理者権限で実行できるようにする
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{   
	$arguments = "& '" + $myinvocation.mycommand.definition + "'"
	Start-Process powershell -Verb runAs -ArgumentList $arguments # 別プロセスにて本処理を実行
	Break
}

# IPv4アドレス取得
$addr = [system.net.dns]::GetHostAddresses((hostname)) | where {$_.AddressFamily -eq "InterNetwork"} | select -ExpandProperty IPAddressToString

# 現在、IPアドレスが自動取得の場合は任意の値に、任意の値になっている場合は自動取得に設定する
if ($addr -eq "〇〇.〇〇.〇〇.〇〇") # IPアドレスが手動設定になっている場合（〇〇.〇〇.〇〇.〇〇にはアドレスを入力）
{
	netsh interface ipv4 set address name = "イーサネット" dhcp
	netsh interface ipv4 set dnsservers name = "イーサネット" dhcp
	echo "IPアドレスをDHCPからの自動取得に設定を変更しました。`n"
}
else # IPアドレスをDHCPサーバから自動取得している場合
{
	netsh interface ipv4 set add name = "イーサネット" source = static addr = "〇〇.〇〇.〇〇.〇〇" # 〇〇.〇〇.〇〇.〇〇にはアドレスを入力
	echo "IPアドレスを任意の値に変更しました。`n"
}

pause
```


ここがおかしい、ここ間違ってるぞ、ここはこうした方がいいぞ！等あれば、是非ご指摘いただけますと非常に喜びます。
プロキシの既定のポート

# はじめに

[BurpSuite](https://portswigger.net/burp), [ZAP](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project), [Fiddler](https://www.telerik.com/fiddler) は、SSL の通信を解読しながら転送するプロキシツールで、デバグ/セキュリティ診断で使われている

最近、オレオレ証明書のままだと、(診断対象外のドメインの)外部JSを読まない(「オレオレだから危険承知でアクセスしてね」ダイアログがHTMLページの内部処理(XHRなど)なので表示されない)で、エラーとなるケースが結構多いので、そろそろプロキシの証明書を認証局として信用させる方法をメモしておく

# 既定のポート

## BurpSuiteの場合

8080/tcp

![burp.png](https://qiita-image-store.s3.amazonaws.com/0/182822/b522cd3b-6195-cae6-be27-c43d4bcabeb4.png)

## ZAPの場合

8080/tcp

![zap.png](https://qiita-image-store.s3.amazonaws.com/0/182822/eca3adae-6430-1e83-5bca-6f691463481d.png)

## Parosの場合

8080/tcp

![paros.png](https://qiita-image-store.s3.amazonaws.com/0/182822/8cace2cc-1707-ae74-3891-26aa8fa0f525.png)

全部 XML ファイル

## Fiddlerの場合

8888/tcp

![fiddler.png](https://qiita-image-store.s3.amazonaws.com/0/182822/99e266a6-29ec-f489-4f46-5368f209fc1c.png)

## sPortRedirector2 の場合

[自作(VB6+COM{VC++6/ATM})のは 8081/tcp](http://rocketeer.dip.jp/sanaki/free/free68.htm)

## sPortRedirector2 の場合

[自作(C#/.NET4})のは 8083/tcp](http://rocketeer.dip.jp/sanaki/free/free140.htm)

# まとめ

ZAP と BurpSuite が同一のポート番号っていうのが、なんか個人的にはモヤっとする...

# Index

[Indexへ戻る](https://qiita.com/tomoki0sanaki/items/258d6e77e4b16bc7d1c9)

# 以上
CVVTuberExample の VRMCVVTuber を動かす

# 概要
Unity アセットの CVVTuberExample の中に同梱されている、
VRMCVVTuberExample を動かすのに少し修正が必要だったのでメモ

## CVVTuberExample とは
OpenCV と Dlib を使って簡単に VTuber システムを作るもの。
その中でも VRMCVVTuberExample は、VRMモデルを利用したもの。

## 利用したもの
[OpenCV for Unity](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088)（有料）
[Dlib FaceLandmark Detector](https://assetstore.unity.com/packages/tools/integration/dlib-facelandmark-detector-64314)（有料）
[CVVTuberExample](https://assetstore.unity.com/packages/templates/tutorials/cv-vtuber-example-118186)
[UniVRM](https://github.com/dwango/UniVRM/releases)（今回は現時点で最新の0.49を利用）
[VRMモデル](https://3d.nicovideo.jp/works/td32797)（今回は AliciaSolid.vrm を利用、お好きなキャラクターでお試しください [VRoid Hub](https://hub.vroid.com/) オススメ）
[Webカメラ Logicool C270](https://www.amazon.co.jp/gp/product/B003YUB660)

## セットアップ
1. Asset Store から CVVTuberExample をインポート
1. CVVTuberExample/CVVTuber/Addons/VRMCVVTuber.unitypackage をダブルクリックしてインポート
1. CVVTuberExample/CVVTuber/Addons/VRMCVVTuber/Examples/VRMCVVTuberExample.unity をダブルクリックしシーンを読み込み
1. Asset Store から OpenCV for Unity をインポート
1. Asset Store から Dlib FaceLandmark Detector をインポート
1. インポートした OpenCVForUnity, DlibFaceLandmarkDetector の中にある StreamingAssets フォルダを、Assets 配下に移動する
1. UniVRM をインポート

## VRM モデルを読み込む
Assets 配下の適当なところに、ダウンロードしてきた vrm ファイルを D&D
出来上がった prefab を Hierarchy に D&D

その後、Hierarchy の VRMCVVTuberExample 内の VRMControllManager を選択し
Inspector に表示される VRM Loader (Script) 内の Meta に読み込んだモデルを選択する

## コードの修正
今のままだと、エラーが出たままで実行できないので、修正します。
原因はおそらく UniVRM の仕様が昔から変わってるからだと思います。

#### VRMCVVTuberControllManager.cs を修正する
67行目あたり

```cs:VRMCVVTuberControllManager.cs
((VRMHeadRotationController)item).target = vrmLoader.lookAtHead.Head.Transform;
```
↓

```cs:VRMCVVTuberControllManager.cs
((VRMHeadRotationController)item).target = vrmLoader.lookAtHead.Head;
```

#### VRMLoader.cs を修正する
56行目あたり

```cs:VRMLoader.cs
var context = new VRMImporterContext (path);
context.ParseVrm (bytes);
```
↓

```cs:VRMLoader.cs
var context = new VRMImporterContext ();
context.ParseGlb(bytes);
```

これで実行できるようになります。

## おまけ
VRMLoader.cs の修正部分は、ランタイムロードを使う部分なので、
そのまま動かす場合は関係ないですが、実行できるようにするために必要です。

ランタイムロードを確認する場合は、StreamingAssets 配下に vrm ファイルを配置します。
また、Hierarchy の VRMCVVTuberExample 内の VRMControllManager を選択し
VRMCVV Tuber Controll Manager (Script) の Use Runtime Loader にチェックをいれて
VRM Loader (Script) 内の VRM File Name StreamingAssets 配下からの vrm ファイルのパスを入力してください。
StreamingAssets/Model/AliciaSolid.vrm と配置していたら Model/AliciaSolid.vrm と入力する。
<img width="518" alt="スクリーンショット 2019-02-03 0.04.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/265518/c61cd679-bead-8b6e-b223-fd9d9762310b.png">
これで VRM モデルのランタイムロードができます。
この場合は、モデルの prefab を Hierarchy においておく必要がありません。
只今勉強中！機械学習で使われる用語、関数、モデル

### 分類と回帰の用語
| 用語            |  意味 |
|:---------------------|:-----------------|
| サンプル or 入力 |モデルに渡される１つのデータ　 |
| 予測値 or 出力  | モデルから返される値 |
| 目的値   | 真の値。外部のデータに基づいてモデルが予測すべき値 |
| クラス | 分類問題において選択可能な一連のラベル|
| ラベル | 分類問題でのクラスアノテーションのインスタンス |
| グラウンドトルース or アノテーション | データセットの全ての目的値 |
| 二値分類 | 入力サンプルを2つの相互吐いたなカテゴリに分類するタスク|
| 多クラス分類 |MNSITのような2つ以上のカテゴリに分類するタスク |
| 多ラベル分類 |各入力サンプルに複数のラベルを割り当てる分類タスク |
| スカラー回帰 |目的値が連続するスカラー値となるタスク　※価格予測問題など |
| ベクトル回帰 |連続ベクトルなど、目的値が連続値となるタスク※画像の境界矩形の座標など |
| ミニバッチ or バッチ |モデルがデータを処理する際の処理単位 |


###　最終レイヤーの活性化関数と損失関数

| 問題の種類              |  活性化関数        | 損失関数 |
|:-----------------------|------------------:|:------------------:|
| 二値分類　             |　sigmoid | binary_crossentropy |
| 多クラス単一ラベル分類  |  sogtmax | categorical_crossentropy |
| 多クラス多ラベル分類   |  sigmoid | binary_crossentropy |
| 任意の値に対する回帰  |   - | mse |
| 0 ~ 1の値に対する回帰 |  sigmoid | mse or binary_crossentropy |
機械学習で何をしたいかによって最終レイヤーの出力形式が変わる
損失関数も変わる


### レイヤー：ディープラーニングの構成要素
データ形状によって選択すべきモデルのアーキテクチャが異なる

| データ形状  |  選択されるレイヤータイプ | Keras クラス |
|:-----------------------|:------------------|:---|
| 2次元テンソル　         |　全結合層 | Denseクラス
| 3次元テンソル  | LSTM層などのリカレント層 |https://keras.io/ja/layers/recurrent/  |
| 多クラス多ラベル分類   |  2次元の畳み込み層(Conv2D)|  |
機械学習で何をしたいかによってデータの形状は変わる
そして、データの形状によって最適なレイヤーが変わる
レイヤーのタイプが変わればデータの渡し方も変わる
XML形式のデータをMySQLにロードする

Q. mysqldumpで生成したxml形式のダンプデータをリストアしたい。
A. LOAD XML 構文を使えばできる。

## mysqlを起動し、ログイン
```shell
$ ls  #xmlファイルが存在することを確認
person.xml
$ mysql.server start 
$ mysql -u [ユーザ名] -p 
```
XMLファイルの中身はこんな感じ(mysqldumpで作成できる)

```xml:person.xml
<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="practice">
	<table_structure name="person">
		<field Field="id" Type="int(11)" Null="YES" Key="" Extra="" Comment="" />
		<field Field="name" Type="varchar(255)" Null="YES" Key="" Extra="" Comment="" />
		<options Name="person" Engine="InnoDB" Version="10" Row_format="Dynamic" Rows="2" Avg_row_length="8192" Data_length="16384" Max_data_length="0" Index_length="0" Data_free="0" Create_time="2019-02-02 14:49:49" Update_time="2019-02-02 14:55:38" Collation="utf8_general_ci" Create_options="" Comment="" />
	</table_structure>
	<table_data name="person">
	<row>
		<field name="id">1</field>
		<field name="name">usera</field>
	</row>
	<row>
		<field name="id">2</field>
		<field name="name">userb</field>
	</row>
	</table_data>
</database>
</mysqldump>
```
## XMLファイルをMySQLにロードする  
personテーブルのデータをリストアする

```sql
mysql> USE [データベース名];
mysql> TRUNCATE person; 
mysql> LOAD XML LOCAL INFILE 'person.xml' INTO TABLE person;
```

## 結果

```sql
mysql> SELECT * FROM person;

+------+-------+
| id   | name  |
+------+-------+
|    1 | usera |
|    2 | userb |
+------+-------+
2 rows in set (0.01 sec)
```

## 参考
https://dev.mysql.com/doc/refman/5.6/ja/load-xml.html
【Go】html上でrangeループさせている中で別の構造体の値を追加して条件分岐【Gorm】

# Gormを使ってDBから取ってきたデータをビューで表示させるとき

下にハマったポイントと解決策を書きてます。

### 配列型のものを中身を繰り返して表示させる
gormから配列型で値を取得し、ビュー側に渡した場合を想定。
配列の中身の文だけ繰り返したいときは下記の用に書くことができる。

```hoge.html
<!-- ループの開始 -->
{{ range .Sample }}
<!-- Sample内にあるnameを表示させる -->
 <div>{{.Name}}</div>
<!-- ループの終わり -->
{{ end }}
```
### HTML上での条件分岐の方法

下記の下記方で可能(今回は　== と != のみ)。

```hoge.html
<!-- if hoge1 == hoge2 を意味する-->
 {{ if eq hoge1 hoge2 }}
 <div>{{.Name}}</div>
<!-- if文のの終わり -->
{{ end }}
<!-- if hoge1 != hoge2 を意味する(あえて上のelseではない方法で記載)-->
 {{ if ne hoge1 hoge2 }}
 <div>{{.Name}}</div>
<!-- if文のの終わり -->
{{ end }}
```
rubyとかと違うから最初困惑しました。

### 特定のループの中で別のinterfaceの値を入れたい（ここハマりました）
想定は、メッセージアプリで自分の投稿と相手の投稿を左右別々に分けたいとき。
Ruby on Rails でいう if current_user.id == hoge.user_id　の部分

```hoge.html
<!-- current_userには今ログインしてるユーザーの情報が入っている -->
<!-- messageはuser_idを持つ。gormにて定義しているため構造体内ではUserIdとなる -->

{{ if eq .current_user.ID message.user_id }}
 <div>{{.message.Name}}</div>
{{ end }}
```
##### 掲題のrangeのループ内で、他の構造体を入れたい場合
以下だとエラーがでる。

```hoge.html
<!-- current_userには今ログインしてるユーザーの情報が入っている -->
<!-- messagesは配列。user_idを持つ。gormにて定義しているため構造体内ではUserIdとなる -->

{{ range .messages }}
{{ if eq .current_user.ID .user_id }}
 <div>{{.Name}}</div>
{{ else }}
 <div>{{.Text}}</div>
{{ end }}
{{ end }}
```
理由は、最初に {{ range .messages }}　を書いているため、直後の .current_user.ID　が messagesの要素だと判定される。
この場合、こちらの意図は別の値(current_user)をループ内で扱いたいのだが、
読み取り側の認識は存在しないフィールドを指定してるとなりエラーが発生する。

##### じゃあどうするねん
一旦、以下でできました。
変数を新たに定義する方法です。

```hoge.html

<!-- current_userには今ログインしてるユーザーの情報が入っている -->
<!-- messagesは配列。user_idを持つ。gormにて定義しているためUserIdと記載 -->
<!-- $hoge := hogehoge の形で変数を定義することができる -->
{{ $user_id := .current_user.ID }}
<!-- rangeのループ開始 -->
{{ range .messages }}
<!-- 上で定義した変数を条件分岐に入れる -->
{{ if eq $user_id .user_id }}
 <div>{{.Name}}</div>
{{ else }}
 <div>{{.Text}}</div>
{{ end }}
{{ end }}

```

変数に入れてifにいれることで望む挙動にはなりました。

###　　終わりに
一旦うまくいったものの、もう少しうまいやり方あるんじゃないかなーと思ってます。
自分でも調べますが、こうやるといいよ、っていうアドバイスやご指摘などあればお願いいたします。
unique_ptr のカスタムデリータにラムダ式を使う際、推論させる方法（C++17）

#はじめに

[追記] 推論させる方法はありませんでした。なので、この記事は「unique_ptr のカスタムデリータにラムダ式を使う際、なぜ推論してくれないか」の紹介になります。

通常、`std::unique_ptr`のカスタムデリータにラムダ式を使うときは、以下のように書くと思われます。

```cpp
#include <iostream>
#include <memory>

struct my_struct {
    void finalize() 
    { 
        std::cout << "finalized!"; 
    }
};

int main()
{
    auto lambda = [](auto * ptr) { 
        ptr->finalize();
        delete ptr;
    };
    
    std::unique_ptr<my_struct, decltype(lambda)> a{ new my_struct };

} // output: finalized!
```

このラムダ式には、名前を付ける必要があります。推論してくれません。

#なぜ推論しないのか
検索したところ、[ここ](https://github.com/adishavit/ctad_for_unique_ptr)を見つけました。理由を要約すると、どうやら、これは配列を引数に取った場合にポインタと推論してしまうからだそうです。一応、例を載せておきます。

```cpp
#include <iostream>
#include <boost/type_index.hpp>

template <typename T>
struct my_struct {
    my_struct(T) {};
    void check_type()
    { 
        std::cout << boost::typeindex::type_id_with_cvr<T>().pretty_name() << std::endl;
    }
};

int main(){
    int i[10];
    my_struct{i}.check_type(); // output: int*
}
```

#推論させる方法(未定義)

上記のリンクにあるように、[推論ガイド](https://cpprefjp.github.io/lang/cpp17/type_deduction_for_class_templates.html)を自分で書けば推論してくれます。推論してほしい型の最初の引数は、配列を使う場合には `my_struct[]`です。(配列と普通のものを、同時には使えなそうです)

[追記] しかし、これは未定義動作です。std名前空間には推論ガイドを書いてはいけません。

```cpp
#include <iostream>
#include <memory>

struct my_struct {
    void finalize() 
    { 
        std::cout << "finalized!" << "\n"; 
    }
};

namespace std { // wandbox の clang では std::__1 でできました

// 推論補助宣言 カスタムデリータ用
template <class T>
unique_ptr(my_struct *, T)
   ->unique_ptr<my_struct, T>;
   // ->unique_ptr<my_struct[], T>; 配列の場合

} // namespace std

int main()
{
    std::unique_ptr a{ // 推論！
        new my_struct, [](auto * ptr) { 
            ptr->finalize();
            delete ptr;
        }
    };
} // output: finalized!
```

#おわりに
~~`std::make_unique`のほうも考えましたが、これはカスタムデリータをサポートしていないため、上記でよさそうです。繰り返しになりますが、配列と同時に使う場合には使用できないと思われます。配列のみの場合は、[こんな感じ](https://wandbox.org/permlink/FnKrzplq2gqj50Ej)になりそうです。（ warning の山は無視してください... )~~

[追記] unique_ptr のカスタムデリータにラムダ式を使う際、推論させる方法はなさそうです。std名前空間は、特に断りがない限り自分で宣言または定義などを追加してはいけないようです。上記にあるように、移植性にかけるので、やらないようにしましょう！
Webのアニメーションチューニングまとめ

#webにゴリゴリのアニメーションつけると死にそうになる

これは私の日々の悩みでございます。一体何番煎じかと思いますが、備忘録としてまとめておきます。

##こんな人に読んでほしい
- フロントエンドエンジニアの人
- アニメーション使い倒したい人

##アプローチ方法
簡単に言えば、きゅー●ー3分クッキングがなぜ3分尺で出来るのか考えようってことです。明らかにその場で全部処理をしたら絶対に3分じゃできないことを、あの番組はやってのけるわけですね。

###1.画像サイズを縮小する
画像を使っている場合はまずここを見直します。ガッタガタで動作ゲキオモのときも、画像を圧縮すればだいたいある程度動くようになります。

###2.リアルタイム計算量を減らす
デザインが完全に固まっていて、これ以上デザイン的な変更が無いだろうという段階でやってほしいことです。
例えば、画像にブラーかけて黒み入れてトランスフォームアニメーションさせてるみたいなケースを想像してみてください。

```css
img {
  position:absolute;
  blur:10px;
  transition: transform 300ms ease;
  z-index:0;
}
img:hover{
  transform: scale(1.5);
}
/* imgの上に被ってる要素として */
.img-cover{
  position:absolute;
  width:...
  height:...
  background-color:rgba(0,0,0,0.5);
  z-index:1;
}
```

これは画像処理をその場でやろうとしていますね。
分解してみると、処理は

- 画像処理
- アニメーション

の二つに分けられます。問題なのは**画像処理計算**です。これは**加工済みの画像を予め用意してしまうのがベスト**です。きゅー●ー3分クッキングでよく見るアレですね。
Safariやchromeはレンダリングエンジンが優秀なのか画像処理入れてもあまり動かなくなることはありませんが、firefox、アイツはだめだ。
アニメーションはインタラクションも含みますから処理を用意しておくことはできません。ゆえに、画像加工などの独立した処理だけ先にやっておいてしまおうという魂胆になります。

###3.Gpuに処理を投げる
CSSのプロパティでこの二つはgpuに処理を投げることができます。

- transform
- opacity

基本的な考え方は[こちら](http://un-tech.jp/performance-gpu/#アニメーションにGPU処理を取り入れる)を参考に。
gpuとは何か、という方はcpuよりめっちゃ強いプロセッサぐらいに思ってください。
Jqueryアニメーションを利用している方は直接transformをいじるのは無理なので、迂回処理を書くか、スタイル用クラスの付与で代用しましょう。

先程参考にとお伝えしたリンク先にもありますが、**gpuのメモリ領域も有限**ですので**gpuに頼りすぎるとかえって遅くなる**場合もございます。ここは注意したいところです。

###4.DOM要素数を減らす
DOM要素を大量に一つのページで表示するのは実はかなり動作を重くする原因だったりします。
これが問題になるのはだいたいSPAで作っているサイトかと思います。ページ遷移してたらそんなに多くならないですよね。


SPAで例えば、ポートフォリオサイトを作ったとして、作品例を沢山のせたいときを考えてみましょう。

作品の詳細画面で、作品数分DOM要素を作ってdisplayを弄ったりして表示を変更するのはちょっと効率が悪いかなという気がします。作品が30、40、50と増えていけば、その分メモリが消費されるのは分かりきっています。
一つの作品表示画面の中身をreact的に変更してしまう、というのがこの解決法です。
作品データを別のファイルにjsonなりで纏めておいて、それを読み込み一つの詳細画面内の内容を書き換えてしまうというわけです。SPA向けライブラリのvue.jsとかAnglerもこの考え方ですよね。これは是非活用してほしい設計法です。

##おわりに
ユースケースとともに紹介しましたが、普通に私のポートフォリオサイトを製作したときの考察です。
なんでspaでそんなサイト作ってんねんって気がしますが、ゴリゴリアニメ使ってアプリっぽく動くの可愛くて使いやすくて大好きなんです。さくさく動いたらもう最高じゃないですか。

ここまで読んでくださりありがとうございました！
では楽しいアニメーションライフを！
junitで"The constructor Empty() is not visible"が発生する際の設定方法

#この記事の概要
eclipseでjunitを使用した際に、少し苦労したので、備忘録を兼ねて設定方法を記載します。
具体的にはテスト対象クラスにprivateコンストラクタがある際に下記エラーが発生することがあるので、その回避方法を記載します。

　 The constructor Empty() is not visible

#参考
[Junitでprivateメソッドのテスト方法](https://qiita.com/village/items/2f0d99b25eef0c8fd4ec)

[JavaのリフレクションAPIでメソッド取得、メソッド実行]
(http://pppurple.hatenablog.com/entry/2016/07/23/205446)

#環境
OS:Windows8.1 32bit
eclipse:4.5.2

#テスト対象クラス

```Java:TestTarget.java

packege com.web.test

public class TestTarget {

  private TestTarget() {
    //記述無し
  }

  private int minus(int x, int y) {
        return (x - y);
  }

}

```

#junitテストクラス

テスト対象クラスに対するjunitのテストクラスを作成

```Java:SampleTest.java

import static org.junit.Assert.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class SampleTest {

    @Test
    public void test()
        throws NoSuchMethodException,
        SecurityException,
        IllegalAccessException,
        IllegalArgumentException,
        InvocationTargetException
    {
        TestTarget testTarget = new TestTarget();

        Method method = Sample.class.getDeclaredMethod("minus", int.class, int.class);
        method.setAccessible(true);

        int actual = (int)method.invoke(testTarget, 8, 2);

        assertEquals(6, actual);
    }

```

このようにすると
　The constructor Empty() is not visible
が発生したので、下記のように変更します

```Java:SampleTest.java

import static org.junit.Assert.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class SampleTest {

    @Test
    public void test()
        throws NoSuchMethodException,
        SecurityException,
        IllegalAccessException,
        IllegalArgumentException,
        InvocationTargetException
    {
        //修正前
        //TestTarget testTarget = new TestTarget();
　　　　　　　　　　　　　　　　//修正後
　　　　　　　　　　　　　　　　//リフレクションAPIを使用してテスト対象クラスのインスタンスを取得
        TestTarget testTarget = Class.forName("com.web.test.TestTarget").newInstance();

        Method method = testTarget.class.getDeclaredMethod("minus", int.class, int.class);
        method.setAccessible(true);

        int actual = (int)method.invoke(testTarget, 8, 2);

        assertEquals(6, actual);
    }

```

これで
　The constructor Empty() is not visible
が解消されました
GistをIndieAuth.comアカウントにする

IndieAuth( https://indieweb.org/IndieAuth )はOAuth2拡張の1つで、Webページ自体をアカウントとして成立させる仕様となっている。昔なつかしの、ConnectじゃないOpenIDみたいな仕様。

で、これの実装としてIndieAuth.comが有り、これはPGP公開鍵単体でアカウントを成立させることができる。

やりかたは簡単で、

```html
<a rel="pgpkey" href="https://keybase.io/okuoku/pgp_keys.asc">PGP公開鍵</a>
```

のように、 `pgpkey` 入りの `rel` 属性を持ったリンクをHTMLに入れるだけになっている。

# アカウントの準備

...アカウントの準備といっても、PGP公開鍵へのリンクが入ったHTMLを適当なところでホストするだけで良い。今回はGistを使っているが、Glitch.meとかGitHub Pagesとか何かHTMLが適切なcontent-typeで送出されるところであればどこでもOKとなる。

## PGP公開鍵の準備

適当に準備する。 https://keybase.io/ とかGnuPGなりなんなりをインストールするとか。

## Gistの準備

https://gist.github.com/ にログインしてPGP公開鍵とHTMLを投稿する。HTMLにはPGP公開鍵のURLを書かないといけないが、とりあえず適当にしておく。

- 実際のGist: https://gist.github.com/okuoku/f9061275a52ecbb449ff5a8dbe0074ae

```html:URLは適当
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>profile</title>
    <meta charset="utf-8">
  </head>  
  <body>
  <a rel="pgpkey" href="https://keybase.io/okuoku/pgp_keys.asc">my pgp public key</a>
  </body>
</html>
```

投稿すると "Raw" ボタンが有るので、それぞれのURLを取得しておく。

![SnapCrab_NoName_2019-2-2_23-24-39_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/67446/72602054-6e95-d8ec-670b-cff6b083fa4d.png)

## URLの取得とページの書き換え

GitHack https://raw.githack.com/ にRawボタンをクリックして飛んだ先のURLを入力し、Productionの方のURLを入手する。今回は以下のようなURLが入手できた:

- HTML: https://gistcdn.githack.com/okuoku/f9061275a52ecbb449ff5a8dbe0074ae/raw/e053b0fe1db90a497a4874726810240b1a019db5/profile.html
- PGP公開鍵: https://gistcdn.githack.com/okuoku/f9061275a52ecbb449ff5a8dbe0074ae/raw/8fe65de36190cf571966bec8893d0b4451052790/pubkey.asc

PGP公開鍵のURLを取得したら、そちらを指すようにHTMLの方を書き換えておく。

# 実際のログイン

https://indieauth.com/setup の下部にお試し用のログインフォームが有るため、これを使ってログインを試すことができる。URLはHTMLの方のgistcdnのURLを入力する。

入力するとテキストデータ(JWT)を署名するように求められるので、秘密鍵で署名する。IndieAuthのページ https://indieauth.com/pgp ではMacOSのGPG Toolsを使った方法とkeybase.ioを使った方法が紹介されている。Windowsの場合はGPG4Winに収録されている、Kleopatraを使うのが簡単。

1. 署名する文字列をクリップボードにコピーする
2. タスクトレイのKleopatraを右クリックして クリップボード → OpenPGP署名... を選ぶ
3. ウィザードに従って署名するとクリップボードに署名済の文字列がコピーされる
4. ブラウザにペースト

ちなみに署名させられるJWTは以下のような内容を `HS256` 署名したものとなっている。

```json
{
  "me": "https://gistcdn.githack.com/okuoku/f9061275a52ecbb449ff5a8dbe0074ae/raw/e053b0fe1db90a497a4874726810240b1a019db5/profile.html",
  "profile": "https://gistcdn.githack.com/okuoku/f9061275a52ecbb449ff5a8dbe0074ae/raw/8fe65de36190cf571966bec8893d0b4451052790/pubkey.asc",
  "redirect_uri": "https://indieauth.com/success",
  "state": null,
  "scope": null,
  "nonce": 970530,
  "created_at": 1549118458
}
```

# 感想

Mailvelopeに対応してよ！(去年末のアップデートで、PC上のGnuPGを直接呼び出せるようになった)

ちなみに最初は **Qiita投稿をアカウントにする** でやろうと思ってたけど、 [QiitaはHTMLタグに属性を入れられない](https://blog.qiita.com/162037299989-2/)ので上手くいかなかった。