OmniAICreator/Qiita-1.07M huggingface dataset:
もう保守されない画面遷移図は嫌なので、UI Flow図を簡単にマークダウンぽく書くエディタ作った




![Kobito.vi0PwG.png](https://qiita-image-store.s3.amazonaws.com/0/35671/cd6d855a-e71c-52e6-a5ce-95e279e5ac44.png "Kobito.vi0PwG.png")


# はじめに

Webサービスやアプリを企画したり、立ち上げたりする際にプロトタイピングツールや、ExcelやPowerpoint、Illustraterなどを駆使した謎のファイルで画面遷移図を描くことがある。

こういう図を元に仕様を決めて行って、サービスを作っていくのは以下の点で困る。

+ 画面遷移図が保守されない。
+ 書くのが非常に面倒くさい
+ ユーザーのモチベーションの流れが追いづらく、見た目ばかりに注目してしまうものになりがち
+ マシンリーダブル(ソフトウェアで構造を取り出せない)でない。

このような欠点があってどうにも扱いづらい。

そんなわけで、markdown風のテキストから簡単に画面遷移図を描けないかなとコンパイラを作成し、次にそれをインタラクティブに編集できるエディタを作成した。

# UI Flows図について

画面遷移図的なものを書く際に、僕が個人的につかっていた表現方法として、UI Flowsというのがある。これは``Ruby on Rails``を生み出したことで有名な[37signalsのブログ](https://signalvnoise.com/posts/1926-a-shorthand-for-designing-ui-flows)で紹介された技法だ。

それは次のように：
![Kobito.WRduWM.png](https://qiita-image-store.s3.amazonaws.com/0/35671/8146cf0a-3e1a-78f9-e1da-6771b452548d.png "Kobito.WRduWM.png")

「ユーザーが見るもの」とそれにともなって起こせる「ユーザーがすること」を連鎖させて、画面遷移を作るというシンプルなものだ。

余計な情報がないので、「動機」と「行動」の連鎖が明確でないような画面を発見しやすい。また、小さく納まるので一覧性が高い。

# uiflow コンパイラについて

UI Flowsを既存のツールで書くのは非常に面倒くさい。図が大きくなってくるとレイアウトも気になるし、表現が多彩にできる分必要以上に「画面の要素」を意識してしまう。そうすると情報設計の粒度とグラフィックデザインの粒度が一緒くたになってしまい、かえって混乱をきたしてしまう。

そこで、シンプルな記法たとえばマークダウンのようなものでこれを記述できれば、githubでも管理できるし、画像に変換する前の構造情報を吐き出せば、画面の構造をプログラムが知ることができて、いろいろ使い勝手がいいだろうと考えた。



```

[page]
ユーザーが見るもの
--
ユーザーがすること
==> page2

[page2]
ユーザーが見るもの
--
ユーザーがすること
==> page4
ユーザーがすること
==> page3


[page4]
ユーザーが見るもの

[page3]
ユーザーが見るもの

```

そこで、こんなかんじにシンプルなテキスト形式をもとに画像を吐き出すコンパイラをつくった。 see => [uiflow](https://github.com/hirokidaichi/uiflow)


# これだけでも比較的満足したが
基本的にコンソールを開いていて、好きなエディタでかけると嬉しいプログラマとしてはこれで満足したが、主に画面遷移図を書くロールはプロダクトオーナーや、デザイナ、IAのような人々なので、インタラクティブなエディタを作ろうと思った。

## guiflow

そこで、[guiflow](https://github.com/hirokidaichi/guiflow)というものを作った。Electronで開発しているので、MacのみならずWindowsでも動くはずだがまだ試していない。

![Kobito.d5tSMP.png](https://qiita-image-store.s3.amazonaws.com/0/35671/f86854ab-2ef5-044b-7cb5-97e308d42737.png "Kobito.d5tSMP.png")


## 実際の動作の様子を動画で見る
![test.gif](https://qiita-image-store.s3.amazonaws.com/0/35671/708be4dc-d96a-5f82-6d9d-61cdd5b941eb.gif "test.gif")



Youtubeはこちら：
[![ビデオが開けなかった場合に表示されるテキスト](http://img.youtube.com/vi/BJYl0nqNyjQ/0.jpg)](http://www.youtube.com/watch?v=BJYl0nqNyjQ)

## インストール方法(追記あり)
まだ、全然βバージョンなことを考慮して、それでも使ってみたいと思われる方は
こちらからダウンロードお願いします。

https://github.com/hirokidaichi/guiflow/releases/tag/v_0.1.1

+ graphvizの依存が切れて単体で動作します。
+ windows10での動作確認済み
+ ubuntuでの動作確認済み
+ macでの動作確認済み





## これからやること

+ アイコンがほしいのでそれを待つ
+ ダウンロードページを用意する
+ チュートリアルを用意する
+ sketchのアートボード自動生成

## やりたいこと
これをつかったアプリ・サービスを作りたい人向けの勉強会的なこと。というのも既存サービスを写経したりすると、すごくよくサービスの構造の理解が進んだりする。なれれば１サービスで３０分もかからないので、流行っているWebサービスがどういう風にUIを設計しているかの勉強になることがわかった。

# まとめ

もう画面遷移図で消耗したくないひとにオススメ。

# あわせて読みたい
[なぜ、組織のつくりとソフトウェアアーキテクチャは似てしまうのか]
(https://qiita.com/hirokidaichi/items/d12fcce80ee593bcf34d)
ストックした人にストックを返すボットを運用中(ストックをかせぎたい人向け)

[Node-REDのREST APIの使い方](http://qiita.com/zuhito/items/ed5f505edaac2baeadd9)を見て、Qiita APIを使って作ったジョークボット。

この投稿をストックすると、自動でストックがたくさん返ってきます。
ストックをかせぎたい新人プログラマはどうぞ。

作ったものはこれ。

![del.png](https://qiita-image-store.s3.amazonaws.com/0/119720/4d7ac7e4-9403-e197-da4c-25f72c3ae18e.png)

Qiita APIで投稿やストックできてしまうのはなぜだろう。。。コミュニケーションの自動化のため？
Manjaro Linuxをインストールしてはじめにしたこと

#Abstract
Manjaro Linux(以下, Manjaro)はArch LinuxをベースとしたLinuxディストリビューションの一つであり, [DustriWatch](https://distrowatch.com)のページヒットランキングでは6位(2016/04/02)と高い人気を持つ.
本記事では, 私がManjaroをインストールしたときに行ったことをメモする.


#インストールするときに
LinuxOS(Ubuntuなど)のインストール時にNVIDIAのGPUがマシンにささっていると
**画面が表示されない**といった問題がよく起こるらしくManjaroもその例外ではない.
私のPCにもGPUがささっていたのでこれを解決する.
詳しくは, [本の虫:nomodesetとLinuxにおけるGPUドライバーの問題](http://cpplover.blogspot.jp/2012/03/nomodesetlinuxgpu.html)等を参考にすると良いかも.

Ubuntuなどの解決法と同じくManjaroにおいても, kernelパラメータを変更すれば良い.
Manjaroの場合, インストールディスクを読み込んだ後に出るOSの選択メニューで**eキー**をおすと編集できる.

私が行った編集は, **[Manjaro Linux...(nonfree)]**を選択しnouveau.modeset=1となっているので**nouveau.modeset=0**とし(必要ない?), 最後に**nomodeset**を付け加えた.
(参考:[Jounrnal de Aki:MageiaからManjaroへ](http://reasonset.net/journal/archives/livewithlinux/344))

Manjaroインストール後はNVIDIAのドライバがインストールされていたのでkernelパラメータの変更はとりあえず必要ないと思う.

#インストールしたあとに
##pacmanのミラーリストの更新
pacmanはArch Linuxで用いられるパッケージマネージャである.
デフォルトではインストール元が日本以外になっている可能性があるので, ミラーを変更する.
そのためには, **/etc/pacman.d/mirrorlist**を編集すれば良い.
mirrorlistから

```
## Location  : Japan
## Time      :  ---
## Last Sync : 
Server = [筑波とか理研のURL]
```
を探し(複数あるかも)mirrorlistの一番上にコピペする. 
[Pacman Mirrorlist Generator](https://www.archlinux.org/mirrorlist/)とかもあるので, そちらを使っても良いかも.
詳しい設定方法は,[ArchWiki:ミラー](https://wiki.archlinuxjp.org/index.php/%E3%83%9F%E3%83%A9%E3%83%BC)を参照するべし.

##pacmanでパッケージ更新
パッケージをインストールする前に以下のコマンドでシステムの全パッケージをアップデートしておきたい.

```
$ pacman -Syu
```

しかし, 

```
error: key "$KEY" could not be looked up remotely
error: required key missing from keyring
error: failed to commit transaction (unexpected error)
Errors occurred, no packages were upgraded.
```

のようなエラーがでた.
そこで, [[SOLVED] error: key "A6234074498E9CEE" could not be looked up remotely](https://bbs.archlinux.org/viewtopic.php?id=193382)に従って, 以下のようなコマンドをうった(もちろん**sudo**で).

```
$ rm -R /etc/pacman.d/gnupg/
$ rm -R /root/.gnupg/  # only if the directory exists
$ gpg --refresh-keys
$ pacman-key --init && pacman-key --populate
$ pacman-key --refresh-keys
```

するとまた,

```
gpg: connecting dirmngr at '/root/.gnupg/S.dirmngr' failed: IPC connect call failed
gpg: keyserver refresh failed: No dirmngr
```

のようなエラーがでた.
よって, 最後に[みちのいに!!:pacmanで更新できなかった](http://m77.hatenablog.com/entry/2015/11/02/190050)を参考にして

```
$ dirmngr < /dev/null
$ pacman-key --refresh-keys
```
としてから

```
$ pacman -Syyu
```
でアップデート成功.

## 日本語入力
最後に**ibus**を用いた日本語入力の設定について書く. とりあえずibus-anthyを用いる.

```
$ pacman -S ibus ibus-anthy
```

によるインストールとibus-setupによる設定を行った.
続いて, 

**~/.bashrc**と**~/.xinitrc**と**~/.xprofile** (どれが必要十分を満たすかわからない...)に

```
export GTK_IM_MODULE="ibus"
export QT_IM_MODULE="ibus"
export XMODIFIERS=@im=ibus
ibus-daemon --xim -d &
```

を書き込んで再起動するとibusを用いて日本語入力可能になった.
.bashrcとxinitrcは必要ないかもしれない...

あとは,

```
$ pacman -S git dropbox
```
等で必要ソフトをインストール.
Safariで2chのエロ広告をブロックしてみた

##そもそも
iOS9以降で使えるようになったコンテンツブロック機能。AppStoreでのランキングを見る感じでは割りと人気らしいということを知り試しに作ってみた。

が、どの広告が表示されないと嬉しいのかなと思って考えた挙句、2chのエロ広告をブロックしてみた。

結局はブロックしたい広告やコンテンツがどう表示されているかを調べ、１つずつ地味にブラックリスト化していく必要があります。イタチごっこなのでこのリストをいかに更新しやすくするか、それが肝なのかなと感じました。

##ビフォー：

<img width="375" alt="before_ad.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/4664/93c2acd4-8dd5-f19b-9361-5a94c5dab24c.png">

がこうなった。

##アフター：

<img width="375" alt="after_ad.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/4664/388cb89e-b66a-80dc-7878-923dbcdb2836.png">

なんかだいぶすっきりしていい感じに。これだけでも嬉しい人いれば公開考えようかな。

##参考リンク：
https://webkit.org/blog/3476/content-blockers-first-look/
https://developer.apple.com/videos/play/wwdc2015/511/
SNSログイン実装のためローカル開発環境設定

#ローカル開発環境のapache設定

## 前提
facebookログインとか実装するとき， ドメインを指定してトークン(?)を取得します．
そのため開発環境へのアクセスをlocalhostとか192.168.33.10とかにしてるとエラーでます． 
そこで開発環境にドメイン名でアクセスする必要があります．

## 参考
apacheファイルの設定
http://www.hizlab.net/app/apache.html
https://httpd.apache.org/docs/2.2/ja/vhosts/examples.html
facebookログインについて
https://developers.facebook.com/docs/facebook-login/web#logindialog
http://www.msng.info/archives/2012/10/facebook-login-with-php.php
## apacheの設定
設定ファイル(/etc/httpd/conf/httpd.conf)に以下を追加

```
<VirtualHost *:80>
    DocumentRoot [DocumentRootへのパス]
    ServerName dev.hogehoge.jp 
</VirtualHost>
```

## hostsの設定
Mac(とたぶんLinux)では/etc/hostsに設定ファイルがあるので以下を追加

```
192.168.33.10  dev.hogehoge.jp
```

## facebookログインのトークン取得
ドメイン名を本番環境用のドメイン(ここでは， hogehoge.jp)で取得

## まとめ
ドメイン名に対応したトークンが与えられるので， 開発環境もドメイン名を指定してアクセスできるようにすれば解決ですね．
Xamarinでネイティブ依存処理付きPCL作る際、ちょっとだけ楽になる？方法

いやあ、Xamarin無料なりましたねー。
いつか来るとは思ってたとはいえ、本当に実現してみると感慨もひとしおです。
私の場合仕事じゃなくて趣味開発なので、お小遣いの事を考えなくていいというのがやっぱり超うれしい（発想が小さすぎる）。
この勢いでどんどん広まるといいなあ...。

先日の[JXUG](http://jxug.connpass.com/event/24442/)でも話題に上がったネイティブ依存コード使えるPCLの作り方、[Fenrirさんのブログ](http://blog.fenrir-inc.com/jp/2015/12/xamarin_plugin.html)にも詳細上がってたので今朝から試してみてたのですが、プラットフォームで実装分けるところ別々に書けるのはいいけど実装一緒のところをCoreに書けなくて（Coreは単なるスタブなので）、共有しようとするとSharedプロジェクト作ってiOS/Android両プロジェクトに組み込まないといけないのがちょっと面倒な感じかなと...。
一つのPCL作るのに、Core、iOS、Android、Sharedと4つのプロジェクト作らないといけないので。

あと、大きなクラスだと、Coreのスタブと依存プロジェクトの実実装のインタフェース一致を維持するのも結構しんどいかなと。
きっちり先に設計して作る形だといいですが、趣味で書き散らかす感じだと特に。

それで思ったんですが、共通処理書くのにどうせSharedプロジェクトがいるのなら、全部の処理Sharedに書いて、Coreのスタブ実装でもShared共有してやって、コンテキストスイッチで処理置き換えてやれば楽になるんじゃないか？とか思いました。
スタブでも実実装でも同じクラスファイル読み込む形になるので、インタフェースがズレることがありえなくなる。

ソリューション内の構成としては、

* Project.Core
* Project.iOS
* Project.Android
* Project.Shared

のような感じで、クラスは全部Sharedに配置して、Core、iOS、Android全てからSharedを参照してやる。
その上で、Sharedのクラス内では、

```csharp:Sample.cs
namespace Project
{
    public class Sample
    {
        public string GetPlatform()
        {
#if __IOS__
            return "iOS";
#elif __ANDROID__
            return "Android";
#else
            throw new Exception("Not implemented GetPlatfom method");
#endif
        }
    }
}
``` 

みたいな感じにしたら超楽じゃないかな？と…。

[サンプル](https://github.com/tilemapjp/DependencyPCLSample)作って動くかどうか試してみましたけど、一応問題なく動くようです。


コンテキストスイッチ使うので好き嫌い分かれるかもしれませんが、個人的には一貫性保つのにあちこち直すより1つにまとめておく方が楽かなあと思うので、同じ感覚の人にとっては楽になるかも。
多人数で開発するような場合には、先にしっかり仕様固めると思うので、一人開発向けに。
Nginx で「502 Bad Gateway」とか、なんだかエラーログがでるよって時

皆大好きNginx

たまーに起動してやろうかと思ったら、
画面には見事に
「502 Bad Gateway」
...はまった Orz

ログを見ると、こんな感じで、Permissionエラー

```
$ tail -f /var/log/nginx/error.log

*1 connect() to unix:/var/run/php-fpm/php-fpm.sock failed (13: Permission denied) while connecting to upstream, client: xxx.xxx.xxx.xxx, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm/php-fpm.sock:", host: "xxx.xxx.xxx.xxx"
```

一応確認したら、rootユーザで起動されてました。。。（ログは嘘つかないｗ

```
$ ls -l /var/run/php-fpm/php-fpm.sock
srw-rw---- 1 root root 0 /var/run/php-fpm/php-fpm.sock
```

どうやら、php-fpmのlisten.ownerと、listen.groupを、
nginxユーザに合わせると良いらしいです。

```
$ vi /etc/php-fpm.d/www.conf

listen.owner = nginx
listen.group = nginx

```

nginx + php-fpm のユーザを合わせる。
基本ですね。

失礼しました。。。TT
ansible利用時に環境変数を読み込ませる際の注意点

Ansibleでreact.jsを使用する際、babelでコードをコンパイルする必要がある。
このbabelを利用する際に、nodeのバイナリに対してパスが通っている必要があるのだが、
環境変数の設定でかなり詰まってしまったので、ここにナレッジを提供する。

・やったこと

Webで検索してみると、Ansibleの"shell"モジュールを使い、以下の条件を満たすことで動作するようだったので、そのまま実行してみた。

　1.bashコマンドに-lcオプションを付与して実行する
　2.~/.bashrcにexportを追記して環境変数を読み込ませる。

なお、これは失敗した。


・解決方法

結論から言ってしまうと、ログインシェルとして実行する"bash -lc"を実行した上で、必ず"~/.bash_profile"に記載を追記するようにすること、が条件になる。

bashのmanを見たところ、どうも.bashrcはログインシェルではないインタラクティブシェルとして起動した際に読み込まれるのであって、ログインシェルとして起動した際には読み込まれないようだ。

何となく、"-l"オプションを付与しなければ".bashrc"でもイケそうな気はするが、これは後日調べる。

コマンドは以下のようになる。

```- shell: echo "export PATH: $PATH:<追加したいパス" >> ~/.bash_profile
- shell: bash -lc "<実行したいコマンド>"
```
設定ファイルに名前付きブロックを使う


[シェルスクリプトの処理境界が鮮明になる「名前付きブロック記法」なるものを考えてみた](http://c16e.com/1603281120/)という記事を先日読みました。  

主張としては、1ファイル内での処理境界を分けるために使うとのこと。それにしても関数で十分事足りるよな、というのが自分の感想でしたが、`.zshrc`で自分が抱えていたちょっとした問題を解決してくれるきっかけになりました。

## 関数が邪魔な時もある

自分の`.zshrc`の抜粋です。設定が百行単位になった頃から大まかな処理を関数で分けるようになりました。先の記事でいうところの、処理境界を明確にするためです。

```zsh
my-zsh::command_line_editting() {
    # Emacs風のキーバインド
    bindkey -e

    # Alt+F, Alt+B でアルファベット、マルチバイト文字以外の文字を区切り文字とする
    autoload -Uz select-word-style
    select-word-style default
    zstyle ':zle:*' word-chars " /:@+|"
    zstyle ':zle:*' word-style unspecified
}

(中略)

my-zsh::command_line_editting
```

しかし、この関数、ログインシェルの起動後も残ります。

```shell-session
% functions my-zsh::command_line_editting
my-zsh::command_line_editting() {
    # Emacs風のキーバインド
    bindkey -e

    # Alt+F, Alt+B でアルファベット、マルチバイト文字以外の文字を区切り文字とする
    autoload -Uz select-word-style
    select-word-style default
    zstyle ':zle:*' word-chars " /:@+|"
    zstyle ':zle:*' word-style unspecified
}
```

シェル起動時に使うだけで再利用のあてもないのに、これはちょっと邪魔っけです。また他の関数と名前が被ってトラブルになることを恐れて、関数名に`my-zsh::`とプレフィックスをつけるようになりました。なぜ一度きりの関数にこう、気を使わないとダメなんだ……

## 無名関数で名前付きブロックをつくる

時期を同じくして、[zshには無名関数がある](http://zsh.sourceforge.net/Doc/Release/Functions.html#Anonymous-Functions)ことを知りました。  
そこで名前付きブロックの考え方と組み合わせて、`.zshrc`の記述を以下のようにしてみました。

```zsh
: "Commandline Editing" && () {
    # Emacs風のキーバインド
    bindkey -e

    # Alt+F, Alt+B でアルファベット、マルチバイト文字以外の文字を区切り文字とする
    autoload -Uz select-word-style
    select-word-style default
    zstyle ':zle:*' word-chars " /:@+|"
    zstyle ':zle:*' word-style unspecified
}
```

`&&`の先のブロックを関数にしておいて、変数に`declare`、`local`、`typeset`など使えるところが自分の好みです。気にならないなら、元記事のように`{ グループコマンド }`を使う方が記述がきれいですね。

無名関数は処理を記述した場所で即時実行され、その定義は残りません。これで関数邪魔っけ問題を解決できました。
些細な悩みだったのですが、解決できてうれしいです。
Debian8にWindowsからリモートデスクトップでログインするための環境構築

主題を実現するまでの手順


# 手段
`xrdp`を使う。


# xrdpとは
フロントページ - 日本 xrdp ユーザ会
https://xrdp.vmeta.jp/

>xrdp はオープンソースで開発されている Remote Desktop Protocol のサーバソフトウェアです。


# xrdpをインストール
ログインしたいDebianに`xrdp`をインストールする。

```console
sudo aptitude install xrdp
sudo systemctl enable xrdp.service
sudo systemctl start xrdp.service
```


# デスクトップ環境をインストール
GNOMEを入れていたが、`xrdp`はGNOMEに対応していないらしい。
xrdpが対応しているデスクトップ環境は複数ある。
今回は`Xfce`を使う。

## Xfceをインストール
```console
sudo aptitude install xfce4
```

## 環境設定
```console
echo "xfce4-session" > ~/.xsession
sudo systemctl restart xrdp.service
```


# Windowsからログイン
リモートデスクトップでログイン。


# スクリーンセーバー停止
`Xfce`を入れてから、`tessellimage`/`cwaves`/`fiberlamp`/`fuzzyflakes`といったプロセスがCPU使用率100%になる。
これらはスクリーンセーバーのプロセスのようだ。
設定でスクリーンセーバー無効にしても動くのでスクリーンセーバーをアンインストールした。

```
aptitude purge xscreensaver
```


# 参考
XRDPのインストール方法 - Narrow Escape
http://hiroom2.jimdo.com/2015/06/13/xrdp%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%96%B9%E6%B3%95/

server - How to configure XRDP to start cinnamon as default desktop session - Ask Ubuntu
http://askubuntu.com/questions/135483/how-to-configure-xrdp-to-start-cinnamon-as-default-desktop-session
オフラインリアルタイムどう書くE03 の問題


オフラインでリアルタイムに「どう書く」をやるイベント( https://yhpg.doorkeeper.jp/events/41098 )を行っています。

問題は「凸頂点の数」という名前で、詳細は
http://nabetani.sakura.ne.jp/hena/orde03nofconv/
です。

出題者の気分としては、問題を読み始めてから解けるまで1時間あればなんとかなると思ってますが、ひとそれぞれで。

実装ができた方はこちらのコメント欄からリンクを張っていただくと見つけやすくて助かります。

似たような問題をもっと解きたいという方は、
https://nabetani.hatenadiary.com/entry/yhpg_list
に過去問リンク集がありますので、そちらをご覧になると良いと思います。
ESLint v2.6.0

前 [v2.5.0] | 次 [v2.8.0]

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="en" dir="ltr">ESLint v2.6.0 released: <a href="https://t.co/jALdJMns4t">https://t.co/jALdJMns4t</a></p>&mdash; ESLint (@geteslint) <a href="https://twitter.com/geteslint/status/715962830063800320">April 1, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

小さな機能改善といくつかのバグ修正が行われました。
前回のマイナー リリースから2週間経っていませんが、要望が強かったため前倒しでリリースされました。

質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。

- 日本語の Issue 管理リポジトリ: https://github.com/eslint/eslint-jp
- チャット: https://gitter.im/eslint/eslint-jp

以下はピックアップです。

# [#5175], [#5468], [#5644]: 共有設定・プラグインの検索ロジックを改善

- npm dedup 関連で読み込みが上手く行かなくなる場合がありました。
- `$NODE_PATH`環境変数で指定されたディレクトリにあるモジュールを検索するようになりました。
- Windows で npm の Scoped Package として公開されているプラグインや共有設定のファイルを読めなかった問題を解決しました。

# [#5612], [#5658], [#5745]: JSDoc 周りを改善 ([valid-jsdoc])

- モジュール名等にハイフンが使えるようになりました。
- 複雑な型を書くと eslint がクラッシュすることがありました。
- 今までデフォルト・パラメーター構文を使うと、`@param`が無くても警告されていませんでした。

# オプションが追加されたルール

## [#5594]: [prefer-const]

ES6 Destructuring Declarations/Assignments 構文を利用した時、Destructuring の内部に `const` にすべき変数とできない変数が混在した場合に、`const` にすべき変数であっても無視するオプションが追加されました。

```js
let {a, b} = obj;    // この `b` を警告するかどうかを選べるようになりました。
                     // デフォルトでは警告されます。
a = a + 1;
```

個人的には追加したくなかったオプションだったりします。

## [#5685]: [complexity], [max-depth], [max-nested-callbacks], [max-params], [max-statements]

`max` オプションが追加され、従来の `maximum` オプションは非推奨になりました。

ESLint 全体で `max` を使うルールと `maximum` を使うルールが混在しており、統一感がなかったためです。
今後は `max` に統一していきます。

[v2.5.0]: http://qiita.com/mysticatea/items/7018ca26abfa7701debc
[v2.8.0]: http://qiita.com/mysticatea/items/8e7ca6f6ae402a494a6b
[#5175]: https://github.com/eslint/eslint/issues/5175
[#5468]: https://github.com/eslint/eslint/issues/5468
[#5644]: https://github.com/eslint/eslint/issues/5644
[#5612]: https://github.com/eslint/eslint/issues/5612
[#5658]: https://github.com/eslint/eslint/issues/5658
[#5745]: https://github.com/eslint/eslint/issues/5745
[#5594]: https://github.com/eslint/eslint/issues/5594
[#5685]: https://github.com/eslint/eslint/issues/5685
[valid-jsdoc]: http://eslint.org/docs/rules/valid-jsdoc
[prefer-const]: http://eslint.org/docs/rules/prefer-const
[complexity]: http://eslint.org/docs/rules/complexity
[max-depth]: http://eslint.org/docs/rules/max-depth
[max-nested-callbacks]: http://eslint.org/docs/rules/max-nested-callbacks
[max-params]: http://eslint.org/docs/rules/max-params
[max-statements]: http://eslint.org/docs/rules/max-statements
コードレビューに大事な褒め言葉

# コードレビューにおいて忘れちゃいけない大事なこと
コメントで突っ込んで修正されたPR、イケてるPR
そんなコードは、盛大に賞賛されるべき(賞賛されたい)！

## 大事な褒め言葉
ただただ良いPRを送り続けてマージされるのを繰り返しているだけでは、本人も自分もモチベーションを維持することは出来るのか。
良いコードだね！と言ってあげたり、PRに**LGTM**とコメントを残している人たちが居るはずだ。
褒めることはモチベーションを上げるのに大事なはず。

でもそれだけでは、味気ない気がしませんか？
もっと盛大にLGTMしてあげたい！！！
自分は[LGTM.in/g](http://lgtm.in "lgtm.in")を使ってPRにコメントを残しています。

## LGTM.in/gにも難点あり
[LGTM.in/g](http://lgtm.in "lgtm.in")はたまにLGTMと関係の無さそうな画像が上がっていたり、重かったりで画像を探すのに気づけば、あらやだ**10分**経ってる。みたいなことがありました。

## もっと効率的に盛大なLGTMをしたい！
もっと簡単に良さ気な画像が欲しい/簡単にコメントに残したい！
そんな自分の願望のため、良さ気な画像をAPIから取得出来るサービスからURLを取得し、マークダウン形式ですぐにコメントに残せるような、LGTM出力コマンドラインツールを作った。
https://github.com/neko-neko/eolgtm
![](https://cloud.githubusercontent.com/assets/6947393/14224109/7f693a54-f8cb-11e5-9940-60e6f7a5795c.gif)

## インストール
ここからバイナリをダウンロード
https://github.com/neko-neko/eolgtm/releases/latest

もしくは`go get`を使ってインストール
```$ go get github.com/neko-neko/eolgtm```

## 使い方
マークダウン形式で出力されるので、以下のコマンドですぐ貼り付けることが出来ます。
```
$ eolgtm | pbcopy
```
あとは、盛大に賞賛したいPRのコメントに貼り付けるだけ！

## 利用したAPI
下記を利用させていただきました。
http://takashicompany.com/lgtm/

取得できる画像がどれも良さ気でLGTMされた側はきっと頬が緩むはず。
あるディレクトリ以下のファイルツリーをJSONで再帰的に出力する

# やりたいこと

Bootstrap Tree View を使って、見栄えよくあるディレクトリ以下のファイル一覧を表示させたい。

https://github.com/jonmiles/bootstrap-treeview

誰か作っているだろうと思ったのですが、探しても見つからなかったので書きました。

```py3
#!/usr/bin/env python

import os
import json

def json_tree(path):
	target_json = []

	for item in os.listdir(path):
		new_hash = {}
		new_hash['text'] = item

		full_path = os.path.join(path,item)
		if os.path.isdir(full_path):
			child_dir = json_tree(full_path)
			new_hash['nodes'] = append(child_dir)
		else:
			new_hash['href'] = full_path.replace(os.getcwd(),'')

		target_json.append(new_hash)
	return target_json

if __name__ == '__main__':
	path = os.getcwd()+'/files'
	print(json.dumps(json_tree(path)))
```

ソースはこちらにも置いておきました。

https://github.com/acro5piano/tree-json
Clojure + SwingでJTableのカラムを削除する

#何の記事？
Clojureの勉強中のためにSwingを使ってCSVエディタのようなものを作っていたときに、
JTableのカラムってどうやって削除するの？って調べてたのでメモ程度に残しておきます。

#やり方
TableModelからgetDataVectorでテーブルデータを取得して変更し、再設定します。
TableModelはDefaultTableModelとします。

``` clj
;; 2次元のVector中のすべてのVectorから特定のindexの要素を削除する
(defn remove-nth [v n]
  (loop [i 0]
    (if (= i (.. v (size)))
      v
      (do
        (.. v (elementAt i) (removeElementAt n))
        (recur (+ i 1))))))

;; カラムを削除
;; ※とりあえずカラム名は適当につけます
(defn removeColumn [model n]
  (let [v (.. model (getDataVector))]
    (remove-nth v n)
      (.. model 
        (setDataVector v (new java.util.Vector (range 0 (.. v (elementAt 0) (size))))))))
```

こんなかんじでカラムを削除できます。

```clj
;; インデックス2のカラムを削除する
(removeColumn model 2)
```
視点がさまよっているif文,for文は読みにくい2

リファクタリングが必要になってC++のソースコードを読んでいる。
数直線での順序が理解しやすいのは私も経験しています。


>わかりにくいソースコードの１つの要因は、ソースコードで変数に着目する際に視点がさまよっていることであることに気づいた。
for文の場合、制御変数にしたがって視点が動いていく。その制御変数に沿った視点で現象を記述していくことで現象が理解しやすくなる。記述の複雑度があがったときにどう考えるのがよいだろうか。

単独のif文での記述の問題ではなく、for文という制御の中心の変数が、文脈の主語になっているような状況では、
その**主語が個々の文の中で埋没しないような記述の仕方**をしたほうがよいのではないかという問題提起です。
既に十分に明快に記述の場合には、「そんなのどっちで書いても同じじゃないか」となると思うのです。
ところが、実際の私が見るコードでは複雑度がもっと上がってしまい、次のような記述になってしまうことが多いのです。
前回の例よりも複雑な事例を示します。
　
よいと思われる例　1

```.cpp:

const double a = 1.0;
double f(double x);
 
for(int x = 0; x < n; x++){
    if(f(x) > a){
        doSomething(x);
    }
}
```


推奨しかねる例 1

```.cpp:
const double a = 1.0;
double f(double x);

for(int x = 0; x < n; x++){
    if(a < f(x)){
        doSomething(x);
    }
}
```

----------------------------

よいと思われる例　2

```.cpp:

const double a = 1.0; 
bool isBar(double x);

for(int x = 0; x < n; x++){
    if
    if(f(x) > a){
        doSomething(x);
    }else if(isBar(x)){
        doSomething2(x);
    }else{
        ;
   }
}
```


推奨しかねる例 2

```.cpp:
const double a = 1.0;
bool isBar(double x);

for(int x = 0; x < n; x++){
    if(a < f(x)){
        doSomething(x);
    }else if(isBar(x)){
        doSomething2(x);
    }else{
        ;
    }
}
```


このような状況のコードを読むことになると、着目している変数（これが、いわば文の主語）が安定している記述になるほうがいいのではないかという提案です。ここで着目している変数ですから、定数は文の主語にはなりません。
コメントで指摘されているように、比較対象が、定数かどうかで記述の仕方を変えることを指摘している
The Order of Arguments in Conditionals
の考えに私は同意します。


###**比較演算の左辺式は文の主語である。**
　 x > a;
は
 x is greater than a.
という文であると考えます。

###**代入式new[i] = a[i];では、左辺値が主語と考えられる。**

```.cpp:
//　new[i]が [a[i], b[i]]の範囲になるようにクリッピングする。
for(int i=0; i<n; i++){
    if(new[i] < a[i]){
        new[i] = a[i];
    }else if(new[i] > b[i]){
        new[i] = b[i];
    }
}
```

----------------------------------------------------------------

数直線で考えるのがよいと思われる例

```.cpp:
if( (-1.0 <= x) && (x < 1.0)){
    doSomething(x);
}

```

推奨しかねる例

```.cpp:
if( (x >= -1.0) && (x < 1.0)){
    doSomething(x);
}

```


扱っている対象のソースコードの対象が、数直線で考えるやり方で十分に理解しやすいものである限りは、
それでいいと思います。
ここで述べたいのは、コードの記述の複雑度が上がってしまって理解しくくなるときには、ソースコードを文章としてとらえ、その主語は何であるのか考えた記述をする方法があるという提案です。
Go TourをMacのローカルで実行

> [目的]
Go言語の学習ができる、[A Tour of Go](https://tour.golang.org/welcome/1) をローカルで実行できるようにする。

# GOPATHの確認

```bash:GOPATHが設定されているか確認
echo $GOPATH
```
```shell-session
/Users/user1/go
```

もし設定されていなければ、適当なパスをGOPATHに指定

```bash:.bash_profile等に追記
export GOPATH=$HOME/go
```
```bash:反映
source ~/.bash_profile
```

# Go Tourのインストール

Xcode licenseの同意をしていないと以下のようになる。

```bash
sudo go get golang.org/x/tour/gotour
```
```shell-session
cd .; git clone https://go.googlesource.com/tour /Users/user1/go/src/golang.org/x/tour

You have not agreed to the Xcode license agreements, please run 'xcodebuild -license' (for user-level acceptance) or 'sudo xcodebuild -license' (for system-wide acceptance) from within a Terminal window to review and agree to the Xcode license agreements.
package golang.org/x/tour/gotour: exit status 69
```

その場合、まずはXcode licenseに同意する。

```bash
sudo xcodebuild -license
```
```shell-session
You have not agreed to the Xcode license agreements. You must agree to both license agreements below in order to use Xcode.

Hit the Enter key to view the license agreements at '/Applications/Xcode.app/Contents/Resources/English.lproj/License.rtf'

Apple Inc.

Xcode and Apple SDKs Agreement

PLEASE SCROLL DOWN AND READ ALL OF THE FOLLOWING TERMS AND CONDITIONS CAREFULLY BEFORE USING THE APPLE SOFTWARE OR APPLE SERVICES.  THIS IS A LEGAL AGREEMENT BETWEEN YOU AND APPLE.  【略】
```
```bash
ｑ
```
```shell-session
By typing 'agree' you are agreeing to the terms of the software license agreements. Type 'print' to print them or anything else to cancel, [agree, print, cancel]
```
```bash
agree
```
```shell-session
You can view the license agreements in Xcode's About Box, or at /Applications/Xcode.app/Contents/Resources/English.lproj/License.rtf
```

Go Tourをインストールする。

```bash
sudo go get golang.org/x/tour/gotour
```


# Go Tourをローカルで実行
```bash
cd $GOPATH/bin
./gotour
```

```shell-session
2016/04/02 15:30:00 Serving content from /Users/user1/go/src/golang.org/x/tour
2016/04/02 15:30:00 A browser window should open. If not, please visit http://127.0.0.1:3999
2016/04/02 15:30:01 accepting connection from: 127.0.0.1:61753
```

ブラウザが立ち上がり、[http://127.0.0.1:3999](http://127.0.0.1:3999)　でGo　Tourが実行できる。
[Swift] OSX でファイルを開く・保存するダイアログを開く


OSX で Swift でファイルを開く、保存するダイアログを表示したかったので調べてみました。

# NSOpenPanel でファイルを開く

NSOpenPanel を使ってダイアログを表示します。プロパティでどんなファイルが選択可能か設定できます。

```
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = false // 複数ファイルの選択を許すか
openPanel.canChooseDirectories = false // ディレクトリを選択できるか
openPanel.canCreateDirectories = false // ディレクトリを作成できるか
openPanel.canChooseFiles = true // ファイルを選択できるか
openPanel.allowedFileTypes = NSImage.imageTypes() // 選択できるファイル種別
openPanel.beginWithCompletionHandler { (result) -> Void in
    if result == NSFileHandlingPanelOKButton {　// ファイルを選択したか(OKを押したか)
        guard let url = openPanel.URL else { return }
        log.info(url.absoluteString)
        // ここでファイルを読み込む
    }
}
```

# NSSavePanel でファイルを保存する

NSSavePanel を使ってダイアログを表示します。

```
let savePanel = NSSavePanel()
savePanel.canCreateDirectories = true
savePanel.showsTagField = false
savePanel.nameFieldStringValue = "\(pj.name).zip"
savePanel.beginWithCompletionHandler { (result) in
    if result == NSFileHandlingPanelOKButton {
        guard let url = savePanel.URL else { return }
        log.info(url.absoluteString)
        // ここでファイルに書き込む
    }
}
```

保存しようとした先にファイルがすでに存在している場合は「上書きしますか？」という確認も自動で表示してくれますが、ファイルを書き込む際は自分で既存のファイルを削除する必要があります。


# おまけ：ドラッグ＆ドロップでファイルを開く

ドラッグ＆ドロップでファイルを開きたい時は自分でクラスを作って、registerForDraggedTypes を呼び出しておく必要があります。ドロップされた時にperformDragOperationが呼ばれるのでここでファイルに関する処理を行います。

```
import Cocoa

class DraggableImageView: NSImageView {

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        registerForDraggedTypes(NSImage.imageTypes())
    }
    
    override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
        return NSDragOperation.Copy
    }
    
    override func performDragOperation(sender: NSDraggingInfo) -> Bool {
        // 画像をドラッグ＆ドロップで読み込む例
        if let image = NSImage(pasteboard: sender.draggingPasteboard()) {
            // ここで画像の処理を行う
            return true
        }
        
        return false
    }

}

```
[WebAudio API] iOS9で音が歪む、遅い、低い、割れる等の回避方法

# WebAudio API で音が歪む

歪んだり歪まなかったりするしよくわかんねー！
ってなってましたが、なんか回避できたので、書いておきます。

## 再現方法

iOS 9.2.1 iPhone6 Plus
**イヤホンを挿してない状態で**　SafariでWebAudioの再生してるページを開いて、Safariを再起動します。

ちなみに、Safariで音を再生するには、touchend等のユーザアクションで音を再生しないといけません。（一回再生すれば、そのAudioContextでは再生できるようになる）
あと、なぜか、iOS9からtouchstartがユーザアクションとして判定されなくなりました。

### 音の再生サンプル

http://goo.gl/UEpbeP

## 回避の方法

一回音を再生してから、サンプルレートが44100じゃない時に、AudioContextを再度生成することで回避できます。

### サンプル

http://goo.gl/jWZDwD
dirtyという関数内で回避しています。

### バグ回避のメインのコード

```js


function playDummy(){
  var source = createBufferSource();
  source.buffer = context.createBuffer(1,1,context.sampleRate);
  source.connect(context.destination);
  source.start(0);
}

function checkSampleRateBug(){
  if(context.sampleRate !== 44100){
    context.close();
    context = getAudioContextInstance();
    return true;
  }
  return false;
}

function dirty(){
  playDummy();
  if(checkSampleRateBug())playDummy();
}

body.addEventListener('touchend',dirty);
body.addEventListener('mouseup',dirty);

```

### コード全体

```js



function getAudioContextInstance(){
  try{
    return new (
      window.AudioContext ||
      window.webkitAudioContext ||
      window.mozAudioContext
    )();
  }catch(e){
    console.error(e);
    return null;
  }
}

onload = function(){
  var body = document.body;
  var context = getAudioContextInstance();
  
  if(context === null){
    alert('WebAudio 未対応です');
    return;
  }
  
  var sampleRate = 44100;
  // 半音上下
  var rate = Math.pow(2.0, 1.0/12.0);
  var temp = rate;
  var rates = [
    rate,
    temp*=rate*rate,
    temp*=rate*rate,
    temp*=rate,
    temp*=rate*rate,
    temp*=rate*rate,
    temp*=rate*rate,
    temp*=rate,
  ];
  
  function playDoremifasorasido(){
    var source = createBufferSource();
    source.buffer = context.createBuffer( 1, sampleRate*1, sampleRate);
    var channel = source.buffer.getChannelData(0);
    
    for( var i=0; i < channel.length; i++ ){
      channel[i] = Math.sin(i/(sampleRate/440)*rate*rate*rate * Math.PI * rates[(i/(sampleRate/8)|0)%rates.length]);
    }
    
    source.connect(context.destination);
    source.start(0);
  }

  function createBufferSource(){
    var source = context.createBufferSource();
    source.start = source.start || source.noteOn;
    return source;
  }
  
  
    
  function playDummy(){
    var source = createBufferSource();
    source.buffer = context.createBuffer(1,1,context.sampleRate);
    source.connect(context.destination);
    source.start = source.start || source.noteOn;
    source.start(0);
  }
  
  function checkSampleRateBug(){
    if(context.sampleRate !== 44100){
      context.close();
      context = getAudioContextInstance();
      return true;
    }
    return false;
  }
  
  function dirty(){
    playDummy();
    if(checkSampleRateBug())playDummy();
  }
  
  body.addEventListener('touchend',dirty);
  body.addEventListener('mouseup',dirty);
  
  body.addEventListener('touchend',playDoremifasorasido);
  body.addEventListener('mouseup',playDoremifasorasido);
  
};


```

# 参考

http://stackoverflow.com/a/34501159
setParamFloatとaddToParamFloatの違い

Live2Dアプリ作ってると軽くハマるポイントなので書いておこうかと。
自分だけかと思ったら、同じようにハマってる人がいました。

[Live2Dフォーラム - Unityでのモーション再生がうまくいきません](http://forum.live2d.com/discussion/372/unity%E3%81%A7%E3%81%AE%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%86%8D%E7%94%9F%E3%81%8C%E3%81%86%E3%81%BE%E3%81%8F%E3%81%84%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93#latest)

Unityに限らず、どのプラットフォームでも共通かと思います。

# 開発環境
・Live2D Unity SDK 2.1.00_1
・Unity5.3.1

# 2つのAPIの違い
[Live2Dドキュメント-パラメータの操作](http://sites.cybernoids.jp/cubism2/sdk_tutorial/live2d_library/parameter)やサンプルソースを見ると、パラメーター操作にはsetParamFloat、addToParamFloat、multParamFloatがあります。
このsetParamFloatとaddToParamFloatの違いですが、値を上書きするか加算するかの違いがあります。

```csharp:
// 上書き
live2DModel.setParamFloat("パラメーターID", 値);
// 加算
live2DModel.addToParamFloat("パラメーターID", 値);
```

SDKサンプルのDemoプロジェクトを見ると、setParamFloatが使われています。
（Demoプロジェクトはマウスドラッグした方に顔を向けるサンプル）

＜Demo - setParamFloat()＞
![001.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/d9c84591-c32d-0c46-9e63-2ef452ec6f46.gif)
では、これをaddToParamFloatに変えてみます。

＜Demo - addToParamFloat()＞
![002.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/23201643-87ea-742d-791e-e1f674bbd41f.gif)
加算されるので、マウスドラッグし続けるとぐいっと顔を向けて不自然ですね。
「うん、これじゃない。addToParamFloatは使う必要ないな」と思った時期がありました。

# はまりポイント
実はaddToParamFloatは、モーション再生とマウスドラッグ処理を併用する際に有効です。
僕もsetParamFloatで値を上書きしてモーションが正しく再生されないって時がありました。

・setParamFloatの場合、モーションで動かすパラメーターも上書きされて正しく再生されない
![003.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/54a1323c-ace4-ae27-830c-65bf642ebf2b.gif)

・addToParamFloatの場合、加算なのでモーションで動かすパラメーターを上書きしない
![004.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/391ff598-f4ed-0b12-34d3-63f7811ca391.gif)

setParamFloatで上手くいかない場合はaddToParamFloatを使ってみて下さい。
dockerのコンテナにroot権限を渡さない方法

[この記事](http://qiita.com/MikamiHiroaki/items/8c22918edcada1ec2aba)に関連して，root権限のないdockerコンテナを起動する方法を探していた．

dockerとroot権限というと，`sudo`なしでdockerを利用する方法ばかりヒットして，コンテナ起動に関するWeb記事が全く見つからない．
やむを得ずhelpを見たら，あっさり解決したので，メモとして投稿．

# 目標
**ホスト側root権限の必要な操作がコンテナからできない事**

# 方法
helpを見た結果，次のようにすればできた．
`-u`オプションは，UID，GIDを指定してコンテナを起動するためのオプションなので，ここに`${UID}`，`${GID}`を指定してやればよい．

```bash
$ sudo docker -u ${UID}:${GID} <その他のオプション> <イメージ名>
```

これで，`xhost local:root`みたいなことをしなくても済むし（`xhost local:${USER}`は残念ながら必要だった），アプリケーションとしてdockerを使う事に対する不安感が減らせるとおもう．`docker`起動時にroot権限が必要な点は，個人使用の範疇ならどうにかできるんじゃないかな．


# 目標達成ができているか確認
凄い雑に，上の目標が達成できているか確認した．

まず，`/tmp`に読み込みにホストのroot権限が必要なファイルを作る．

```bash
$ mkdir /tmp/docker-test
$ su
# echo foo > /tmp/docker-test/foo
# exit
$ sudo chmod 600 /tmp/docker-test/foo
$ cat /tmp/docker-test/foo
cat: /tmp/docker-test/foo: 許可がありません
$ sudo cat /tmp/docker-test/foo
foo
```

次に，この`/tmp/docker-test`をデータボリュームとして利用し，`foo`をコンテナから読もうとしてみる．

## `-u`オプションなし
結局のところrootプロセスで動いているので，当然読めてしまう．

```bash
$ sudo docker run -v /tmp/docker-test:/home -ti --rm ubuntu:14.04
root@6e87dcde582e:/# cat /home/foo
foo
```

## `-u`オプションあり
単純な方法では読めなくなっている．が，dockerの権限周りを完全に理解して大丈夫なことを確認したわけではないので，抜け道はあるかもしれない．

```bash
$ sudo docker run -v /tmp/docker-test:/home -ti --rm -u $UID:$GID ubuntu:14.04
I have no name!@69833ade7f0b:/$ cat /home/foo
cat: /home/foo: Permission denied
```
最近、Laravel5でベストだと思うフォルダ共有方法。With Windows

ベストだと思うWindowsでの環境とか言ってますけど、伝えたいのはフォルダ共有周りの話です。
(ブログの方で公開すればよかったかもなぁ・・・と若干思ってる)

## 前提

Vagrantを利用して立ててるの前提です。
あと、コマンドプロンプトは管理者権限で開いている状態です。

## 一時期のシンボリックリンク貼れない問題に関して

一時期まで私はnode_modulesをシンボリックリンクでどうにか貼ろうとして以下の様な記事を書いてます。
[windowsでlaravel5をvagrantの共有フォルダで開発しようと思っている人へ。](http://qiita.com/fagai/items/82e3e660ebf3702e782a)
Virtualboxのバージョンが上がったことでどうやらシンボリックリンクが貼ることが出来るようになったみたいです。
フロントエンドをごりごりされてないようであればシンボリックリンクで対応するのがベストであると思います。

ただし、、、

browserify-shimなどのプラグインはシンボリックリンク経由ではファイルを読めないみたいなのです・・・！
これは知らなかったのでどうしようかどうしようかと考えました。

そして結論としては以下です。

## vagrant-winnfsdプラグインとWindows上でNodeを利用する

winnfsdプラグインを知らない人は多いと思うのですが、Macの場合NFSという機能が有り、Vagrantのフォルダ共有が遅いということでググるとよく検索にひっかかります。

そしてWindowsにはNFSの機能が無いのですが、winnfsdプラグインを使うことでこのNFSがWindowsで使えます。
最初に言っていますが、コマンドプロンプトは管理者権限で開いておいてください。

### vagrant-winnfsdを利用する

インストールは

```
vagrant plugin install vagrant-winnfsd
```

これで。

あとは、Vagrantfileのフォルダ共有のコードに`type: "nfs"`を追加するのです。
これはvagrantの公式でも書かれているので確認してくださいー。
https://www.vagrantup.com/docs/synced-folders/nfs.html

```
config.vm.synced_folder ".", "/vagrant", type: "nfs"
```

Homesteadの場合だと、homestead.yamlのfoldersを以下のような指定をします。
通常の場合、普通に`type: nfs`を指定すれば問題ないのですがWindowsの場合は少し変わった書き方にしないと動いてくれません。

```
folders:
    - map: "C:\\product\\laravel"
      to: /home/vagrant/laravel
      options:
        type: nfs
```

こんな風にoptionsでtype:nfsを指定します。

あとはですね、NFSの対象とするuidとgidを指定しなきゃいけないのです。
通常だとフォルダがrootになってしまうので色々と大変です。vagrantユーザーの場合はどちらも1000番みたいなので、これを指定します。

```
config.winnfsd.uid = 1000
config.winnfsd.gid = 1000
```

もしuidとgidが違った場合は仮想環境下で以下のコマンドで調べてください。

```
UIDの調べ方
$ id -u vagrant
1000

GIDの調べ方
$ getent group vagrant
vagrant:x:1000:vagrant
↑の数字の部分です
```

ここまで指定したらvagrant upです。

## Node周りはNodistで対応

npm installやgulpを利用する場合はWindows環境上で行います。
仮想環境上でやってもいいのですが、以前のシンボリックリンクみたいにしてないと大抵失敗することが多いです。
また、仮想環境でnpm installするよりもホスト環境でやったほうが早いのです。

自分の場合は、Node周りにはNodistというWindows用のNodeのバージョン管理ツールを利用しています。

こいつの導入や、設定に関しては書きません。

## 終わり

これがベストだと思います。rsyncも有りだとおもいますすす
TOPPERS/R2CA を MacOSXで動かす

[TOPPERS/R2CA](http://qiita.com/exshonda/items/093870ecdcda6c79678c)をMacOSで動かす方法を紹介します．大まかな流れ，必要なハードウェアとソフトウェアは，Windowsと同じですので，まずはそちらの方法を一読してください．

# Arduino のインストール
## Arduino IDE のダウンロード
http://www.arduino.org/software#ide
「Mac OS X: Zip file (Java 7 or newer required)」をダウンロードしてください．動作を確認したのはv1.7.9．
※以下のサイトからダウンロードできるファイルではNGなので，間違えないように注意．
https://www.arduino.cc/en/Main/Software


zipファイルを解凍すると，Arduino.appが生成されます．
Arduino.appをアプリケーションディレクトリ（/Application）に移動します．

## 環境設定

### 設定１

Arduino.app をアプリケーションディレクトリ（/Application）に置いた場合には，この設定は不要です．アプリケーションディレクトリ（/Application）以外に置いた場合には，その場所に合わせて，以下のファイルを修正してください．

```asp_1.9.2/target/arduino_m0_gcc/Makefile.target
ARDUINO_BASE_DIR = /Applications/Arduino.app/Contents/Java
```

### 設定２

過去にARMのクロスコンパイラをインストールしていない場合には，この設定は不要です．
複数のバージョンのクロスコンパイラがインストールされていると，コンパイルに失敗する場合がありますので，Arduinoに同梱されているクロスコンパイラを使用するよう，以下のようにパスを設定しておきます．

```
$ export PATH=/Applications/Arduino.app/Contents/Java/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/:$PATH
```

# プログラムのビルド

ここでは，TOPPERS/R2CAをインストールした場所を[R2CA_DIR]と表記します．

## ビルド

端末を起動して，以下を実行します．
```
TOPPERS/R2CAをインストールしたディレクトリに移動．
$ cd [R2CA_DIR]/examples/
ビルドしたいプログラムのディレクトリに移動
$ cd Basic
$ make
```

## 実行
```
$ make run
```

### ログを確認する
```
$ screen /dev/tty.usbmodem1412 115200
```
Ctrl-a kで閉じます．

※ 「/dev/tty.usbmodem1412」の部分は，環境に合わせて修正してください．

## GDBを使ったデバッグ
新しい端末を起動します．端末上でCtrl-Tを入力し，新しい端末（タブ）を開いてもOKです．
```
$ make ocd
```
元の端末（タブ）でGDBを実行します．
```
$ make db
```

Eclipse対応は，今後進めたいと思います．
MacOS対応に関して，要望がありましたらお知らせください．
モデル移動してもマウスドラッグの顔追従させる

Live2D SDKサンプルのDemoプロジェクトで、Live2Dモデルの位置を中心以外に移動したらマウスドラッグの顔追従がずれてしまった。

＜Live2Dモデルの位置が画面中心の場合はOK＞
![000.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/d5cb4a47-439e-502f-e817-f22836dbf4b7.gif)
＜Live2Dモデルの位置が画面中心でない場合は顔の向きがずれる＞
![001.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/29714eab-1959-40ae-56c2-2ed26bcb5f57.gif)
SampleApp1プロジェクトには、モデルを移動しても顔追従できるけど行列などプログラムが複雑で困った...。
SampleApp1や難しいコードを使わず、簡単に直す方法を見つけたのでメモしておきます。

# 開発環境
・Live2D Unity SDK 2.1.00_1のDemoプロジェクト
・Unity5.3.1

# 修正箇所
ポイントとなる部分は以下のマウス位置の部分のみです。

```csharp:SimpleModel.csの62行目あたり
// マウス左ボタンが押され続けている場合、マウス位置XとYをドラッグマネージャーに渡す
dragMgr.Set(pos.x / Screen.width * 2 - 1, pos.y / Screen.height * 2 - 1);
```

pos.xyは、画面左下が(X:0, Y:0)で右上が(X:画面width, Y:画面height)です。
<img width="470" alt="002.png" src="https://qiita-image-store.s3.amazonaws.com/0/15028/3f2b004b-5d1f-538d-9d8d-cd1d7bde47aa.png">

pos.x / Screen.width * 2でマウス座標を0.0〜2.0の間に正規化します。
さらに-1する事で(X:0, Y:0)は(X:-1.0, Y:-1.0)、(X:2.0, Y:2.0)は(X:1.0, Y:1.0)になります。
<img width="470" alt="003.png" src="https://qiita-image-store.s3.amazonaws.com/0/15028/57867a0b-04f6-20bf-679f-65319627ea69.png">

これを以下のように直すと、モデル位置を変更しても追従します
(transformはLive2Dゲームオブジェクト)

```csharp:SimpleModel.csの62行目あたり
dragMgr.Set(
	(pos.x  / Screen.width * 2-1) - transform.position.x,
	(pos.y  / Screen.height * 2-1) - transform.position.y
);
```

また、カメラの位置を変えた時にも対応するための最終コードは以下の通りです。
（カメラがOrthographicの時のみ）

```csharp:SimpleModel.csの62行目あたり
// mainCameraにはMainCameraのゲームオブジェクトを取得しておく
dragMgr.Set(
	(pos.x  / Screen.width * 2-1) - (transform.position.x - mainCamera.transform.position.x),
	(pos.y  / Screen.height * 2-1) - (transform.position.y - mainCamera.transform.position.y)
);
```

![004.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/571df01a-79dd-7684-ba7f-aa758111dab2.gif)
簡単にやるには上記方法が良いかと思います。
ちなみにSampleApp1から同じ機能を流用しようとしたら、以下のスクリプトが必要っぽい。

*＜マウスドラッグ用のクラス＞*
*Assets/Scripts/sample/LAppView.cs*
*　→　LAppLive2DManagerはコメント*

*＜LAppViewで使うクラス＞*
*Assets/Scripts/sample/LAppModel.cs*
*　→　LAppModelProxyはコメント*
*　→　ModelSettingはコメント*

*Assets/Scripts/sample/LAppDefine.cs*
*Assets/Scripts/sample/L2DModelMatrix.cs*
*Assets/Live2D/framework/L2DMatrix44.cs*
*Assets/Live2D/framework/L2DTargetPoint.cs*
*Assets/Scripts/utils/AccelHelper.cs*
*Assets/Scripts/utils/TouchManager.cs*
MySQLで集合の重なりを出す

[MySQLで集合差を出す - Qiita](http://qiita.com/Hiraku/items/71873bf31e503eb1b4e1)
これと似たようなところで、集合同士の重なり(intersect)を出す方法。

ぱっといい例が思いつかないので適当だけど、

```sql
CREATE TABLE a (
  id INT NOT NULL,
  PRIMARY KEY(id)
);
CREATE TABLE b (
  id INT NOT NULL,
  PRIMARY KEY(id)
);
```

aとbに共通する部分を抜き出したいとする。

```sql
-- イメージ的にはこうしたいんよ
a INTERSECT b
```

もちろんこんな機能はMySQLにはない。

## INを使う方法

素直に書くとINになると思う。が、大抵遅いので推奨されない。

```sql
SELECT a.id
  FROM a
 WHERE a.id IN (
          SELECT b.id
            FROM b
       )
;
```

## EXISTS + 相関サブクエリ

相関サブクエリを使って、合致する行が一行でもあれば、という書き換えもできる。

```sql
SELECT a.id
  FROM a
 WHERE EXISTS (
         SELECT 1
           FROM b
          WHERE a.id = b.id
          LIMIT 1
       )
;
```

## INNER JOIN

今回のケースだとこれが一番単純だと思う。

```sql
SELECT a.id
  FROM a INNER JOIN b
    ON a.id = b.id
```

SELECT句で絞込が発生するのがちょっと嫌な所かな。


# その他の集合演算

他の処理は、、だいたい何とかなりそう。

## 射影 (project)

`SELECT id, name` みたいに取ってくる句を絞り込む操作が射影にあたる。

## 制限 (restrict)

`WHERE` 句に相当する。

## 和 (UNION)

まんま、`UNION` と `UNION ALL` がある。

## 差 (EXCEPT)

MySQLで素直に書けないけど、大抵はLEFT JOINで実現できる。
[MySQLで集合差を出す - Qiita](http://qiita.com/Hiraku/items/71873bf31e503eb1b4e1)

## 直積 (CROSS JOIN)

`CROSS JOIN`に相当する。

あとは商(DIVIDE BY)か。むむ。
異常検知のアンサンブル


異常検知、特に教師なし設定における異常検知問題において、アンサンブル手法というものはあまりない。
[この論文](http://kdd.org/exploration_files/V15-01-02-Zimek.pdf)曰く、教師なしの場合、各検知手法の精度評価や各手法毎の多様性についての評価が難しい事が大きな原因らしい。

しかし興味深かったのが、[この論文](http://arxiv.org/pdf/1507.08104.pdf)では、大量のラベルなしデータに対し教師なし異常検知モデルを複数学習させて、その出力をデータの特徴量に加えた少量のラベルありデータを用いた教師あり異常検知モデルを学習すると性能が良いとの事であった。

どちらかというとkaggleとかで良くやられているstackingだがblendingだかと似ている。
ガチャの確率

最近はガチャの確率がホットな話題です。

10%のくじを10回引いた時、何個あたりが出るかというやつですね。
この場合のくじは何回引いても確率は変わることはありませんので、
ルーレットやサイコロのほうが適切かもしれません。

1/nの確率のくじをn回引いた時、nの値を無限大にまで大きくすると
あたりを1つでも引く確率は大体63%に収束します。
はずれが1/3強(37%)、あたりが2/3弱(63%)とおぼえておくといいです。

10%のくじを20回ひいてもはずれるのが10%程度、40回でも1%がはずれます。

1/nの確率のくじをn回引くということは、期待値が1になるということです。
だから1個ぐらい出てもいいんじゃないか、と思いますが実際は1/3がはずれです。
ということは、その分を埋め合わせるように2個以上あたっている人が居ます。
2回以上あたっている人の確率は全体の約1/3です、意外に高いと思いませんか。

重複当選の大体の確率は以下のように覚えるといいです。
1回以上あたっている人の中の1/2が2回以上あたっていて、
2回以上あたっている人の中の1/3が3回以上あたっていて、
3回以上あたっている人の中の1/4が4回以上あたっています。
ざっと計算すると、約1/10で3回あたりがでる確率です。

直感的にはくじをたくさん引くほどハズレや重複当選の確率が下がりそうですが、
ハズレの確率や重複当選の確率は引く回数が多いほうがあがります。
1/2を2回の時のハズレは25%ですが、1/10を10回なら34%、1/100を100回だと37%です。
当たる確率は低くて何度も引ける方が波が荒い、ってことですね。

この辺を理解して良いガチャライフを歩んでください。

~~2倍なのに桃華ちゃまでないな～。(ｶﾞﾁｬｶﾞﾁｬ~~
Outlook2010のVBAで会議開催通知を自動承諾出来ない

Outlookのルールに該当する会議開催通知を受信した時に自動承諾するマクロともし相手が会議開催をキャンセルしてきたときに
自動で予定表から削除するマクロを組んでいます。

いろんな文献を参考にしてみているのですが、どうしても動いてくれません。
初心者向けに解説願えませんでしょうか？

Public Sub DisplaySubjectByRule(ByRef objItem As MeetingItem)

Dim myNameSpace As Outlook.NameSpace 
Dim myFolder As Outlook.Folder 
Dim myMtgReq As Outlook.MeetingItem 
Dim myAppt As Outlook.AppointmentItem 
Dim myMtg As Outlook.MeetingItem 

 　Set myNameSpace = Application.GetNamespace("MAPI") 
　 Set myFolder = myNameSpace.GetDefaultFolder(olFolderInbox) 
　 Set myMtgReq = myFolder.Items.Find("[MessageClass] = 'IPM.Schedule.Meeting.Request'") 
   Set myMtgReq2 = myFolder.Items.Find("[MessageClass] = 'IPM.Schedule.Meeting.Canceled'") 
 
If TypeName(myMtgReq) <> "Nothing" Then 
 　Set myAppt = myMtgReq.GetAssociatedAppointment(True) 
　 Set myMtg = myAppt.Respond(olResponseAccepted, True) 
 　myMtg.Send 
ElseIf TypeName(myMtgReq2) = "Nothing" Then 
 　Set myAppt = myMtgReq2.GetAssociatedAppointment(False) 
　 Set myMtg = myAppt.Respond(olResponseAccepted, False) 
 　myMtg.Send
   myMtg.Delete 
End If 
End Sub
SELECT文中で定数テーブルを作る方法がほしい

テーブルを作らなくてもSELECT文の中で定数テーブルを書ければ便利だと思うんだけど、なんかお手軽な方法が見つからない。

定数SELECTをUNION ALLでくっつけていく、というのは思いついたけど、構文が野暮ったいような気が。。。

```sql
SELECT 1 as a, 2 as b, 3 as c
UNION ALL
SELECT 10, 20, 30
UNION ALL
SELECT 100, 200, 300
;
```

```sql
-- こうなる
+-----+-----+-----+
| a   | b   | c   |
+-----+-----+-----+
|   1 |   2 |   3 |
|  10 |  20 |  30 |
| 100 | 200 | 300 |
+-----+-----+-----+
3 rows in set (0.00 sec)
```

JSONみたいに書きたいんだけどなー。一時テーブルを作るのが正しいのかな。
手っ取り早くlivereload環境構築

### node & npm
```bash
[vagrant@localhost]$ node -v
v4.2.3
[vagrant@localhost]$ npm -v
3.8.2
```
### 必要パッケージの用意
```bash
$ npm init -y
$ npm install -g gulp
$ npm install --save-dev browser-sync gulp
```
### .gitignore
```bash
#追記
node_modules/
```

### gulpfile.js
```javascript
var gulp          = require("gulp");
var browserSync   = require('browser-sync').create();
var reload        = browserSync.reload;

gulp.task('default', ['server'], function() {
  gulp.watch('Watch Dir', ['reload']);
});

gulp.task('server', function() {
  browserSync.init({
      debugInfo: true,
      open: false,
      host: "Your Host"
  });
});

gulp.task('reload', function() {
  return browserSync.reload();
});
```
### 起動
```bash
$ gulp
# こんなメッセージがでるはず
...
...
[BS] Copy the following snippet into your website, just before the closing </body> tag
<script id="__bs_script__">//<![CDATA[
    document.write("<script async src='http://HOST:3000/browser-sync/browser-sync-client.2.11.2.js'><\/script>".replace("HOST", location.hostname));
//]]></script>
...
...
# bodyタグ直前に上記スクリプトを追加する
```
### watch対象を変更した時
```bash
[13:31:02] Starting 'reload'...
[BS] Reloading Browsers...
[13:31:02] Finished 'reload' after 2.15 ms
#変更が反映されてればok
```
phpBBでひらがな、カタカナを含まない投稿を禁止する

バージョンは3.1.5。直下の `posting.php` をいじる。
120行目以降に以下を追記。

```php
$chkmsg = request_var('message', '', true);
if(strlen($chkmsg) == 0 || preg_match("/[ぁ-ゞ]/u", $chkmsg) || preg_match("/[ァ-ヶー]/u", $chkmsg)) {
  $chkres = true;
}

if (!$chkres)
{
    trigger_error('Error');
}
```
MacでSikuliXの画像文字認識をさせてテスト自動化できる範囲を増やす

# はじめに
SikuliとTesseractの画像文字認識(OCR)機能を使って主にFlexのテスト自動化を強化したい。


# 環境
- Maac OS X El Capitan
- JRE (build 1.8.0_71-b15)

# インストール

Setupを実行。

```
https://launchpad.net/sikuli/sikulix/1.1.0
sikulixsetup-1.1.0.jar
```

チェックはOpt1と3につけておく。

もしうまく動かない時は
オプション1だけでセットアップしておく。

最後に「Have a fun」というダイアログがでればセットアップ完了。

Sikuliはsetupを実行したディレクトリに作成されるので、
そのアイコンをクリックして起動させる。

アプリケーションフォルダに移動させておくと良いと思う。

# Tessdataの追加

OCR機能であるTesseractは、実はOpt3選択しなくてもライブラリまではインストールされる。
なので、Opt3を選択しないでインストールして、後でTessdataを追加しても良い。

Sikuli 1.1.0ではTessractのライブラリは以下のディレクトリに作成される。

```
/Users/butada/Library/Application Support/Sikulix
```

ディレクトリ構成は以下のとおり。

```
├── SikulixLibs_201510051707
│   ├── 1.1-MadeForSikuliX64M.txt
│   ├── SetFile
│   ├── libMacHotkeyManager.dylib
│   ├── libMacUtil.dylib
│   ├── libVisionProxy.dylib
│   ├── libjpeg.8.dylib
│   ├── liblept.3.dylib
│   ├── libopencv_java248.dylib
│   ├── libpng15.15.dylib
│   ├── libtesseract.3.dylib
│   └── libtiff.5.dylib
```

Opt3を選択してインストールするとTessdataは以下のように配置される。

```
└── SikulixTesseract
    └── tessdata
        ├── eng.cube.bigrams
        ├── eng.cube.fold
        ├── eng.cube.lm
        ├── eng.cube.nn
        ├── eng.cube.params
        ├── eng.cube.size
        ├── eng.cube.word-freq
        ├── eng.tesseract_cube.nn
        └── eng.traineddata
```

手動でSikulixTessractフォルダを作成し、
そこにダウンロードしたtar.gzを解凍して展開するのも可能。

上のファイルだけだと英語だけなので、
日本語などに対応させたい場合は別途GitHubから入手し、同様に配置する。
https://github.com/tesseract-ocr/tessdata

# 参考

http://www.sikulix.com/quickstart.html
Bash コーディングの小ネタ [for loop 編]

# 【Bash コーディングの小ネタ [for loop 編]】
* bash コーディングのテクニックをまとていく。今回は for loop 編。

# ♢ for loop
* 参考資料:  
  37.3. Bash, version 4:  http://tldp.org/LDP/abs/html/bashver4.html

## 1. for loop でインクリメント

### a. .. 記法 [刻み値1のインクリメント]
* 現行の bash v4 はインクリメントのロジックを内包しており、.. 記法のインクリメントを推奨。
* seq や expr よりも断然高速。子プロセスを別途立ち上げる必要無し。

```bash
#!/bin/bash
i=0
for i in {40..50}; do
  echo $i
done
---- 実行結果 ----
40
41
42
43
44
45
46
47
48
49
50
```

### b. .. 記法 [刻み値2以上のインクリメント]
* 2以上の刻み値にだって対応可能

```bash
#!/bin/bash
i=0
for i in {40..50..2}; do
  echo $i
done
---- 実行結果 ----
40
42
44
46
48
50
```

### c. .. 記法 [0パディング]
* 0パディングにも対応。日付ファイルを touch で作る際に愛用。

```bash
#!/bin/bash
i=0
for i in {01..10}; do
  echo $i
done
---- 実行結果 ----
01
02
03
04
05
06
07
08
09
10
```

### d. C言語ライク 
* C言語ライクな記法にも対応。私はこの書き方が一番使いやすい。
* bash コーダ以外でも直感的に理解し易い点が good !!

```bash
#!/bin/bash
for (( i=0; i <= 5; i++ )) ; do
  echo $i
done
---- 実行結果 ----
0
1
2
3
4
5
```

## 2. for loop でデクリメント

### a. .. 記法 [刻み値1のデクリメント]
* 開始値を大きく、終了値を小さくするだけで良い

```bash
#!/bin/bash
i=0
for i in {50..45}; do
  echo $i
done
---- 実行結果 ----
50
49
48
47
46
45
```

### b. .. 記法 [刻み値2以上のデクリメント]
* インクリメントの場合と要領は同じ

```bash
#!/bin/bash
i=0
for i in {50..40..2}; do
  echo $i
done
---- 実行結果 ----
50
48
46
44
42
40
```
nkfのmanページ文字化けをなんとかする

## nipponデバイス？
特にマニュアルを見る必要はなかったのだけれど、MacにHomebrewでインストールしたnkfのmanを見てみたらいきなりEOFとか表示されて、manを終了させるとなんかエラーが出てた。

```
$ man nkf
/usr/bin/groff: can't find `DESC' file
/usr/bin/groff:fatal error: invalid device `nippon'
```

なんだ？こりゃ。

## groffをインストールする
調べてみたら[OSXにHomebrewで入れたnkfでman nkfするとfatal error: invalid device `nippon'と言われるのをなんとかする](http://5zalt.hatenablog.com/entry/2014/12/03/204549)にあるように、groffをインストールして **vimで** /etc/man.confを編集してやると、とりあえずmanページは表示されるようになりました。。。が！

![Screen Shot 2016-04-02 at 12.24.44.png](https://qiita-image-store.s3.amazonaws.com/0/32983/757b0689-135c-5d4f-fa3a-f80e745419ee.png)

化けとる。

## nkfを使おう！
これはあれだな、nkfのお出ましだな。

```
$ cp -p /usr/local/Cellar/nkf/2.1.4/share/man/ja/man1/nkf.1 /usr/local/Cellar/nkf/2.1.4/share/man/ja/man1/nkf.1.org
$ cat /usr/local/Cellar/nkf/2.1.4/share/man/ja/man1/nkf.1.org | nkf -w8 > /usr/local/Cellar/nkf/2.1.4/share/man/ja/man1/nkf.1
```

ということでnkfが役に立った。…あれ？
[modo 使ってみた #02] ベジェ曲線で曲がったパイプをつくる

3Dのことを1mmもわかっていない状態から 3D マスターになるべくはじめるシリーズ。
目次は[こちら](http://qiita.com/aki_55p/items/4fad97cfaa814081e06c)

## 今回やったこと
今回も[こちらのチュートリアル](http://www.mars-inc.net/press/tutorials/index.html)から、「02: 直線と曲線が混在したパイプ形状」をやりました。

新しく出てくるのは、

- ４分割ビュー
- スナップ機能
- ベジェ曲線
- 曲線で押し出し

の４つ。

## 4分割ビュー
画面を４分割にして、「真上から」、「前から」、「横から」、「全体的にグリグリできるビュー」の４つに分割する機能。
画面右上のここから、
<img width="137" alt="icon.png" src="https://qiita-image-store.s3.amazonaws.com/0/1725/d337a986-9bb1-6c7e-6dd1-644744b87c9b.png">
"Model Quad" っていうのを選ぶと画面が４つに割れます。
平行とか直角とかで線引いたりする時見やすい。

## スナップ機能
[ここ](http://cgchips.com/how-to-use-snap-tool/)を参考にしました。
上部タブの "Snapping" っていうの選択するとスナップモードに入って、左カラムにスナッピングの設定できる欄が出現するので、そこからスナップ対象を選択可。
今回の場合、vertex と grid に設定。
<img width="1396" alt="Untitled_-_MODO_indie.png" src="https://qiita-image-store.s3.amazonaws.com/0/1725/c68afa31-1252-6904-4983-4ff2907dab8c.png">

## ベジェ曲線
イラレとかでもお馴染みのベジェ曲線。
４分割ビューにしたのは、ベジェを書くのが楽だからです。

ベジェ曲線自体の説明は省きますが、ツールの在り処がチュートリアル動画と同じ場所に見つけられなかったので補足だけ。
"Basic" の中の "Pen" ツールを長押しすると "Bezier Curve" が出てきます。
他にも普通の曲線とかフリーハンド的なやつもある。

これで、パイプの元になる線を引いていきます。
<img width="1191" alt="Screen Shot 2016-04-02 at 11.34.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/1725/029a17cd-66c2-dba6-aefd-374152ace14a.png">

## 曲線で押し出し（Curve Extrude）
ベジェ曲線で、パイプの元になる線が引けたら、今度はパイプの肉付けをしていきます。

右上の ”Item List" で新しいメッシュレイヤーを追加して、"Basic" の球ツールや円柱ツールで、パイプに対して垂直に交わる円を設置。

それを左タブ "Duplicate" の中の "Curve Extrude" で先ほどのベジェ曲線に沿って押し出し。
パイプの肉付けの元になる円を設置したレイヤーにフォーカスして、ベジェ曲線レイヤーが背景にある状態で、"Curve Extrude" を選択して、メインビューをクリックすると自動でベジェ曲線にそって円が押し出されて形になります。
<img width="1186" alt="Screen Shot 2016-04-02 at 11.34.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/1725/423d3387-13be-b472-0a54-271cfe401f6a.png">

この「勝手に線に沿って円が押し出される」仕組みがよくわかってないのだけど、勝手にやってくれます。
沿う曲線とかどうやって判定してるの。。。？

ともあれ、今回はこれだけです。

次回も、チュートリアルをなんかやる予定。

## 参考
[MARS modoチュートリアルシリーズ　初級編](http://www.mars-inc.net/press/tutorials/index.html)
[CGchips　スナップツールの使い方](http://cgchips.com/how-to-use-snap-tool/)