OmniAICreator/Qiita-1.07M huggingface dataset:
Qiita gemを使ってみる！

##前提
Qiitaのアカウントを取得済みであること


##アクセストークンの発行  
  

QiitaのTopページを開き、赤枠の「設定」を押下する
![スクリーンショット 2017-02-11 18.15.56.png](https://qiita-image-store.s3.amazonaws.com/0/128479/08577496-8413-65ea-fba4-ad06186cf679.png "スクリーンショット 2017-02-11 18.15.56.png")

赤枠の「アプリケーション」を押下する  
![スクリーンショット 2017-02-11 18.17.07.png](https://qiita-image-store.s3.amazonaws.com/0/128479/9b4a126b-aded-c40c-c02f-20e2ded862d5.png "スクリーンショット 2017-02-11 18.17.07.png")
    
  
赤枠の「新しくトークンを発行する」を押下する
![スクリーンショット 2017-02-11 18.17.25.png](https://qiita-image-store.s3.amazonaws.com/0/128479/60bec478-388e-07b7-c35f-d590cf93fa26.png "スクリーンショット 2017-02-11 18.17.25.png")

  
赤枠の「説明」を入力、「スコープ」のチェックボックスは用途に合わせて、チェックする  
![スクリーンショット 2017-02-11 18.21.33.png](https://qiita-image-store.s3.amazonaws.com/0/128479/294c84c0-a7da-c519-afda-86b7b24387c3.png "スクリーンショット 2017-02-11 18.21.33.png")
 赤枠の黒塗り部分にアクセストークンが記述されている
![スクリーンショット 2017-02-11 18.21.52.png](https://qiita-image-store.s3.amazonaws.com/0/128479/4c290a4b-5617-98b7-f497-9bfecc023b1b.png "スクリーンショット 2017-02-11 18.21.52.png")

  

##gemのinstall
以下のコマンドを実行する

	gem install qiita
	
	bundle install
	
これで準備は完了！
	
##実際にAPIを呼んでみる
ここは実装によるので、処理を記述する場所はどこでもよいです、`controller`でも`model`でも`job`でも。  
  
先ほど取得したアクセストークンを設定する
	
	client = Qiita::Client.new(access_token: "取得したアクセストークン")
	
自分のqiitaIdを使用して、自分の情報を取得する

	client.list_user_items("自分のqiitaId")


これでjson形式のレスポンスが返ってきます！

#終わりに
すごく簡単に取得できるので、是非やってみてください。
ただ「いいね」数を取得したかったんですが、qiitaチームに入ってないと「いいね」は取れないようです残念笑
さくらレンタルサーバでredis

- アカウント : hoge

1. [redis最新を確認](https://redis.io/download) -> 現時点では3.2.7だったので今回はこれを採用
2. 汚したくないので `/home/hoge` に `src` ディレクトリを作ってそこで作業をする

    ```
$ cd
$ mkdir src
$ cd src
$ wget http://download.redis.io/releases/redis-3.2.7.tar.gz
$ tar xzf redis-3.2.7.tar.gz
$ cd redis-3.2.7
    ```

1. `src/Makefile` ファイルの`PREFIX?=/usr/local`部分を `/home/hoge/お好きなPath` -> 自分は `/home/hoge/usr/local`とした
1. pwd= `/home/hoge/src/redis-3.2.7`
2. 
    ```
$ gmake
$ gmake install
    ```

1. `3`で設定した `PREFIX`のpath/bin 内にインストールされる
1. `.cshrc` の `set path` に `$HOME/3のPREFIX/bin`を追加
1. 一旦exit
2. ssh で再度ログイン
3. `nohup redis-server < /dev/null >& /dev/null &`　でバックグラウンド起動
4. `$ redis-cli`で接続できた
ScalaScalableProgramming 02章 ふりかえり

# Scala 02章

## インタープリタでやる

```Bash
$ def max(x:Int, y:Int) = if (x > y) x else y
```

を入力すれば、関数maxが定義される。
あとは呼べばいいだけ。

```Bash
$ max(3, 5)
res0: Int = 5
```

yの方が大きいので、「5」が出力される。

## Scalaスクリプトでやる

```scala:pa.scala
args.foreach(println)
```

pa.scala で保存。

```Bash
$ scala pa.scala scala is fun
scala
is
fun
```

改行されて表示される。
知っていると便利なEclipseのショートカットキー

# はじめに
Eclipseを使っていてこれは便利だなと思ったショートカットキーをMacとWindowsをまとめました。

## ウィンドウ

|コマンド|Mac|Windows|用途|
|---|---|---|---|
|Open Resource<br>(リソースを開く)|command+shift+R|Ctrl+Shift+R|ファイル名で検索|
|Show Key Assist<br>(キー・アシストを表示)|command+shift+L|Ctrl+Shift+L|ショートカットキー一覧表示|
|Toggles maximize/restore state of active view or editor<br>(アクティブ・ビューまたはエディターの最大化)|control+M|Ctrl+M|エディタの拡大/縮小|
|<br>||||

## ファイル

|コマンド|Mac|Windows|用途|
|---|---|---|---|
|Save<br>(保管)|command+s|Ctrl+S|ファイルの保存をする|
|Close All<br>(すべて閉じる)|command+shift+W|Ctrl+Shift+W|すべてのウィンドウを閉じる|
|<br>||||

## 検索

|コマンド|Mac|Windows|用途|
|---|---|---|---|
|<br>(「検索」ダイアログを開く)||Ctrl+H|ワークスペース内を検索する|
|<br>||||

## ナビゲート

|コマンド|Mac|Windows|用途|
|---|---|---|---|
|Go to Matching Bracket<br>(対応する大括弧にジャンプ)|command+shift+P|Ctrl+Shift+P|開始終了の括弧を探す|
|Go to Line<br>(指定行へジャンプ)|command+L|Ctrl+L|行指定で開く|
|Forward History<br>(次のサブ・タブ)|command+]|Alt+PageDown|前の行動に戻る|
|Backward History<br>(前のサブ・タブ)|command+[|Alt+PageUp|次の行動を開く|
|<br>(前のメンバーへジャンプ)||Ctrl+Shift+Up|上にある前のメソッドへ移動|
|<br>(次のメンバーへジャンプ)||Ctrl+Shift+Down|下にある次のメソッドへ移動|
|<br>||||

## 編集

|コマンド|Mac|Windows|用途|
|---|---|---|---|
|Undo<br>(元に戻す)|command+Z|Ctrl+Z|修正前に戻す|
|Redo<br>(やり直し)|command+shift+Z|Ctrl+Y|修正後に戻す|
|Cut<br>(切り取り)|command+X|Ctrl+X|ドラッグした部分を切り取る|
|Copy<br>(コピー)|command+C|Ctrl+C|ドラッグした部分をコピーする|
|Paste<br>(貼り付け)|command+V|Ctrl+V|コピーした部分を貼り付ける|
|Content Assist<br>(コンテンツ・アシスト)|control+space|Ctrl+Space|使用可能候補一覧を表示する|
|Find and Replace<br>(検索と置換)|command+F|Ctrl+F|エディタ内の検索や置換をする|
|<br>||||

## テキスト編集

|コマンド|Mac|Windows|用途|
|---|---|---|---|
|<br>(行の末尾まで削除)||Ctrl+Shift+Delete|カーソルより後ろの行末尾まで削除する|
|<br>||||

## リファクタリング - Java

|コマンド|Mac|Windows|用途|
|---|---|---|---|
|Rename - Refactoring<br>(名前変更)|option+command+R|Alt+Shift+R|一括で名前を変更する|
|<br>||||
Arduino YunにAjaxで通信できたぁ〜

# 前説
## Arduino Yunとは
https://www.switch-science.com/catalog/2210/
wifiが付いてるArduino
IoTのプロトタイプ作成時に活躍していくと思います
BLEはGenuinoなどがあります
（https://www.switch-science.com/catalog/2670/）
Genuinoに関しては，後日投稿予定

Arduino Yunの設定方法は以下も参考にしていただければ
http://qiita.com/tkyko13/items/495b4b1bdc2d4eb00d0a

## Ajaxとは
ページごと読み込まずに通信できる（簡単すぎる．．．）
HTMLは静的なので通信するってことはページをもう一回全部読み込むってことをしなきゃだが，javascriptを利用してページ遷移せずとも，なんかのユーザーアクションに合わせてなどで，通信して情報を表示できるようにするもの（長すぎる．．．）
今回はjavascriptのjqueryを利用して書いています〜

## JSONPとは
フォーマットを見ればjsonになんか余計なもんがくっついてて，ルールが増えてるやつ
でもなんかクロスドメインと連携するときはなんかできるらしい
なので，これを今回は使ってます
今回詰まったところはこのクロスドメインとjsでのjsonpの扱い方でした


# Arduino側コード
ArduinoのサンプルにあるBrigeをちょっと書き換えます
（書き換えるところだけ書きます）
最初あたりの行に書いてある"callback"は共通のキーワードなので覚えておきましょう

``` BrigeJson.ino

// (省略)

// Send feedback to client
  client.println(F("callback(")); //jsonp用
  client.print(F("{\"pin\":\""));
  client.print(pin);
  client.print(F("\", "));
  client.print(F("\"value\":\""));
  client.print(value);
  client.print(F("\"})"));

```


# html,javascript側コード
jsonpCallbackの値は先程の共通キーワードです


``` index.html

<html>
<head>
  <script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script type="text/javascript">
  	$(document).ready(function(){
  		console.log("ready");

  		var url = "http://arduino.local/arduino/";
  		var ledReadUrl = url + "digital/13/";
		var ledOnUrl = url + "digital/13/1/";
		var ledOffUrl = url + "digital/13/0/";
		
  		$.ajax({
  			url: ledReadUrl,
  			//username: "root", //yun側でパスワード解除したのでいらない
  			//password: "arduino",
  			dataType : 'jsonp',
  			jsonpCallback : 'callback', //jsonp用
  			success: function(json){
     			console.log(json);
   			}
		});

	});
</script>
</head>
<body>
	<input type="number" name="led">
  
</body>
</html>

```
Web Bluetooth APIでArduino 101とブラウザを直接つなぐ

Google Chromeのバージョン56からWeb Bluetooth APIが正式にリリースされたので、BLEでセンサーの値を飛ばすデバイスを作って試してみました。

## 試したこと

Arduino 101の内蔵IMUから加速度センサ3軸の値を読み取り、BLEで送信する。Chromeは、受信した各軸の値をグラフに描画する。

## 試した環境

- macOS 10.12.3
- Chrome 56.0.2924.87
- Arduino (Genuino) 101
    - BLEと6軸センサーがあらかじめ載っているので、ハンダ付けの手間がなく楽だった。

## 手順

https://github.com/niccolli/WebBluetoothAPIwithCURIE

こちらのリポジトリにまとめています。

1. Arduino 101にCurieIMU.inoを書き込みます
2. Arduino 101を起動させておく
3. index.htmlをChromeで開く。localhostのWebサーバか、file://として開く。
4. Start Notificationsのボタンを押す

## 結果

[![Arduinoを動かすとグラフ描画に反映される様子](http://img.youtube.com/vi/Ap-wo2-b5Rk/0.jpg)](http://www.youtube.com/watch?v=Ap-wo2-b5Rk)
JavaScript クイックソート

#クイックソート
クイックソートはその名にクイックとあるように処理速度の速いコードです。
「再帰」という考え方を使っています。

##アルゴリズムのイメージ
・配列の中の小さいデータを左側に集め、大きいデータを右側に集めるて大小二つのグループをつくる。
・それぞれのグループで同じように小さいデータを左側に、大きいデータを右側に集めてさらに大小二つのグループをつくる。
・上記の処理を繰り返す事によって配列全体を小さいデータから大きいデータに順番に並べる。
・クイックソートでは処理速度を速めるために、交換する必要のある値だけを交換する。
・クイックソートでは「再帰」を利用する

##交換する必要のある値だけを交換
クイックソートでは、交換する必要のある値だけを交換するために「ピボット(大小の値の分岐点)」を決めます。
ピボットの決め方は色々ありますが、本記事では「真ん中にある値」ですすめます。
アイデアとしては、ピボットを基準に左側を調べてピボットより大きい値を見つけます。
同時に、ピボットの右側を調べてピボットより小さい値を見つけます。二つがそろった時に値を交換すれば無駄な処理を省くことができるのです。

##「再帰」を利用
クイックソートでは再帰を利用します。再帰とは「自分で自分自身を呼び出す」ことです。
先頭から末尾まで順番に探していくような「並列的な繰り返し」はループ処理で行います。しかし、「分割した部分に対してさらに同じように分割する」といった階層的に一段深い処理に対しては再帰を利用します。
再帰のイメージは自分と同じ役割をこなせる分身をつくって分身に作業をさせる、でしょうか。分身がさらに分身をつくっていく感じです。
「人間は反復し、神は再帰する。」というような言葉もあります。
注意点としては、階層が深くなるにつれて消費のメモリが大きくなること、無限の繰り返しを止めるために終了条件をきめておくことです。

##手順
前提 未整列のデータを用意する。
1 再帰のための関数を作成する。引数にソートの開始位置と終了位置を設定する。
2 開始位置と終了位置からピボットを決めて、「交換する必要のある値だけを交換」して大小のグループに分割します。
3 分割したグループに対してさらに大小のグループに分けるように再帰的に処理を繰り返します。
4 分割できなくなるまで処理を繰り返しを行えばソート完了



##コード

```script.js
//クイックソート関数
function quickSort(startID,endID){
    //範囲の間にある値をピポットに設定する
    var pivot = a[Math.floor((startID + endID)/2)];
    //引数を左端、右端として変数にいれる
    var left = startID;
    var right = endID;

    //ピポットより小さい値を左側へ、大きい値を右側へ分割する
    while(true){
        //leftの値がpivotより小さければleftを一つ右へ移動する
        while(a[left]<pivot){
            left++;
        }
        //rightの値がpivotより小さければrightを一つ左へ移動する
        while(pivot<a[right]){
            right--;
        }
        //leftとrightの値がぶつかったら、そこでグループ分けの処理を止める。
        if(right <= left){
            break;
        }

        //rightとrightの値がぶつかっていない場合、leftとrightを交換
        //交換後にleftを後ろへ、rightを前へ一つ移動する
        var tmp =a[left];
        a[left] =a[right];
        a[right] =tmp;
        left++;
        right--;
    }

    //左側に分割できるデータがある場合、quickSort関数を呼び出して再帰的に処理を繰り返す。
    if(startID < left-1){
        quickSort(startID,left-1);
    }
    //右側に分割できるデータがある場合、quickSort関数を呼び出して再帰的に処理を繰り返す。
    if(right+1 < endID){
        quickSort(right+1,endID);
    }
}

   //未整列の配列
   var a = [3,7,2,4,6,1,9,8,5];
   //先頭から末尾までソートする
   quickSort(0,a.length-1);

//結果の表示    
console.log(a);
```
Raspberry Pi で コーデックに h264_omx で ffmpeg を使おうとして OMX_GetHandle(OMX.broadcom.video_encode) failed: 80001005 とかエラーになった時

# conclusion
考えられる原因はいろいろあるのでしょうけど、 ***カメラモジュールが有効になっていない***、のが原因かも

![スクリーンショット 2017-02-11 17.29.59.png](https://qiita-image-store.s3.amazonaws.com/0/46544/78799b28-2afc-17d8-6a78-5b35850ecc36.png)

raspi-config で ***enable にしたら動いた***

こんな感じで input に uvc カメラ使ってたのでちょっと気が付きにくい盲点でした

```bash:
ffmpeg -f v4l2 -input_format yuv420p -i /dev/video0 -an -c:v h264_omx test.mp4
```

# future works
でも、なんで hw encoder 使うのにカメラモジュールを有効にしないといけないんだろ？
というか、そもそもカメラモジュールの enable/disable って VideoCore 側で何やってるんだろ？
全然無知なのをなんとかしたい
カレントディレクトリ下のzipファイルをすべて解凍する

カレントディレクトリ以下のサブディレクトリに散らばったzipファイルをたくさん解凍する必要があったのでPythonで書いた。
動かした環境はSolaris11.2, Python2.6.2でネットに繋がってない環境だったのですべて標準モジュールだけでやる必要があった。

ファイル一覧の取得は、「[Pythonで再帰的にファイル・ディレクトリを探して出力する](http://qiita.com/suin/items/cdef17e447ceeff6e79d)」を参考にさせてもらった。

``` Python:unzip_all_files.py
import sys
import os
import commands

def find_all_files(directory):
    """ list-up all files in current directory(includes subdir). """
    for dir, subdirs, files in os.walk(directory):
        yield dir
        for file in files:
            yield os.path.join(dir, file)

def unzip_all_files(directory):
    """ unzip all files in current directory(includes subdir). """
    files = find_all_files(directory)
    for file in files:
        if file.endswith(u".zip") or file.endswith(u".ZIP"):
            command = u"unzip -o " + file + u" -d " + os.path.dirname(file)
            print command
            commands.getoutput(command)

if __name__ == "__main__":
    if os.path.exists(sys.argv[1]):
        unzip_all_files(sys.argv[1])
```
google cloud  コマンドメモ にゃ


コマンド周りを忘却するので、メモ


## 設定

* Project一覧 `gcloud projects list `
* 設定確認 `gcloud config list`
* Project変更 `gcloud config set project xxxx`
* Login `gcloud auth login <username>`
    * list `gcloud auth list`
    * remove `gcloud auth revoke <username>`


## ストレージ操作

* list contents `gsutil ls gs://<bucketname>/path ...`
* print `gsutil cat gs://<bucketname>/path ...`
* copy `gsutil cp gs://<bucketname>/path ./<path to local path>`

## GAE

* services `gcloud app services list`
* versions `gcloud app versions list`
* deploy `gcloud app deploy <app yaml>`
   * dispatch, index, queue, cron `gcloud app deploy {dispatch, index, queue, cron}.yaml`



## Container

* images list `gcloud beta container images list --repository=gcr.io/xxxx`
* image tag list`gcloud beta container images list-tags`
* k8s cluster `gcloud container clusters list`
* k8s pool `gcloud container node-pools list  --cluster <cluster name> --zone <zone>`

[k8s command](https://qiita.com/YooWaan/items/84e0c1ea891a40954bba)

## Compute

* create `gcloud compute instances create <instance name> --zone xxxx --machine-type xxx --image-family=xxxxx --image-project=xxxxx --address xxxxxxxxx --scopes xxxx`
    * --zone xxxx  場所関係
    * --machine-type xxx --image-family=xxxxx --image-project=xxxxx   マシンタイプ、OSとか
    * --address xxxxxxxxx   外部IPを設定する場合
    * --scope インスタンスに許可するスコープ
* describe `gcloud compute instances describe <instance name>`
* ssh `gcloud compute ssh <user name>@<instance name>`
* delete `gcloud compute instance delete <instance name>`
* instance group `gcloud compute instance-groups list`
* instance group members `gcloud compute instance-groups list-instances <instance group name> --zone <zone name>`

## Network

* ip addrs `gcloud compute addresses list`
* forwords list `gcloud compute forwarding-rules list`
* url-maps `gcloud compute url-maps list`
* backend services `gcloud compute backend-services list`
* neg list `gcloud compute network-endpoint-groups list`
* dns managed `gcloud dns managed-zones list`


## StackDriver

* Log 一覧 `gcloud logging logs list`
    * read `gcloud logging read`
    * write `gcloud logging write`
* Alert設定一覧 `gcloud alpha monitoring policies list`
* 通知一覧 `gcloud alpha monitoring chanels list`
VirtualBox 上の CentOS7 仮想マシンで Kernel panic 起動トラブル

先ほど作ったばかりの VirtualBox 上の CentOS7 の仮想マシンで起動トラブルが発生した．たまたま解決できたようなので，今回も備忘録として（画面，コピペもスクショもとれなかったのでテキスト説明で）

【環境】
- Mac
- VirtualBox Version 5.0.32 r112930
- CentOS-7-x86_64-Minimal-1511.iso (このファイルで仮想マシン作成)
- CentOS Linux release 7.3.1611 (Core) (# yum -y update 後)
- SELINUX は無効化済み

```
/etc/sysconfig/selinux
SELINUX=disabled
```

VirtualBox から仮想マシンを起動すると3つの OS の選択画面が出るが，

```
CentOS Linux (3.10.0-514.6.1.el7.x86_64) 7 (Core)
CentOS Linux (3.10.0-327.el7.x86_64) 7 (Core)
CentOS Linux (0-rescue-1***f) 7 (Core)
```
通常，そのまま待っていると，数秒後にトップのものが自動的に選択される．

ところが，次の画面

```
error: file '/initramfs-3.10.0-514.6.1.el7.x86_64.img' not found.

Press any key to continue...
```
そして

```
[****.****] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
```
以下何行ものエラーが出た．

たまたま発見したのだが，起動直後の3つの OS の選択画面で，2番めのものを選ぶと，普通に起動した．Power Off し，再度1番めのものを選ぶと，無事起動．

```
CentOS Linux 7 (Core)
Kernel 3.10.0-514.6.1.el17.x86_64 on an x86_64
localhost login: _
```
この状態のものを .ova ファイルにエクスポートし，インポートすると，問題なく起動するようになった．この .ova ファイルを別途保存し，活用することにする．
[Docker] MacでDockerを動かすときにつまずいたポイント

つまずいたポイントをメモ

## あらゆるdockerコマンドが `Cannot connect to the Docker daemon`となり実行できない

```
$ docker ps
Cannot connect to the Docker daemon at tcp://12.168.99.100:2376. Is the docker daemon running?
```

これはenvの設定が間違っていてVMに接続できていないのが原因だった

```
DOCKER_HOST=tcp://12.168.99.100:2376  # IPが間違っていたり
DOCKER_MACHINE_NAME=default # VM名が違っていたり
DOCKER_TLS_VERIFY=1 
DOCKER_CERT_PATH=/Users/username/.boot2docker/certs/boot2docker-vm # パスが過去に入れていたboot2dockerのものになっていたり
```

`docker-machine env default` で正しい設定が得られるので、

```
$ eval "$(docker-machine env default)"
$ source ~/.bash_profile
```

を実行して書き直してあげればOK

## ブラウザからアクセスできない

これはVMの方のポートフォワーディングの設定が間違っていたのが原因だった

Railsアプリをポート3000で起動してhttp://localhost:3000でアクセスしようとして以下のコマンドでコンテナ作成

```
$ docker run -d -p 3000:3000 developer_name/project_name
```

だが繋がらない:(
調べた所Virtualboxの方でポートフォワーディングの設定が間違っていたので、以下のような設定に変更

defaultを選択 > 歯車のアイコンで設定を開く > ネットワーク > アダプター1 > 「高度」を選択 > ポートフォワーディング から

![image](https://qiita-image-store.s3.amazonaws.com/0/52847/d6c178c7-ecdd-11b2-10c5-72dc629b09b6.png)

3000:3000なら上記のような設定を追加

これでhttp://localhost:3000でつながるようになった。
MacOSXのフルスクリーンアプリの切り替え時のアニメーションをオフにする

MacOSXでフルスクリーンのアプリを使っていると、他のアプリに切り替える際にアニメーションが入ってアニメーションの切り替えが遅くなる。

MacOS Sierraではそのアニメーションをオフにできる。

## 手順

[システム環境設定] - [アクセシビリティ] - [ディスプレイ] - [視差効果を減らす] にチェックを入れるだけ。

![image](https://qiita-image-store.s3.amazonaws.com/0/28792/a40bd530-0655-b6a1-1a6b-5e7867e78a96.png)

これでアプリをフルスクリーンで使うのに躊躇することがなくなった。
Sierraから使える。

（ところで「視差効果を減らす」って和訳間違えてないだろうか？？英語では[Reduce Motion]というメニューになっている）

# 参考
https://www.tekrevue.com/tip/reduce-motion-macos-sierra/
excelの目盛表示の一部だけを消す

第二縦軸と目盛り線を合わせるために最大値は1.5に設定したいけど
実際の値は1.0が上限だから1.1以上は表示したくないというときのやり方.

第一縦軸の書式設定を呼び出して
表示形式タブを開き,カテゴリをユーザ設定にして
[>=1.1]""; と入力すると以下のように表示してくれる.

![image010.png](https://qiita-image-store.s3.amazonaws.com/0/78786/cca76617-bbc4-a3c4-41c4-489ceb06b257.png)


さらに小数点以下をそろえたい場合は
[>=1.1]"";#,##0.0_)
 と入力.

![image012.png](https://qiita-image-store.s3.amazonaws.com/0/78786/7024316a-0268-19ff-a4a2-d59138435b1a.png)
コマンドラインで簡単に画像変換 - ImageMagick編

ImageMagickを使うと、簡単に画像の一括変換できます。改めて、やり方をまとめてみます。

# インストール - ImageMagick

Windows版のImageMagickは、以下よりダウンロードできます。

- http://www.imagemagick.org/script/binary-releases.php#windows

macOSでは、Homebrewで簡単にインストールできます。

```
$ brew install imagemagick
```

# convert コマンド

``convert``コマンドを使うことができます。

## 画像形式の変換

test.bmp を test.png に変換するには、以下のように指定します。

```
$ convert test.bmp test.png
```

複数ファイルを変換するときは、シェルスクリプトを書くと良いです。

以下は、ディレクトリ内の「*.bmp」をPNGファイルに変換するものです。

```file:bmp2png.sh
#!/bin/sh
for f in $(ls *.bmp) 
do
  f2=`echo $f | sed -e "s/bmp$/png/"` 
  convert $f $f2 
done
```

## PDFファイルへの変換

ディレクトリ内のＰＮＧファイルをPDFに変換する

```
$ convert *.png out.pdf
```
わーい、すごーい

どうしてこのブームがあるかちょっとわからないけど、

とりあえず、[fromkk さんの Swift バージョン](http://qiita.com/fromkk/items/0797bdf3923622073a4f)を元に、中国語のバージョンをやってみました。

```
import Foundation

enum Friends {
    case wai
    case sugoi
    case tanoshii
    case skill(String)
    func message() -> String {
        switch self {
        case .wai:
            return "哇～"
        case .sugoi:
            return "好厲害～"
        case .tanoshii:
            return "好好玩～"
        case .skill(let skill):
            return "你\(skill)還滿厲害的、你們是朋友唄！！"
        }
    }
}

print([Friends.wai, Friends.sugoi, Friends.tanoshii, Friends.skill("Swift")].map({ $0.message() }).joined(separator: "\n"))
```

アウトプットはこちら

```
哇～
好厲害～
好好玩～
你Swift還滿厲害的、你們是朋友唄！！
```

## 元ネタ

- Kotlin: http://qiita.com/Reyurnible/items/ea852250c651695df5d5
- Swift : http://qiita.com/fromkk/items/0797bdf3923622073a4f
- Java: http://qiita.com/hanakayui0628/items/97242465693bda8cacd2
- PHP: http://qiita.com/t_ishida/items/bae7e62950d81f427f13
- Scala: http://qiita.com/YukiAsu/items/d75b5e16f641c9d4bbf2
- Golang: http://qiita.com/sakajunquality/items/5c4a2dc6967e584193ad
- Ruby: http://qiita.com/844196/items/debc0cd1d39a6c3e32c7
- Python: http://qiita.com/Nao-Y/items/f544a96cbd09b135c7e7
- Bash: http://qiita.com/fk_2000/items/afd5f4ca8f5bb25011c7
タグの検索方法とタグの効果

# タグ一覧

http://qiita.com/tags

検索時に利用できるオプション>タグが付いている

http://help.qiita.com/ja/articles/qiita-search-options

# タグ検索方法
新規登録を使う。
右上の [新規作成] をクリック、または画面左側にある [ノウハウ・Tipsを投稿する] をクリック
タイトル・タグ・投稿欄のタグ欄に文字入力しながら、しばらく待つと登録済みのタグ一覧がでます。

# タグの効果
申し訳ありません。以前？円グラフが出ていたと思います。(2024-11-19)
~~マイページでタグの割合を円グラフで確認できます。~~
http://qiita.com/mrrclb48z
```
$ analyze @mrrclb48z
```
ターミナルの設定


## exitした時にウィンドウを閉じる
シェルの終了時　を設定してあげればOK！


![ターミナル.png](https://qiita-image-store.s3.amazonaws.com/0/10966/741ff4c2-35f7-117b-a790-5f6ec06314ce.png "ターミナル.png")
わーい、すごーい


Kotlinがなかったのと、sealdクラスのいい例だと思ったので投稿。

```kotlin
sealed class KemonoFriends {
    object Wai : KemonoFriends()
    object Sugoi : KemonoFriends()
    object Tanosii : KemonoFriends()
    data class Friends(val skill: String) : KemonoFriends()
    ;
    
    fun say(): String =
        when(this) {
            is KemonoFriends.Wai -> "わーい"
            is KemonoFriends.Sugoi -> "すごーい"
            is KemonoFriends.Tanosii -> "たのしー"
            is KemonoFriends.Friends -> "君は${skill}がとくいな、フレンズなんだね！！"
        }
}

fun main(args: Array<String>) {
    arrayOf(
        KemonoFriends.Wai,
        KemonoFriends.Sugoi,
        KemonoFriends.Tanosii,
        KemonoFriends.Friends("Kotlin")
    )
    .joinToString(separator = "\n") { it.say() }
    .let {
        print(it)
    }
}

/*
わーい
すごーい
たのしー
君はKotlinがとくいな、フレンズなんだね！！
*/

```

## 元ネタ

- Swift : http://qiita.com/fromkk/items/0797bdf3923622073a4f
- Java: http://qiita.com/hanakayui0628/items/97242465693bda8cacd2
- PHP: http://qiita.com/t_ishida/items/bae7e62950d81f427f13
- Scala: http://qiita.com/YukiAsu/items/d75b5e16f641c9d4bbf2
- Golang: http://qiita.com/sakajunquality/items/5c4a2dc6967e584193ad
- Ruby: http://qiita.com/844196/items/debc0cd1d39a6c3e32c7
- Python: http://qiita.com/Nao-Y/items/f544a96cbd09b135c7e7
- Bash: http://qiita.com/fk_2000/items/afd5f4ca8f5bb25011c7
RubyでTrello APIを使う

# 前置き
行事の準備など、複数の工程からなる作業は[Trello](https://trello.com/)のようなタスク管理ツールで把握するのが便利です。[Trello](https://trello.com/)をスクリプトから操作すれば、より一層便利になるでしょう

# 事前調査
先行事例は山ほどあるはずなので、とりあえず適当なキーワードで検索します。

[Trello APIを利用してスクリプトからタスクを管理する](http://qiita.com/AKB428/items/a4a9ff2893affb20f99c)
[ruby-trello gem で API を利用して Trello を操作する](http://qiita.com/tbpgr/items/60fc13aca8afd153e37b)

簡単に見つかりましたね。[ruby-trello](https://github.com/jeremytregunna/ruby-trello)一本でいけそうです。

# OAuth認証
APIを利用するにあたって、認証が必要なのは言うまでもありません。[ruby-trello](https://github.com/jeremytregunna/ruby-trello)では、三種類の認証方式が用意されていますが、今回は[2-legged OAuth authorization](https://github.com/jeremytregunna/ruby-trello#2-legged-oauth-authorization)を使います。必要な情報は開発者向けAPIキー、秘密、トークンの３つ。うち、全社２つは[開発者向けAPIキー](https://trello.com/app-key)で手に入ります。トークンは、次のようなフォーマットのURLで手に入ります。

https://trello.com/1/authorize?key=your_key&name=My+Application&expiration=1day&response_type=token&scope=read,write

しかし、これでは使いにくいですね。'ruby-trello'gemには、この書式のページをデフォルトのブラウザで開くための*Trello.open_authorization_url*メソッドが準備されています。トークンが設定されていない場合は、ブラウザに認可ページを表示させ、トークンをコンソールに入力するようにスクリプトを組めば良いですね。ただし、この手法は[launchy](https://github.com/copiousfreetime/launchy)gemを必要とします。

# 動作環境の準備
```
C:\Sites>mkdir trello
C:\Sites>cd trello
```

```:Gemfile
source 'https://rubygems.org'
gem 'ruby-trello'
gem 'launchy'
```

```
C:\Sites\trello>bundle install
C:\Sites\trello>mkdir config
```

今回は個人のwindows上で実行するコンソールアプリなので、トークンをconfig以下にyamlで保存する予定です。適切な鍵の管理方法を採用してください。

# Rubyスクリプト
出来上がったのが以下のスクリプトです。実行するとボードを作成します。

ハマリポイントもないと思います。せいぜい、トークンをコピペする時に改行コードなどを拾わないようってことと、同じ名前のボードがあると上書きされちゃうくらい。

ドキュメントの2-legged OAuth authorizationの例では、*oauth_token_secret*を設定してますが、なくてもいいですね。

```rb:trello.rb
require 'yaml'
require 'trello'

dir_path = File.dirname(__FILE__)
yaml_file = dir_path + '/config/trello_api.yml'

def make_yaml yaml_file
  Trello.open_public_key_url 
  puts 'ブラウザに表示されるキーを入力してenterを押してください'
  puts 'key:'
  key = gets.gsub(/\n/, '').gsub(/\s/, '')
  puts 'ブラウザに表示される秘密を入力してenterを押してください'
  puts 'secret:'
  secret = gets.gsub(/\n/, '').gsub(/\s/, '')
  Trello.open_authorization_url name: 'RubyExample',key: key, expiration: '30days'
  puts 'ブラウザに表示されるページでAPIの利用を許可してください'
  puts '応答ページに表示されるtokenを入力してenterを押してください'
  puts 'token:'
  token = gets.gsub(/\n/, '').gsub(/\s/, '')
  
  config = {
    consumer_key: key,
    consumer_secret: secret,
    oauth_token: token
  }
  File.open(yaml_file, 'w') {|f| f.write config.to_yaml }
end

make_yaml(yaml_file) unless File.exist?(yaml_file)
api_config = YAML.load_file(yaml_file)

Trello.configure do |config|
  config.consumer_key = api_config[:consumer_key]
  config.consumer_secret = api_config[:consumer_secret]
  config.oauth_token = api_config[:oauth_token]
end

Trello::Board.create(name: 'Ruby Example', description: "Hello, world")
```

実行するとこんな感じです。

```
C:\Sites\trello>bundle exec ruby trello.rb
```
# 文献
もっといろいろやりたい場合は次を参照

[Doc](http://www.rubydoc.info/gems/ruby-trello/Trello)
[trello api reference](https://developers.trello.com/advanced-reference)
秘密鍵と公開鍵を作成する

自分用メモ

```
tonosama$ ssh-keygen -t rsa -b 4096 -C "xxxxxxx@gmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (~/.ssh/id_rsa): ~/.ssh/id_rsa_github
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ~/.ssh/id_rsa_github.
Your public key has been saved in ~/.ssh/id_rsa_github.pub.
The key fingerprint is:
SHA256:peqSA1OHSh4FfRL1mdqBt9ux2X98tkwyfNxTPeoRgDE xxxxxxx@gmail.com
The key's randomart image is:

tonosama$ 


```


<参照>
[【メモ】githubの複数アカウントにSSH接続するための設定手順](http://dev.classmethod.jp/tool/github-ssh-sub-account-setting/,"【メモ】githubの複数アカウントにSSH接続するための設定手順")



```:~/.ssh/config

Host github.com
    HostName        github.com
    IdentityFile    ~/.ssh/id_rsa_github
    User            git
    TCPKeepAlive yes
    IdentitiesOnly yes


```



```:sshでgithubに接続できるか確認する
ssh -T github.com

```
ssh -T Hostで接続できます
nginxのpagespeedでrewrite_javascript,rewrite_cssなどが効かないときに確認すること

ハマりまくったので、メモ

httpsのページでrewrite_*するときは、以下の設定が必要なようだ

```
pagespeed SslCertDirectory /etc/pki/tls/certs;
pagespeed SslCertFile /etc/pki/tls/cert.pem;
```

## 参考
https://modpagespeed.com/doc/https_support
SSH接続でREMOTE HOST IDENTIFICATION HAS CHANGED!

これもよく知られていることと思われますが，自分への備忘録として．

VirtualBox で何度めかに CentOS 7 の仮想マシンを作成．

【環境】
- Mac
- VirtualBox Version 5.0.32 r112930
- CentOS-7-x86_64-Minimal-1511.iso

【参考サイト】
[yk5656 diary: VirtualBoxにCentOS7をインストールしてみる](http://d.hatena.ne.jp/yk5656/20141120/1419172461)

作成後にホストの Mac から SSH を試みると，
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
の警告メッセージ．

```
mac$ ssh developer@192.168.56.101
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:t***M.
Please contact your system administrator.
Add correct host key in /Users/hoge/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/hoge/.ssh/known_hosts:5
ECDSA host key for 192.168.56.101 has changed and you have requested strict checking.
Host key verification failed.
```
解決策はいくつかあるようだが，stack overflow 記事から
[ssh remote host identification has changed](http://stackoverflow.com/questions/20840012/ssh-remote-host-identification-has-changed)

```
ssh-keygen -R <host>
```
を実行．

```
mac$ ssh-keygen -R 192.168.56.101
# Host 192.168.56.101 found: line 5
/Users/hoge/.ssh/known_hosts updated.
Original contents retained as /Users/hoge/.ssh/known_hosts.old
```
再度 SSH を試みて，

```
mac$ ssh developer@192.168.56.101
The authenticity of host '192.168.56.101 (192.168.56.101)' can't be established.
ECDSA key fingerprint is SHA256:t***M.
Are you sure you want to continue connecting (yes/no)?
```
yes と答え，

```
Warning: Permanently added '192.168.56.101' (ECDSA) to the list of known hosts.
developer@192.168.56.101's password: 
```
PW 入力で，接続〜ログインできた．
NumPyで慣性テンソルから慣性主軸と主慣性モーメントを求める

慣性テンソルから慣性主軸と主慣性モーメント求めるには行列の対角化という操作を行う。
対角化のプログラムを書くのはかなり大変だと思うけど、NumPyを使うことで案外簡単に求めることができる。
理論的な話は他で読んでもらうことにして、NumPyを使った計算の手順だけを説明する。
#### 参考：
[慣性モーメント - Wikipedia](https://ja.wikipedia.org/wiki/%E6%85%A3%E6%80%A7%E3%83%A2%E3%83%BC%E3%83%A1%E3%83%B3%E3%83%88#.E6.85.A3.E6.80.A7.E4.B8.BB.E8.BB.B8.E3.81.A8.E4.B8.BB.E6.85.A3.E6.80.A7.E3.83.A2.E3.83.BC.E3.83.A1.E3.83.B3.E3.83.88)
[慣性テンソルの座標変換](http://www.kumst.kyoto-u.ac.jp/kougi/mechanics/appendix2.pdf)

## 計算手順
1. 慣性テンソルを表す行列$I$を作る。
2. numpy.linalg.eigで固有値と固有ベクトルを束ねた行列$P$を求める。
3. 行列$P$を使って慣性テンソル$I$を対角化する。（省略可）

## 0. 準備
NumPyの出力を読みやすいように設定しておく。
ここでは小数点以下４桁で固定して表示するように設定する。

```py3
import numpy as np
np.set_printoptions(precision=4, suppress=True)
```
特に極小の値の読みやすさが大きく違ってくる。
`-2.86013404e-15`　→　`0.`


## 1. 慣性テンソルを表す行列_I_を作る。
慣性テンソルを表す行列をndarrayとして定義する。
ただし慣性テンソルは対称行列なので、対称になるように。

```py3
I = np.array([[30, 5, 5],
              [5, 20, 5],
              [5, 5, 10]])
print(I)
```
```:output
[[30  5  5]
 [ 5 20  5]
 [ 5  5 10]]
```

## 2. numpy.linalg.eigで固有値と固有ベクトルを束ねた行列_P_を求める。
numpy.linalg.eigは固有値と固有ベクトルを求める関数。
これを使って主慣性モーメントと慣性主軸を求めることができる。

```py3
I_p, P = np.linalg.eig(I)
print('主慣性モーメント: \n', I_p)
print('慣性主軸: \n', P.T)
```
```:output
主慣性モーメント: 
 [ 33.8923  18.5542   7.5536]
慣性主軸: 
 [[ 0.8716  0.4103  0.2683]
 [ 0.4706 -0.8535 -0.2238]
 [-0.1371 -0.3213  0.937 ]]
```
１つ目の戻り値は固有値の配列。これが主慣性モーメントとなる。
２つ目の戻り値は３つの固有ベクトルを列ベクトルとして並べたもので、それぞれのベクトルが慣性主軸となる。
行ベクトルの方が見た目としてわかりやすいので転置して出力している。


## 3. 行列_P_を使って慣性テンソル_I_を対角化する。（省略可）
すでに必要なものは得られているが、対角化によって主慣性モーメントが得られることを確認してみる。
慣性テンソル$I$を行列$P$を使って対角化すると主慣性モーメントを得られる。
主慣性モーメントの対角行列 = $P^{-1} I P$
参考：[対角化 \- Wikipedia](https://ja.wikipedia.org/wiki/%E5%AF%BE%E8%A7%92%E5%8C%96)

numpy.linalg.invは逆行列を求める関数。
`@`演算子は行列の積を表す。（NumPyでは`*`演算子は要素どうしの積になることに注意。）

```py3
I_p = np.linalg.inv(P) @ I @ P
print(I_p)
```
```:output
[[ 33.8923  -0.       0.    ]
 [ -0.      18.5542   0.    ]
 [ -0.      -0.       7.5536]]
```

これで得られた対角成分が主慣性モーメント。
diag関数を使うと対角成分だけを取り出せる。

```py3
print(np.diag(I_p))
```
```:output
[ 33.8923  18.5542   7.5536]
```

### 注意事項
行列の積を計算する`@`演算子が使えるのはPython 3.5以降なので、Python 3.4以前のバージョンでは代わりにnumpy.dot関数を使う。
iPhoneのuserAgentが全て小文字に変わった？

userAgentをみてスマホはスマホのページに飛ばすという、
レスポンシブ未対応のサイトでの話です。

今まで　.htaccess　で飛ばしていたのですが、
昨日iPhoneで見たら飛んでいない。

？？？

PHPで飛ばしてしまおうと、コードを追加するも、
飛ばない。

$_SERVER['HTTP_USER_AGENT']　を画面に表示してわかったのが、

機種名が iPhone ではなく　iphone となっていこと。

iPhone　という文字列と比較しているから、
これでは飛ばない。

PHPの方で　strtolower()　を使って、小文字にしてから、
小文字の　iPhone と比較するようにして、
無事飛ぶようになった。

自分のiPhoneだけかなぁ？
GitHubでテンプレートを作成する


GitHub上で使用する、Issues及びPull Requestsのテンプレートを登録することができる！
下記に作成方法を記載していきます！

##Issuesテンプレートを作成する  
  
リポジトリのルートディレクトリまたは`.github`ディレクトリ内に`ISSUE_TEMPLATE.md`という名前のファイルを作成する。(拡張子はつけなくてもよい)  
  
作成した`ISSUE_TEMPLATE.md`にマークダウン形式でテンプレートとして仕様したい内容を記述する。

![スクリーンショット 2017-02-11 14.37.34.png](https://qiita-image-store.s3.amazonaws.com/0/128479/a9f4cabf-f8b5-738b-a0fb-093745c5d61d.png "スクリーンショット 2017-02-11 14.37.34.png")

  

書き終えたらコミット！

IssuesタブでNew issueを押下する  
  
![スクリーンショット 2017-02-11 14.41.58.png](https://qiita-image-store.s3.amazonaws.com/0/128479/f1fe2658-794d-8731-ddee-11cb04fb49cd.png "スクリーンショット 2017-02-11 14.41.58.png")

  
先ほど記述したテンプレートが適応されていればOK!
  
##Pull Requestsテンプレートを作成する  
  
Issuesテンプレート作成時と同様の手順で作成できます！  
  
リポジトリのルートディレクトリまたは`.github`ディレクトリ内に`PULL_REQUEST_TEMPLATE.md`という名前のファイルを作成する。(拡張子はつけなくてもよい)  
  
作成した`PULL_REQUEST_TEMPLATE.md`にマークダウン形式でテンプレートとして使用したい内容を記述する。

![スクリーンショット 2017-02-11 14.46.06.png](https://qiita-image-store.s3.amazonaws.com/0/128479/ef5445ec-446e-11d1-7601-c9e981bc3dad.png "スクリーンショット 2017-02-11 14.46.06.png")
書き終えたらコミット！
  
pull requestを作成できる状態で、
CodeタブでCompare & pull requestを押下する  
![スクリーンショット 2017-02-11 14.58.32.png](https://qiita-image-store.s3.amazonaws.com/0/128479/59e37ffd-f427-9391-570f-1207fe6e123f.png "スクリーンショット 2017-02-11 14.58.32.png")


  
先ほど記述したテンプレートが適応されていればOK!  
  
  
#おわりに

すごく簡単ですね笑
IssueやPull requestは人によって書き方がバラバラだったりするので、フォーマットが統一されていた方が見易いですよね！  
フォーマットがしっかりしていれば、対応漏れなども回避できると思います！

ただ、このテンプレート機能はIssueで一つ、Pull requestで一つしか作成できないので、「バグ報告」の場合にはこのテンプレート、「タスク」の場合にはこのテンプレートレートを使いたい！などという運用方法はできません。

その点を補っている良い記事がQiitaにありましたので参考に貼らせていただきました。  
  
#参考
[http://qiita.com/yoshimikeisui/items/3e1873e3bf1bbafe8733](http://qiita.com/yoshimikeisui/items/3e1873e3bf1bbafe8733)
Raspberry Pi > 動体を検知したら、"Rear Center"という音声を流す

```txt:動作環境
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
```

## 概要

Motionを使って動体を検知して、検知時になんらかの音声を流す。

## 準備

### soundの準備

http://qiita.com/7of9/items/1f3c9253985ece8160b2

### カメラの準備

http://qiita.com/7of9/items/fe5937ea9f3384a98fae

## セットアップ

### Motion

参考 http://qiita.com/kinpira/items/bf1df2c1983ba79ba455

イベントはon_picture_saveを使用。

```/etc/motion/motion.conf
; on_picture_save value
on_picture_save python /home/pi/MOTION/say_170211.py
```

say_170211.pyの実装は後述。

### 音声

音声を流す方法は以下を参考にしました。
http://qiita.com/plsplsme/items/57b8d79d3725497fd69b

> 
```
#wavテスト
aplay /usr/share/sounds/alsa/Rear_Center.wav
```

上記のaplayをbashで実行しようとしたところ、not foundなどなり失敗。
そのため、pythonからコマンド実行で音声を流すようにした。

コマンド実行は以下を参考にしました。
http://takuya-1st.hatenablog.jp/entry/2014/08/23/022031

### code

```/home/pi/MOTION/say_170211.py
#!/usr/bin/env python
import subprocess
print("hello")
cmd = "aplay /usr/share/sounds/alsa/Rear_Center.wav"
subprocess.call( cmd, shell=True )
```

### Motion起動

```
$sudo motion -c /etc/motion/motion.conf
```

以上で動体を検知するたびに”Rear Center"と音声が流れるようになった。
Unityでウディタのキャラクタ画像の向きと3Dオブジェクトの回転を連携させる

[前回](http://qiita.com/tak/items/f4b60014012ece2bc311)、せっかくウディタ画像を利用できるようになったので、3D空間内でいいかんじに向き変更をやってみようと思う。

# カメラを回転させる
オブジェクトを回転させる方法はいくつかあるようだけれど、今回は回転用のオブジェクトとカメラを別のオブジェクトにすることで責務の分担を試みる。
以下のように、Pivotオブジェクトを作って回転用スクリプト(Rotator)を新規作成、Pivotの子要素にカメラを置く。

![image](https://qiita-image-store.s3.amazonaws.com/0/162289/807cca21-c686-6df4-b9b3-4884dd49c07e.png)

``` C#:Rotator.cs
using UnityEngine;

public class Rotator : MonoBehaviour {
    void Update () {
        gameObject.transform.Rotate(new Vector3(0f, 1f));
    }
}
```
結果。3Dと2Dの融合した不思議な世界。
![elfsan.gif](https://qiita-image-store.s3.amazonaws.com/0/162289/25422d14-769c-22c4-02f9-4b715664e227.gif)

# スプライトの向きをオブジェクトに追随させる
次にスプライトがカメラに対して正面（というと変な言い方だけど）を向けるようにする。
これは超簡単。下のようなスクリプトをSpriteにアタッチして、TargetにさっきのPivotオブジェクトを指定すればいい。

``` C#:DirectionFollower.cs
using UnityEngine;
public class DirectionFollower : MonoBehaviour {
    public GameObject Target;
	// Update is called once per frame
	void Update () {
        gameObject.transform.rotation = Target.transform.rotation;
	}
}
```

こうなる。
![elfsan.gif](https://qiita-image-store.s3.amazonaws.com/0/162289/764acd6d-75a0-3066-8d40-a4fa4d6429ad.gif)

# オブジェクトのrotateからキャラクタの向きを算出する
あとは前回のスクリプトに手を加えて、向きによって画像が変わるようにすればOK。

``` C#:DirectionalSprite.cs
using UnityEngine;

public class DirectionalSprite : MonoBehaviour
{

    public enum Directions { N = 18, S = 0, E = 12, W = 6, NW = 15, NE = 21, SW = 3, SE = 9 }
    //
    public string Name;
    public SpriteRenderer SpriteRenderer;
    public Directions Direction;
    //
    private string _lastSpriteName = "";
    private Sprite[] _subsprites;
    // 
    void Start() {
        SetName(Name);
    }
    void LateUpdate() {
        // 現在のスプライトを得る
        string name = SpriteRenderer.sprite.name;
        // 向きが変化したか、スプライトが変化したならば画像を変更
        if (Compute2DDirection() == true || _lastSpriteName != name) {
            int idx = name.IndexOf('_');
            if (idx >= 0) {
                int id = int.Parse(name.Substring(idx + 1)) + (int)(Direction);
                SpriteRenderer.sprite = _subsprites[id];
            }
            _lastSpriteName = SpriteRenderer.sprite.name;
        }
    }
    // 名前からスプライトを作成
    public void SetName(string name) {
        Name = name;
        _subsprites = Resources.LoadAll<Sprite>("Units/" + name);
    }
    // 角度ごとの向き
    static readonly Directions[] dlist = {
        Directions.N, Directions.NW, Directions.W, Directions.SW,
        Directions.S, Directions.SE, Directions.E, Directions.NE };
    // Directionを算出する
    bool Compute2DDirection() {
        int idx = (int)(((transform.rotation.eulerAngles.y + 22.5f + 360f) % 360f) / 45f);
        bool return_val = (Direction != dlist[idx] ? true : false);
        Direction = dlist[idx];
        return return_val;
    }
}
```

こんな感じ。これはあくまでカメラの角度に追随しているだけなので、ゲームで動かすならさらにキャラクタの向きの情報を足しこむ必要がある。
![elfsan.gif](https://qiita-image-store.s3.amazonaws.com/0/162289/6d5df807-e6d6-0682-bddb-d6c016b2b970.gif)
初めてのGulp入門 ~gulpfile入門~


##前提条件

下記はすでにインストールと仮定

- gulp

また、下記の記事を完了していることを想定

http://qiita.com/y_sekitoba/private/ca8f582dbf437afdbf1d


##プラグインの利用とgulpfileの書き方

今回は、「gulp-sass」というプラグインを利用してインストールからgulpfileの書き方を説明していきます。

前回の記事が完了している方は、gulpfile.jsというファイル(中身は空)は作成済みのはずですので、ここに設定を記述しながら実際にgulp-sassプラグインを利用できるようにしていきましょう。

###◆gulp-sassプラグインとは？


##下準備

今回、gulp-sassプラグインを実際に利用するために下準備を行います。

###◆HTMLファイルの作成

下記のコマンドを実行してファイルを作成。

```
// publicというディレクトリを作成
$ mkdir public

// publicディレクトリの中にindex.htmlファイルを作成
$ touch public/index.html
```

作成したindex.htmlというファイルに下記を貼り付け

```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>エフゼロ勉強会</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
   <h1>エフゼロ勉強会</h1>
</body>
</html>
```

これで事前準備は終了です。


##プラグインのインストール

ではまずは今回利用するgulp-sassプラグインをインストールしていきます。

インストールは下記のコマンドを実行すれば完了です。
※前回gulpをインストールしたディレクトリ(gulp_lessonディレクトリ)にいる前提です。

```
// npmを利用してgulp-sassをインストールする
$ npm install gulp-sass
```


##gulpfile.jsに設定を記述

gulp-sassプラグインを利用できるようにgulpfile.jsに設定を記述してきます。

```gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');

// sassコンパイルタスク
gulp.task('sass-compile', function(){
  return gulp.src('./dev/style.scss')
    .pipe(sass.sync().on('error', sass.logError))
    .pipe(gulp.dest('./public/style.css'));
});

// gulpのデフォルトタスクとしてsass-compaileタスクを指定
gulp.task('default', ['sass-compile']);

```

上記を記述後、保存してください。
※詳しい説明は後半でしています。


##scssファイルの作成

では実際に、gulp-sassプラグインを利用してsassファイルをcssファイルに変換してみましょう。

まずsassファイルを作成します。

```
// devというディレクトリを作成
$ mkdir dev

// devディレクトリの中にindex.htmlファイルを作成
$ touch dev/style.scss
```

作成したstyle.scssファイルの中に書きを記述

```style.scss
body {
	background-color: red;
	
	& h1 {
		color: bule;
	}
}
```


##実行

最後にgulpを利用してsassファイルをcssに変換してみましょう。

下記のコマンドを実行してください。

```
$ gulp
```

これでgulpとgulp-sassを利用できるようになりました。
ただ、現状ではgulpのよさを実感できないのでより実務に使える形にしていきます。


##プラグインを追加していく

ここまでで作成したファイルをさらに便利にしていきましょう。

現状、下記のパッケージが入っています。

- gulp
- gulp-sass

ここではさらに便利にしていくために下記のパッケージを導入します。

- gulp-autoprefixer =>
- gulp-csscomb =>
- gulp-plumber =>
- browser-sync =>


###◆パッケージのインストール

まずはnpmを利用してパッケージをインストールして使用できるようにしていきます。

```
// npmを利用してインストール(半角スペースを入れることで複数をまとめて指定することも可能)
$ npm install gulp-autoprefixer gulp-csscomb gulp-plumber browser-sync
```


###◆gulpfile.jsのカスタマイズ

パッケージのインストールが完了したので実際に利用できるようにgulpfile.jsをカスタマイズしていきます。
最終的に下記のようになります。

```gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var csscomb = require('gulp-csscomb');
var plumber = require('gulp-plumber');
var browser = require('browser-sync');


// sassコンパイルタスク
gulp.task('sass-compile', function(){
  return gulp.src('./dev/style.scss')
    .pipe(sass.sync().on('error', sass.logError))
    .pipe(gulp.dest('./public/style.css'));
});

// gulpのデフォルトタスクとしてsass-compaileタスクを指定
gulp.task('default', ['sass-compile']);


```

では少しづつ解説していきます。
ポイントを押さえてしまえばある程度カスタマイズができるようになりますので少しづつ慣れていきましょう。



##こちらもどうぞ
[新人の指導者 or 新人の方へ](http://qiita.com/y_sekitoba/private/89e421c5e2b28dfe5dfb)
Chrome拡張機能のソースが丸見えな件。

Chrome拡張機能を公開したことがあるので、気になって他の拡張機能も調べていたらなんと！公開したソースコードは丸見えなんだって。
暗号化もなにもされていなくて、そのままフォルダがコピーされているだけ。

これは驚いた。

拡張機能の中身すべてを見られるようにしているサイトがある。
[Chrome Extensions Archive](https://crx.dam.io/ "Chrome Extensions Archive")
![Chrome Extensions Archive](https://i2.wp.com/mycodeoutput.com/wp-content/uploads/2017/02/ss.png?w=763)

ここのサイトではわざわざインストールしなくても見れるようにしてあるし、ソースをzipでダウンロードできる。


また、インストールして直接見る方法もある。

 ![Chrome Extensions adblock](https://i0.wp.com/mycodeoutput.com/wp-content/uploads/2017/02/url-1.png?w=637)
これはchromeウェブストアのadblockのページのURL。

赤枠部分をコピーしておいて、拡張機能をインストールする。
windowsの場合は「%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Extensions\」に拡張機能がインストールされる。
ここに先程、赤枠で囲った文字列でフォルダが作られる。
![ss1.png](https://qiita-image-store.s3.amazonaws.com/0/72949/e27b0971-37cf-e7e7-dd71-b8db202156e4.png)

覗いてみると、暗号化も何もされてない素の.jsファイルやjsonファイルがある。
![ss2.png](https://qiita-image-store.s3.amazonaws.com/0/72949/0af299f4-e72d-df8a-1dae-8e625823edbd.png)


これでは悪意のある人からしたらパクリし放題。これではいくらまともに拡張機能の作っても簡単に真似されてしまう。有料で販売するのはキツイなあ。
拡張機能内にアフィリエイトを含めてクリックさせる方向に持っていくしかないね。
Reactが用意しているライフサイクルメソッド7つ

Reactのライフサイクルメソッドを学んだのでメモ

## componentWillmount
「[マウント](http://e-words.jp/w/%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88.html)される直前に1回だけ呼ばれる」
- 初期化処理を行うのに適している
- コンポーネントがDOMツリーに追加される前に1度だけ呼ばれる
- このメソッド内でsetstate()するとrender時にまとめて行われる

## componentDidMount
「マウントされた直後に1回だけ呼ばれる」
- DOMに関わる初期処理を行いたい時に便利
- コンポーネントがDOMツリーに追加された状態で呼ばれる

## componentWillReceiveProps
「コンポーネントがプロパティの値を受けるときに呼ばれる」
- プロパティが更新されるときに呼ばれる
- 親コンポーネントのStateがPropsとして渡されていて、その変化で(表示以外で)何かしたいときに便利

## shouldComponentUpdate
「コンポーネントを更新してもいいかどうかの判断を行う」
- 戻り値は「True」または「False」
- 無駄な処理を無くし、パフォーマンスの向上を行うときに便利

## componentWillUpdate
「コンポーネントが更新される前に呼ばれる」
- shouldComponentの戻り値がtrueの場合呼ばれる

## componentDidUpdate
「コンポーネントが更新された後に呼ばれる」
- DOMの変化にフックして何かしたい場合に使うと便利

## componentWillUnmount
「コンポーネントがアンマウントする前に呼ばれる」
- コンポーネントがDOMから削除される時に呼ばれる
- Timerの処理やDOMのイベントを解除するときはここで処理をかいておく
Generate Apple Push Service Certificate

The way to prepare for the Apple Push Service certificate is simple as following. You are supposed to be one had done all needed procedures before you start, including but not limited to apply an App ID, request certificate and download it, import the certificate into the KeyChain and then export it out as P12 format.

## Preparation

Three files you would hold after you generated and submitted the Apple Push Service Certificate, and exported them from KeyChains.

> CertificateSigningRequest.certSigningRequest

The certificate file signing request file, put it away.

> PushLib_CerKey.p12

The P12 format package containing certificate and its key.

> aps_development_PushLib.cer

The downloaded APS certificate file.

## Generate Certificate PEM

Use the APS certificate file to generate certificate PEM file in x509 der form.

```bash
openssl x509 -in aps_development_PushLib.cer -inform der -out PushLibCert.pem
```

## Generate Key PEM


Use the P12 CerKey file to generate Key PEM file. You need to enter import password, and set thge PEM pass phrase.

```bash
openssl pkcs12 -nocerts -out PushLibKey.pem -in PushLib_CerKey.p12 
```

This time interactivity is needed for security.

```bash
Enter Import Password: [THE PASSWORD YOU HAVE SET FOR P12]
MAC verified OK
Enter PEM pass phrase: [PASS PHRASE YOU SET]
Verifying - Enter PEM pass phrase: [PASS PHRASE YOU SET, AGAIN]
```

## Generate Integrated Cert&Key PEM

Integrate the two generated PEM files into one. The result PEM file is used for connect Apple Push Service Server.

```bash
cat PushLibCert.pem PushLibKey.pem > PushLibDuoCK.pem
```

----
[自分のブログから移転してきたものである。](http://www.everstray.com/news/news.php?newsCode=MjAxNTAyMjcyMTQ4NTZbR2VuZXJhdGUgQXBwbGUgUHVzaCBTZXJ2aWNlIENlcnRpZmljYXRlXUV2ZXJzdHJheS5sb2c%3D)
Node.jsでLINE Beaconの最初の一歩のミニマムコードを書いてみる #botawards


![](https://i.gyazo.com/c742d829f54d93003297ca5185a19d61.png)

LINE Beaconを初めて使う時ってMassaging APIの仕様もわからずBeaconの仕様もわからず、反応してくれないけどどこに原因があるのか分かりにくいですね。

* LINEのビジネスアカウント(BOTアカウント)を作成
* ビジネスアカウントにBeaconを紐づける
    * https://manager.line.biz/beacon/register
* 手元のLINEのアプリの設定 > プライバシー管理 > ビーコン利用をオンに
* LINE Beaconの電源をオンに
* ngrokなどでトンネリングする
* トンネリングサーバーのhttpsアドレスをlinedevelopersに登録する
* プログラムを作り起動する

など手順がありますが、最後のプログラム部分はサクッとログを出すためし方をするとハマらなくて良さそうです。

```app.js
'use strict';

const http = require('http');
const PORT = process.env.PORT || 3000;

http.createServer((req, res) => {    
    if(req.url !== '/' || req.method !== 'POST'){
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('hello');
    }

    let body = '';
    req.on('data', (chunk) => {
        body += chunk;
    });        
    req.on('end', () => {
        if(body === ''){
          console.log('bodyが空です。');
          return;
        }

        let WebhookEventObject = JSON.parse(body).events[0];  
        if(WebhookEventObject.type === 'beacon'){
            console.log('beacon発見');
            console.log(WebhookEventObject);
            return;
        }  
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('success');
    });

}).listen(PORT);

console.log(`Server running at ${PORT}`);
```

起動させる

```bash
$ node app.js
Server running at 3000
```

ここで、LINEのアプリを再起動させたりすると反応があると思います。

```
beacon発見
{ type: 'beacon',
  replyToken: 'xxxxxxxxxxxxxxxxxxxxxxx',
  source: { userId: 'xxxxxxxxxxxxxxxxxxxxxx', type: 'user' },
  timestamp: 1486789863718,
  beacon: { hwid: 'xxxxxxxxxx', type: 'enter' } }
```

LINE Beaconの検知はアプリのバックグラウンドでも動作する想定っぽいのですが僕の手元だとこのやり方が一番結果が返ってきます。

本当にログを出すだけなので、ここから発言させたり他のAPIを使う時は認証情報を使いましょう。
BarとViewのコンテンツの高さについて

iOS 7からUINavigationControllerの中のUIViewControllerでViewに当てるUIScrollViewはそのコンテンツをBarの高さの程度で下げます。解決する策としては、以下のコードはかなり有名かもしれません。

	- (void)viewDidLoad{
	    [super viewDidLoad];
	    // iOS7以上の場合
	    if ([[[UIDevice currentDevice]systemVersion]floatValue]>=7.0) {
	        // 拡張レイアウトのエッジをクリア
	        self.edgesForExtendedLayout = UIRectEdgeNone;
	        // 不透明バーが拡張レイアウトに含まれない
	        self.extendedLayoutIncludesOpaqueBars = NO;
	        // ScrollViewのインセット自動調整をしない
	        self.automaticallyAdjustsScrollViewInsets = NO;
	    }
	}

qiitaで読んだ[やはりお前らのiOS7対応は間違っている(解説編)](http://qiita.com/yimajo/items/254c7cebab7864678246)という文章が詳しく解説してくれて助かります。Storyboard使えるならStoryboardで設定するのがオススメです、と言われましたけど、私は先輩に全てのことをコードで始末するという癖を染みられてしまいました。ならば、コードの意味をはっきりにすることはできる限りやらせてもらおう。

具体的にいうと、View Controllerの中身のViewは状況によって、上のNavigation Barと下のTab Barの下に潜り込むことが初期設定です。実はそのViewの潜り込むことは二つのBarに分けて、論理的に四つの設定が可能です。本質的なことはその結果的な効果によって、Barの下に潜り込んだViewの部分の色はその上にガラス効果を持ちます。しかし、Table ViewとしてYの値は0からですので、処理もせずにそのまま展示すると、0番目のアイテムはBarに隠されます。そのために、スクロールを支援するView、すなわちUIScrollViewを利用するものは、初期設定でそのコンテンツをBarの高さの程度で下げます。その二つの機能以外、Barが半透明ではない場合には、潜り込むかどうかは設定できます。

考えると、今までそのiOS 7の新しいUIに対応することはよくわからないままでとりあえず正しく展示させることだけを求めていました。反省することも必要ですが、中国語のIT圏でそんな資料は大体コピーしたもので、あるいは結果論ばかりで、皆よくわからないけど役に立てばいいじゃないという態度で技術をやっています。もっと明らかな例は、今まで面接官をやった経験として、接したものは大体アウトソーシング企業出身で、その態度は常態みたいです。最近ようやくそれを認識して、グーグルの言語を日本語に切り替えてしまいました。

----
[自分のブログから移転してきたものです。](http://www.everstray.com/news/news.php?newsCode=MjAxNDEyMTIwMDI5Mzdb5pu05paw57aa44GR44KLaU9T44GL44KJ5aeL44G%2B44KL5paw44GX44GE6K2w6aGMXUV2ZXJzdHJheS5sb2c%3D)
TeraTermのショートカットを作成し、ダブルクリックだけで公開鍵方式のSSH接続

自分用備忘録も兼ねて。

管理するサーバ数が増えてくると、いちいち接続のたびにTeraTermを開いて、接続先とユーザ名、パスワード、鍵を設定するのが
めんどいので、ショートカットを作ってダブルクリックするだけで接続するようにする。

TeraTermのヘルプを開くと、様々なオプションがあり、、、、、、、
そのあたりの説明もめんどいので割愛

基本的には

ttermpro.exeパス 接続先ホスト  /ssh2 /auth=publickey /user=ユーザ名 /password=パスワード /keyfile=秘密鍵 


なショートカットを作ればできます。

|項目|値|
|--:|--:|
|接続先ホスト|192.168.0.1|
|ユーザ名|hogehoge|
|パスワード|hoge123456|
|秘密鍵|C:&yen;key&yen;id_rsa|

の場合

"C:&yen;Program Files (x86)&yen;teraterm&yen;ttermpro.exe" 192.168.0.1 /ssh2 /auth=publickey /user=hogehoge　/passwd=hoge123456 /keyfile=C:&yen;key&yen;id_rsa


な感じでショートカットを作ります。

パスワードは入れたくないわあという場合は　/passwdを/ask4passwdに変えれば接続時パスワードを聞いてきます。

"C:&yen;Program Files (x86)&yen;teraterm&yen;ttermpro.exe" 192.168.0.1 /ssh2 /auth=publickey /user=hogehoge　/ask4passwd /keyfile=C:&yen;key&yen;id_rsa
Jupyter Notebookのログイントークン

# Jupyter Notebookの起動画面にログイントークン
どうも最新のJupyter Notebookでは起動画面でログイントークンが必要になったようです。

![2017-02-11_jp2.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/37abe130-8e5f-ab1e-2237-f87a67f15cea.png)



ログイントークンはシェルでJupyter Notebookを起動した時に表示されます。

![2017-02-11_jp.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/94662210-5b42-3827-a348-bac9c34eadb7.png)

http://localhost:8888/?token=282d5a11368c4b36f1db8ad888f9c33a61ae83b81ff7ae6c

このtokern=以降をコピペすればログインできます。
初めてのGulp入門 ~インストール編~


##前提条件

下記はすでにインストールしていると仮定

- npm

また、下記の記事を完了していることを想定
http://qiita.com/y_sekitoba/private/f0d50afe3884bd22f6d5

##Gulpとは?

Gulpを簡単に言うと「面倒な作業を自動化するもの」です。

具体的には下記のようなことを自動で実行することが可能です。
※下記はあくまでGulpで自動化できることのほんの一部です

- CSS、JavaScript、画像、などの様々なファイルを自動で圧縮
- CSSプリプロセッサと言われるSASS、LESS、Stylusなどを自動で通常のCSSに変換(コンパイル)
- 作業中にファイルが更新されたら自動でブラウザを更新して最新の画面を表示

上記のようなことはもちろん手動でもできます。
しかし、Gulpを導入することでそれらを全て自動化することで作業の効率化が図れます。


##下準備

これからGulpをインストールしていきますが、その前に下準備をしていきます。

まずは下記のコマンドを実行して`package.json`というファイルを作成します。

```
// 今回作業するディレクトリを作成
$ mkdir gulp_lesson

// 該当ディレクトリへ移動
$ cd gulp_lesson

// package.jsonを作成
$ npm init -y
```

これで、`package.json`の作成が完了しました。

###◆package.jsonとは?

package.jsonとは簡単に言うと「プロジェクトでどんなパッケージを使用しているかを記述しているファイル」です。
詳しい使い方は今回は割愛しますが、このファイルを利用することで複数人で同じ環境で作業することを容易にできるようになります。

その他にも使い方は数多くありますので、気になる方は調べてみてください。
今回は、こういうものがあるという認識だけ持っていただければ大丈夫です。


##Gulpのインストール

では早速、Gulpをインストールするところまで説明していきます。

インストールには下記の3ステップを実行することで完了します。
※公式を参照

```
// ステップ1
$ npm install gulp-cli -g

// ステップ2
$ npm install gulp -D

// ステップ3
$ touch gulpfile.js
```

では、上記で何をしているのかを説明していきます。
※npmのオプションやグローバルインストールに関しては下記のページを参照してください。
http://qiita.com/y_sekitoba/private/f0d50afe3884bd22f6d5


###◆ステップ1

ステップ1では下記のコマンドを実行しています。
※このステップは最初の1回のみ実行すればOKです。

```
$ npm install gulp-cli -g
```

これは、npm(ノードパッケージマネージャ)を利用して「gulp-cli」というパッケージをグローバルインストールしています。

gulp-cliというパッケージに関してはおまじないのようなものとして覚えておいていただく程度で大丈夫です。

※実際にはgulp-cliというパッケージの主な機能はnode_modules配下のgulpコマンドへパスを通すということをしています。気になる方はご自身でも色々調べてみてください。

[gulp-cliのページへ](https://www.npmjs.com/package/gulp-cli)


###◆ステップ2

ステップ2では下記のコマンドを実行しています。
※今回のディレクトリ以外でもGulpを利用したい場合はこのステップから始めてください。

```
$ npm install gulp -D
```

これは、npm(ノードパッケージマネージャ)を利用して「gulp」というパッケージを`-D`オプションを利用して対象のディレクトリにインスートルしています。

下記のコマンドを実行してGulpのインストールが成功しているか確認します。

```
// 下記のコマンドでバージョンの情報などが表示されればOK
$ gulp -v
```

これで、対象のディレクトリにGulpのインストールが完了しました。

####補足

ネット上でGulpのインストール系の記事を探すと下記のようにしているものも出てきますが、現在Gulpの公式ページでは今回のインストールの仕方が掲載されています。

```
$ npm install -g gulp
```

上記のコマンドは、「 ***Gulpパッケージそのものをグローバルインストールする*** 」という方法を取っています。
この方法でもGulpを利用することはできますが、諸々と問題が発生することが多いです。


###◆ステップ3

ステップ3では下記のコマンドを実行しています。

```
$ touch gulpfile.js
```

これは、`touch`コマンドを利用して「gulpfile.js」というgulpの設定ファイルを作成しています。

ここで作成した、「gulpfile.js」にはGulpの設定を記述していきます。


##Gulpを実際に利用するには？

現状、Gulpパッケージのインストールが完了している状態のはずです。

ここからは、プラグインというものを利用してGulpで作業(タスク)の自動化をしていきます。
※Gulp単体では最初に説明した自動化を実行することができません。

実際に、[次回](http://qiita.com/y_sekitoba/private/363eae906925ada83289)では「gulp-sass」というプラグインを利用しながらgulpfile.jsの書き方なども説明していきます。



##こちらもどうぞ
[新人の指導者 or 新人の方へ](http://qiita.com/y_sekitoba/private/89e421c5e2b28dfe5dfb)