OmniAICreator/Qiita-1.07M huggingface dataset:
howler.jsのimportが出来ない！

# やりたいこと
```js
import { Howl } from "./howler";
```

# 現実
```
SyntaxError: The requested module './howler' does not provide an export named 'Howl'
```

# 解決策
howler.jsの一番下に

```js
export let _Howl = Howl;
```

を入れる。そしてimportの部分を

```js
import { _Howl as Howl } from "./howler";
```

とするとHowlクラスが使えるようになる！

# おわりに
もっといい方法があれば教えてください。
Amplitube3によりAnaconda3のSpyderが起動しない

記事公開日: 2019/07/18
最終更新日: 2019/09/26


# 概要
- Anacondaのインストールを行い、Spyderを使用しようとした
- Spyderが”Intel MKL FATAL ERROR”で起動できなかった
- 調べた結果、趣味用にインストールしていたAmplitube3が原因との情報
- 対策として以下の３つがありそう
 - Amplitube3をアンインストールする方法
 - Amplitube3をアンインストールしない方法（未検証のため本記事では紹介しない）
 - AnacondaではなくpipでSpyderをインストールする方法

# 1. はじめに
Amplitube3が原因でAnacondaのSpyderが起動できませんでした。後述のサイト[1] にこの問題が詳しく述べられていますが、日本語の記事は見当たらなかったため本記事を作成しました。

# 2. 環境
OS: Windows10pro version 1903 build 18362.239
Anaconda3 2019.03 (python3.7.3 64-bit), conda 4.7.5
(Anaconda内の）Spyder: 3.3.3
IK Multimedia Amplitube3: バージョン不明


# 3. Spyderが起動しない症状
大学の講義で使用するために手持ちのPCにAnacondaをインストールしました。インストール完了後、Spyderの起動を試みると、以下のスクリーンショットのように MKL（Intel math kernel library）で何かが起きている模様。
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359473/4d7f957d-1b81-ca27-d04a-6b16ddee8aa2.png)

プロンプトから `spyder -v` をしても同様に `Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.`とのことで起動できず。また、condaやSpyderをアップデートしてみるも変わらず。

# 4. 見つけた情報
調べた結果次のサイトに辿り着きました。
https://github.com/ContinuumIO/anaconda-issues/issues/8561
このサイトよりAmplitube3が原因候補になりました。

Amplitube3は音楽制作等に使用するIK Multimediaのギターアンプシミュレータで、趣味で使用するためにインストールをしていました。詳細はIK Multimedia公式サイトか、日本語だと以下のサイトを参照ください。
http://www.e-frontier.co.jp/store/products/ik/amplitube3.html

# 5.改善策

## 5.1 Amplitubeをアンインストール
Ampitube3のアンインストールを行った上で、Anacondaを再インストールしました。
結果、3.Anacondaが起動しない症状 が改善され、Spyderの起動を確認しました。


## 5.2 AmplitubeをアンインストールせずにSpyderを使う
先に挙げたサイトではアンインストールを行わずに起動する方法も紹介されているみたいです。
まだ試してはおらず、できたら後日検証して別記事にて書きたいと思います。

[記事作成後にここに追記予定]

## 5.3. AnacondaではなくpipによりSpyderをインストール
改善策ではなく代替案ですが、そもそも私の場合はAnacondaを使う必要がないのではと思い、Anacondaをアンインストールしたうえで代わりにpipを導入、pipからSpyderをインストールしました。Amplitube3がインストールされた状態で、`spyder3`コマンドにて起動を確認しました。

condaとpipを同時に使うと衝突するとの報告があるので注意。
http://onoz000.hatenablog.com/entry/2018/02/11/142347
検索すれば記事がたくさん出てくるかと思います。

# 6. おわりに
以上のようにAmplitube3を入れているとAnacondaのSpyderが起動しない場合があるようです。私の環境ではAmplitubeをアンインストールするか、Anacondaを使わずにpipを使うことでSpyderが起動できたことを報告します。


# 参考文献
[1] GitHub ContinuumIO/anaconda-issues, ”Freshly installed anaconda3 python crashes on use of MKL due to python fetching wrong dll's on import #8561,” "https://github.com/ContinuumIO/anaconda-issues/issues/8561", 2019/07/18 閲覧.
[2] e-frontier, ”Amplitube3,” "http://www.e-frontier.co.jp/store/products/ik/amplitube3.html", 2019/07/18 閲覧.
[3] onoz000, ”condaとpip：混ぜるな危険,” onoz000’s blog, http://onoz000.hatenablog.com/entry/2018/02/11/142347, 2019/07/18 閲覧.

# おまけ
初投稿で至らない点が多くあるかもしれませんが、優しくご指摘いただければ幸いです。
【Mac】gitで複数の鍵・アカウントをconfigファイルで管理する方法

#案件が複数、githubアカウントも複数で困っている方向け

##1、~/.ssh/configファイルを作成する
configファイルを下記の様に記載。
※Hostや秘密鍵の部分は自分の環境で合わせてください。

```~/.ssh/config
#プロジェクトAはgithubアカウントA
Host projectA
HostName github.com
User git
Port 22
#↓名前は超適当
IdentityFile ~/.ssh/github_a_rsa
TCPKeepAlive yes
IdentitiesOnly yes

#プロジェクトBはgithubアカウントB
Host projectB
HostName github.com
User git
Port 22
#↓名前は超適当
IdentityFile ~/.ssh/github_b_rsa
TCPKeepAlive yes
IdentitiesOnly yes

```
##2、各プロジェクトのリモートリポジトリURLをメモする。
git@github.com:AccountA/projectA.git
git@github.com:AccountB/projectB.git

##3、各プロジェクトの.gitファイルと同じ階層で下記コマンドをそれぞれ実施
```shell:ターミナル上での操作
#プロジェクトAの.gitと同階層で実行
$git remote add origin git@projectA:AccountA/projectA.git

#プロジェクトBの.gitと同階層で実行
$git remote add origin git@projectB:AccountB/projectB.git
```

これで無限にプロジェクト設定できますね。
後は、pullなりpushなりお好きにどうぞm(__)m
PHPUnitテスト時のメモリエラー対策

PHPUnitでテストをする際に以下のようなエラーが出た場合の対処

Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to allocate 581632 bytes)


実行時に以下のコマンドを指定

```
./vendor/bin/phpunit -d memory_limit=1024M
```


以上
「ディープラーニングってアレですよね、凄いやつ」ぐらいの人がG検定に合格した話

## 背景
はじめて記事投稿します。
先日7月6日、日本ディープラーニング協会(以下JDLA)の[G検定](https://www.jdla.org/business/certificate/?id=certificate_No02)を受験し、無事合格できました。
普段データ分析とは無関係の業務で、試験対策を始めるまで基本的な用語の意味すら知らなかったですが、そんなレベルでもとっつきやすいよ、と思っていただければ。

## G検定とは
G検定の説明として、JDLA公式サイトに以下のような記述があります。
```ディープラーニングの基礎知識を有し、適切な活用方針を決定して事業応用する能力を持つ人材```
出オチですが後半の「適切な〜」はどうしても「まじかよ」と思ってしまいます。
ですので前半部分、「ディープラーニングの基礎知識を有し」たい方向けのものかなと。

## 受験のきっかけ
私自身、この分野の知識が全くないことに多少の危機感を感じていました。
理由は以下のとおりです。

- 学生時代
    - 同じ研究室の人が機械学習を使いこなしていた（ロボット工学や画像認識など）
    - メインで研究を見てくれていた先生の口癖が「とりあえず ニューラルネット 入れてみた」だった
- 就職以降  
    - この分野の話を見聞きする頻度が極端に増えた
    - 同期や後輩が学生時代にAIを専攻、「うわっ...私の○○、低すぎ...？」状態

そんな中どこで知ったか分かりませんが「**基礎知識を体系的に学べる資格だぜ！**」みたいな宣伝文句を目にして受験を決めました。

## 学習方法
JDLAの公式サイトには推薦図書がいくつか紹介されていますが、以下の2冊を利用しました。

- [人工知能は人間を超えるか](https://amzn.to/2LrRI40)
JDLAの理事長である松尾豊氏の有名（らしい）な本です。
第一次AIブームの話から現在までの人工知能研究の変遷や、今後社会がどうなっていくか、技術をどうしていくべきかについて、著名人の発言を混じえながら書かれています。
本格的な試験対策の前に、全体を俯瞰するために大変参考になりました。

- [徹底攻略 ディープラーニングG検定 ジェネラリスト問題集](https://amzn.to/32Ho7Jw)
こちらは試験対策用の問題集です。1周目はほぼ解説のみ目を通し、2周目で設問と回答の交互見、3周目は章単位で解いていくという感じで学習しました。

## 受験してみて
詳細は書きませんが、いろいろ感じました。

- 時事問題が大変
私の勉強方法のせいかもしれませんが、時事問題が多く出題され困りました。
時期を見てもほんの数ヶ月前の話題まで出題され、何度Google先生に泣き縋ったことか（※不正ではありません）

- 全然時間がない
試験時間は**120分**で、設問数は**226問**です。
「アレッ...？おかしくない？」と思っていましたが、やっぱりおかしかったです、自己責任なんですが。
結果、最後まで解き終えたときには残り7分ぐらいで、全然見直せないまま試験を終えることになりました。
基本的な学習手法の名称や原理など、もっと即答できるようにしておけばよかったなと後悔が残ります。

## 最後に
だらだら書きましたが、受験の6日後、7/12日に無事合格通知を受け取りました。
業務に活かせるレベルには到底及びませんが、学習のきっかけが見つからない人には適した試験かと。
今回紹介したG検定とは別に、JDLAではディープラーニングを実装能力を問われる「E資格」も開催しています。
試験はどちらも年2,3回のみの開催ですが、この流れで実用的な知識も欲しいので引き続き頑張っていきます。

あと合格者限定のSlackチャンネルがあるそうです、参加者の8割botとかだと楽しそう。
NestJSからJiraのチケットを作る

Angularで作ったUIからJiraチケットを作ろうとしたところ、CORSの問題でうまくいかなかった。デフォルトではJiraは同じOriginからのリクエストしか受け付けてくれないためらしい。対策としては、[リクエストを受け付けるOriginを設定する(Jiraの掲示板参照)](https://community.atlassian.com/t5/Answers-Developer-Questions/Cross-Origin-Resource-Sharing-with-JIRA-REST-API-and-Javascript/qaq-p/484801)か、同じOriginに見えるようリバースプロキシか何かを設定すればよいらしい。しかしどちらも相手のサーバを触る必要があるので敷居が高い。(会社のサーバは、一つのプラグイン追加に対して"協議"に半年かかる)

代わりにAngularで作ったUIからバックエンド(自PCで稼働させる)のNestJSサーバに要求を出して、NestJSからJiraのREST APIを叩かせようと思う。

> サーバを使う場合もAuthorizationをどうするかが課題になる。現状、社内Jiraはイントラネットだからか、Basic認証を使っているらしい。そのままで良いものか…

# チケットを投稿するコントローラ
以下にNestJSからAxios(HTTPクライアント)を使ってJiraチケット作成を試行した際の簡単なコントローラを示す。testというエンドポイントを開くとエピックを作るので、APIとしてはありえない仕様だが、とりあえず動きは確認できる(ブラウザを開くだけで確認でき、Swaggerの設定をせずに試せるのでついついやってしまう)。

```typescript:controller.ts
import { Controller, Get, HttpService } from '@nestjs/common';
import { AxiosResponse, AxiosRequestConfig } from 'axios';

@Controller()
export class AppController {
    constructor( private readonly http: HttpService ) {}

    @Get( '/test' )
    async createEpic(): Promise<any> {
        let config: AxiosRequestConfig = {
            baseURL: 'http://<JiraサーバのURL>/rest/api/2/',
            auth: { username: 'ユーザ名', password: 'パスワード' } // Basic認証の指定も兼ねる
        };
        const issue = { 
            fields: { 
                "project": { "key": "プロジェクトのキー" }, 
                "issuetype": { "id": "10000" },
                "summary": "概要",
                "description": "説明",
                "customfield_10104": "エピック名!! これが無いとエピックが作れない。"
            } 
        };
        let res= {};
        try {
            // ここで、BaseURLにissueが付け加えられて、issueエンドポイントを指す
            res= await this.http.post( 'issue', issue, config ).toPromise();
        }
        catch( e )
        {
            // Jiraサーバから文句を言われたらここを見る
            console.log( e.response );
        }
        return res;
    }
}

```
#嵌まったポイント
どうしようもないところで嵌まってしまったので、忘れないようメモする。
## エピック名が無い
400 Bad Requestが連発してチケットが作れなかった。実は要求自体はほぼできていたのだが、必須のフィールド(エピック名)が抜けていてNGだった。エラー応答の`e.response`を早く見ていたら、「エピック名がありません」と書いてあるのに気づけたが、よく見ずにいじってしまい時間を浪費してしまった。
## エピック名のフィールドが分からない
`customfield_10104`がエピック名だなんて初見殺しも良いところ…と思ってしまったが、実はREST APIの`field`から調べることができた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/b2552167-82ef-7320-f039-6644caf701af.png)
## チケットタイプが分からない
既存のエピックから、エピックのチケットタイプは10000と分かったものの、実はREST APIの`issuetype`から調べることができた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/97ad55b6-7c71-8de4-ec98-c8df50125444.png)
なるはや Vue SPA入門

この記事は JavaScript や jQuery は知っているが、Vue.js は初めてといった方がなるはやで Vue SPA(Single Page Application) エンジニアになるのをサポートします。

「なるはや」のポイントはいきなり最終形である Vue CLI3 で作ったプロジェクト上で演習しているところです。プロジェクトファイルの全体像を俯瞰してから単一ファイルコンポーネント上で演習しています。

## なるはや Vue SPA入門

- [プロジェクト作成](https://qiita.com/tsubo/items/50ec81ffdfb26b8bc15d)
- [ファイル構成](https://qiita.com/tsubo/items/579daa4f1b45f13b8175)
- [Vue Router](https://qiita.com/tsubo/items/fe91e95e52ee82e05681)
- [単一ファイルコンポーネント](https://qiita.com/tsubo/items/6822cfb3f4369976db65)
- [Vue の基本](https://qiita.com/tsubo/items/02a18b1899128505682e)
- [コンポーネント](https://qiita.com/tsubo/items/745324a9f4719cb6b8fa)
- [Vue.js devtools](https://qiita.com/tsubo/items/d03ef6aa7ca187527860)
- [Bootstrap](https://qiita.com/tsubo/items/fdee5fd998b0399546b9)
- [Vuex](https://qiita.com/tsubo/items/af3886cdbeb6781e7d52)
- [ライフサイクル](https://qiita.com/tsubo/items/a0c9ded90bba1370131c)
- [API コール](https://qiita.com/tsubo/items/d741b52e5fea4aba2147)
- [Vuex モジュール](https://qiita.com/tsubo/items/be12451533db74428d95)
- [Vuex ファイル分割](https://qiita.com/tsubo/items/771d163a3c6b807a6977)

## Github レポジトリ

https://github.com/tsubo/vue-tutorial

## Vue.js 公式ドキュメント

なるはや Vue SPA入門は公式ドキュメントほど網羅的ではないので、最終的には公式ドキュメントにも一通り目を通してください。

- [Vue.js](https://jp.vuejs.org/index.html)
  - [ガイド](https://jp.vuejs.org/v2/guide/)
  - [API](https://jp.vuejs.org/v2/api/)
  - [クックブック](https://jp.vuejs.org/v2/cookbook/) 
- [Vue Router](https://router.vuejs.org/ja/)
- [Vuex](https://vuex.vuejs.org/ja/)
- [Vue CLI](https://cli.vuejs.org/)
  - [ガイド](https://cli.vuejs.org/guide/)
Ubuntuでubuntuユーザ以外のアカウントでSSHログインできるようにする

クライアント:MacOS High Sierra
サーバ:16.04.6 LTS (Xenial Xerus)
AWS EC2 で構築したため、ubuntuユーザのキーペアがあらかじめ作成されています。
クライアントPC側はAWSで生成したキーペアを使用しています。

Ubuntuの初期アカウントのubuntuでSShします。
クライアント

```console
$ ssh -i aws.pem ubuntu@y.y.y.y
```

サーバ

```console
$ sudo su
```

アカウント作成

```console
# useradd xxxx
# passwd xxxx
```

# sudoユーザへの追加

```console
# groups xxxx
   xxxx : xxxx
# gpasswd -a xxxx sudo
   Adding user xxxx to group sudo
# groups xxxx
   xxxx : xxxx sudo
```

# ユーザディレクトリの作成

```console
# mkdir /home/xxxx
# midir /home/xxxx/.ssh
```

# 鍵の設置
今回はubuntuユーザと同じ鍵を設置することとします。

```console
# ls -l /home/ubuntu/.ssh/
    total 4
    -rw------- 1 ubuntu ubuntu 392 Jul 17 15:39 authorized_keys
# cp /home/ubuntu/.ssh/authorized_keys /home/xxxx/.ssh/authorized_keys
# diff /home/ubuntu/.ssh/authorized_keys /home/xxxx/.ssh/authorized_keys
# chmod 600 /home/xxxx/.ssh/authorized_keys
# chown xxxx:xxxx /home/xxxx/.ssh/authorized_keys
```

# クライアント

```console
$ ssh -i aws.pem xxxx@y.y.y.y
    Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-1087-aws x86_64)
$ 
```


※　cat /etc/ssh/sshd_configの　PermitRootLogin prohibit-password　については、PermitRootLogin no としてもよい。

```console
# vi /etc/ssh/sshd_config
# /etc/init.d/ssh restart
    [ ok ] Restarting ssh (via systemctl): ssh.service
```
Angular で変換確定前に input の値を得たい時は COMPOSITION_BUFFER_MODE

## やりたいことと方法を手短に

Google の検索欄って、変換を確定する前から検索してくれて便利ですよね。

![GoogleSuggest.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6870/0b343a57-a1a1-45a0-5359-e822b5cde74e.gif)

Angular でこのように変換確定前の入力値を使いたいときには [`COMPOSITION_BUFFER_MODE`](https://angular.jp/api/forms/COMPOSITION_BUFFER_MODE) が役に立ちます。モジュールやコンポーネントの `providers` で `COMPOSITION_BUFFER_MODE` を `false` にすれば、 IME の変換が確定していなくても input の入力値がモデルに反映されます。

- [デモページ](https://angular-composition-buffer-mode.stackblitz.io/)
- [ソース](https://stackblitz.com/edit/angular-composition-buffer-mode?file=src/app/app.component.html)

## 詳しい説明

入力された文字を表示するだけの簡単なコードを考えます。

```html
<input ngModel #text="ngModel"> {{ text.value }}
```

これを PC のブラウザで操作すると、変換を確定するまで入力した文字が表示されないはずです。なぜこのような動作になるかというと、 Angular が変換が確定するまでモデルに入力値を反映させていないからです。具体的な処理は [DefaultValueAccessor](https://github.com/angular/angular/blob/8.0.2/packages/forms/src/directives/default_value_accessor.ts#L135) に書いてあります。

この挙動は `COMPOSITION_BUFFER_MODE` の値を設定することで変えることができます。

- `true` なら変換を確定するまでモデルに反映されません。
- `false` なら変換を確定する前でもモデルに反映されます。
- 無指定の時は Android なら `true`、それ以外なら `false` を指定したときと同じ動作をします。詳しくは  [DefaultValueAccessor の実装](https://github.com/angular/angular/blob/8.0.2/packages/forms/src/directives/default_value_accessor.ts#L94)を参照

最初に書いたデモでは、これら３種類の設定について動作を確認することができます。忙しい人のために、実際に操作している様子の動画を貼っておきます。 `false` のときだけ変換確定前でも値を表示できていますね。

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6870/6c7b2dd7-0734-3fc4-dc7a-feeb66c6495e.gif)

変換を確定する前でもモデルに反映させるために `false` にするコードのイメージです。このように `AppModule` に書いてもいいですし、コンポーネント単位で挙動を変えたいときはコンポーネント側に書いても構いません。

```ts
import { COMPOSITION_BUFFER_MODE } from '@angular/forms'

@NgModule({
  // ...
  providers: [
    // 変換が確定する前でも input の値を得られるようにするため
    { provide: COMPOSITION_BUFFER_MODE, useValue: false }
  ]
})
export class AppModule {}
```

これでサジェストや文字数カウントなどの機能も思いのまま！ Happy Angular Life！

## 参考

- [JavaScript とクロスブラウザでの IME event handling \(2017年\) \- たにしきんぐダム](https://tanishiking24.hatenablog.com/entry/ime-event-handling-javascript) - input イベントや compositionend イベント周りの話が参考になりました
- [fix\(forms\): make composition event buffering configurable \(\#15256\) · angular/angular@5efc860](https://github.com/angular/angular/commit/5efc86069ff92d980bb460c15deccb1e0fff9363) - この処理が入ったコミット
grafanaからslackに直接panel共有したかった

# 動機
mackerel から prometheus + grafana の環境に移行したんですが
grafanaにもこういうのがあるといいなと思ってました

![l.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122084/2efa1fca-12f1-24a3-19bb-464fd33a6402.png)

ないならないでスクショして貼るだけなんで別にどうという手間でもないんですが

# で

image作った
https://hub.docker.com/r/masahata/grafana

grafana.iniに必要な情報を追加して

```ini:grafana.ini
; 画像保存のために external_image_storage を設定する必要があります
; s3 しか使ったことないけどどれでも問題ないはず…

; 以下オリジナルの設定項目
[share_slack]
; trueにするとtabが出る
enable = true
; alertと同じくincoming-webhookのアレ
webhook = https://hooks.slack.com/services/xxxxxxxxx/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxx
; 以下3つは設定しなければwebhookのデフォルト
icon_emoji = sushi
icon_url =
user_name = Grafana
; 送信する選択肢にするチャンネルを `,` 区切りで羅列する（デフォルトはwebhookに設定したチャンネル）
channels = general,random,my-channel
```

↑のimageでコンテナを起動
適当なダッシュボードを開き

![スクリーンショット 2019-07-18 0.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122084/feb69038-8a37-1392-06a9-ad775123ec24.png)

いつものshareのモーダルを開くと…

![スクリーンショット 2019-07-18 0.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122084/e4a0461e-2368-e09a-d725-9ec9fe4b3542.png)

こんな感じのものが増えてるので、適当にポチポチ選んで青いボタンを押すと…

![スクリーンショット 2019-07-18 0.12.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122084/b0849f19-2859-8674-5da8-ba23ba5417dc.png)

slackに送られる（タイトルのリンク先はボタン押した時のurl）

おわり

# おまけ

https://github.com/buildsville/grafana/compare/v6.2.5-base...merge-share-to-v6.2.5

grafana本体に手を加えずにやる方法はちょっとわからん
はじめてのgulp構築

## はじめに
gulpをはじめて、なんとなくこの設定がシンプルでしっくりきたgulpfile.js。
LPとか１ページテスト用ぐらいの小規模。
watch対象をちょっと変えれば複数ページ対応できるのだけど、まず動かせるぐらいのニュアンス。

とりあえずsass、あとは最低限必須のものを入れている感じ。
npm5.2.0以上、gulp4に対応。

## ポイントなど
- `npx gulp watch`でwatchする
- htmlとjsは自動リロードぐらい
- cssはsass使ってベンダープレフィックスつけとく程度
- `browserSync`の`open: 'external'`はIPで開くので、スマホチェック時とかでわざわざ自分のIP調べなくても良い


## 構成

![gulpfile.js.s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232821/56b25b14-53f4-1f5d-921f-40bd14f17764.png)



## gulpfile.js

```js

var browserSync = require('browser-sync');

var gulp = require('gulp');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');

// css
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');

// sass
gulp.task('sass', function(done){
  gulp.src( 'src/assets/sass/style.scss')
    .pipe(plumber())
    // expanded / compact / compressed
    .pipe(sass({outputStyle: 'compact'}).on('error', sass.logError))
    .pipe(autoprefixer())
    .pipe(rename('style.css'))
    .pipe(gulp.dest('src/assets/css'));
  
  browserSync.reload();
  return done();
});

// html
gulp.task('html', function(done){

  browserSync.reload();
  return done();
});

// js
gulp.task('js', function(done){

  browserSync.reload();
  return done();
});

// --------------------
// watch
gulp.task('watch', function(done){
  browserSync.init({
      server: './',
      startPath: 'src/',
      open: 'external'// IPで開く
  });

  // html
  gulp.watch(['src/index.html'])
    .on('change', gulp.series('html'));

  // sass
  gulp.watch(['src/assets/sass/*.scss'])
    .on('change', gulp.series('sass'));

  // js
  gulp.watch(['src/assets/js/script.js'])
    .on('change', gulp.series('js'));

  return done();
});


gulp.task('default', function(done){
  console.log('gulp installed!!');

  return done();
});
```

## バージョン
node v10.13.0
npm 6.4.1
【超初心者向け】Firebaseでハマった落とし穴

## 当時の状況
デプロイはできた。しかしindex.html 以外のファイル（.jpg / .css）がサイトに反映されない。ローカルではきちんと見れる。
クロームの検証で見てみると404エラーでパスがおかしいとのこと

###環境
```
macOS Mojave 10.14.5
node 12.5.0
npm 6.9.0
Firebase 7.0.2

テキストエディタ：VScode
```

## 試したこと
- **画像タグのパスの確認（絶対パスのコビぺ ）**
- **styleseet のパスの確認絶対パスのコビぺ ）**
- キャッシュの削除（１週間分）
- プロジェクトの作り直し
- [google cloud functions - Firebase hosting cannot find my CSS - Stack Overflow](https://stackoverflow.com/questions/51938831/firebase-hosting-cannot-find-my-css)
- [HTML - FirebaseでDeploy 後にcssが無効になった｜teratail](https://teratail.com/questions/145980)
-過去に作成された３つのファイルの削除（firebase.json & firebaserc & gitignore）その後、初期化 firebase init
- デプロイしたいディレクトリよりも上の層でfirebase.jsonが無いか確認
- https://teratail.com/questions/175877
- 作成されたファイル、プロジェクトを決して、デスクトップのファイルも作り直してみる

###参考にした記事
- [Firebaseの始め方](https://qiita.com/kohashi/items/43ea22f61ade45972881)
- [FirebaseでWebサイトを無料でサクッと公開してみる](https://qiita.com/Ijoru/items/5b27f1c32df2222514fb)
- [Firebaseでサイトを公開する方法を初心者目線で解説します！ - Qiita](https://qiita.com/Tajima-Kazuki/items/0339952ee3597b1c0815)



#結論
**~パスが通らない~**
原因1：CSSやIMGのリンクに対しても絶対パスで行なっていた。
.css や.jpgはindex.htmlに対して相対パス使わないと見失うとのこと

原因2：VScodeのサイドバーで「右クリック→相対パスでコピー」でリンクにコピペしていた
相対パスの書き方をググってきちんと書けば解決

```html
 <link rel="stylesheet" href="/Users/USER/Desktop/LeoPort/public/style.css"/>
　　　　　↓
 <link rel="stylesheet" href="./style.css"/>
```
##最後に
「プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

ちなみに今回デプロイしたやつです。特に機能的なものはないですが、、
https://leoport-79122.web.app/
circleciにssh接続（Permission denied (publickey).エラー対処も）

## circleciにssh接続する方法
1. JOBS
2. 右上の「Return workflow」の右のにある▽を押して「Rerun job with SSH」を押す
3. Wait for SSH Sessionsのタスクにある「$ ssh -p ＊＊＊＊＊ ＊＊.＊＊＊.＊＊＊.＊＊＊」で接続する

## Permission denied (publickey).
翻訳したとおり、鍵の認証が通らなかったので、GitHub接続に使っている鍵を指定する

```
$ ssh -i ~/.ssh/github.pem -p ＊＊＊＊＊ ＊＊.＊＊＊.＊＊＊.＊＊＊
```
以上。
【jQuery】スクロールに合わせてヘッダーを出現・格納させる

ページを下にスクロールすると隠れ、上にスクロールするとスィーっと現れるヘッダーをjQueryで実装する。

```HTML:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <!--jQueryを読み込んでおく-->
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <link rel="stylesheet" href="style.css">
    <script type="text/javascript" src="main.js"></script>
    <title>タイトル</title>
  </head>
  <body>
    <header>
      ここがヘッダーです。
    </header>
  </body>
</html>
```

```CSS:style.css
body{
  background: #FFF;
  height:2000px;
}
header{
  background: #000;
  width: 100%;
  height: 100px;
  position: fixed;
  top: 0;
  left: 0;
  transition: .5s; /*ヘッダーが0.5秒かけて動く*/
}
.hide{
  transform: translateY(-100%); /*マイナス方向(上方向)に元の高さ(100px)の100%分移動する*/
}
```

```javascript:main.js
$(function(){
  var nowPos = 0;  //現在のスクロールポジション
  var lastPos = 0; //一つ前のスクロールポジション
  $(window).on('scroll',function(){
    nowPos = $(this).scrollTop();
    if (nowPos > lastPos) {
      if (nowPos > 400) {
        $('header').addClass('hide'); //headerタグにhideクラスを付与する
      }
    }else {
      $('header').removeClass('hide'); //headerタグからhideクラスを取り除く
    }
  lastPos = nowPos; //今のポジション値が、一つ前のポジション値となる。
  });
});

```
Notは美しくないから記号にしてみた。

VBAで条件を反転する場合、

```VBA
IF Not(条件) THEN
    実行文
ENDIF
``` 
というは、美しくないので、数学の記号をつかう。

```VBA
IF ￢(条件) THEN
    実行文
ENDIF
````

種は、ユーザ定義関数で、Notを再定義してみた。

```VBA
Function ￢(A)
    ￢ = Not (A)
End Function
```

但し、記号でも関数名に使えるもの、使えないものがあるようだ。
これから申し込みができる７月８月のおススメイベント

これから申し込みができるイベントについてお勧めのものをご紹介します。

お子さんともいかがでしょうか
========================================
日本科学未来館　オープンラボ夏休みスペシャル 「研究エリア」一挙公開！2019
7月26日(金)、27日(土)、8月23日(金)、24日(土)
https://www.miraikan.jst.go.jp/event/1907261024447.html
ロボットや生命科学の研究室を見学できます。
事前申し込み不要ですが、それだけに早めに行くことをお勧めします

Maker Faire Tokyo
2019/08/03（土）～08/04（日）
https://makezine.jp/event/mft2019/
東京ビッグサイト
日本中のつくる人たちが集まってきています。
つくるための子供向けワークショップも数多く企画されています

夏休み航空企画『ひこうきの話をきこう！2019』
2019年8月7日（水）・8月15日（木）・8月23日（金）
https://fanfun.jaxa.jp/event/detail/14794.html
JAXA調布航空宇宙センター
プリントが配布されるので自由研究にも使えます

【未経験者歓迎】中高生のためのプログラミング教室
2019/08/24(土) 10:00 〜 17:00
https://connpass.com/event/139738/
東京工業大学大岡山キャンパス南4号館S421
Javascriptでゲームを作ります。
保護者の見学も可能です。

Webのあれこれを知りたい方にお勧めします
========================================
Meguro.ts v0.0.1
2019/08/01(木) 19:30 〜 22:30
https://megurots.connpass.com/event/138047/
抽選（2019/07/26）
株式会社ドリコム　カフェスペース（下目黒）
TypeScript についてのイベントです

表参道Web勉強会『Vue.js/PWA/JavaScript…新&定番なんでもあり』Vol.7
2019/08/07(水) 19:00 〜 21:00
https://connpass.com/event/137526/
先着順
ジーズアカデミー（北青山）
５分単位の発表なので気軽に聞けると思います

PWA Night vol.7 ～PWAのミライや活用方法をみんなで考えよう～
2019/08/21(水) 19:00 〜 22:00
抽選（2019/07/31）先着順枠もあります
Yahoo! Lodge（千代田区紀尾井町）
Yahoo! JAPANトップページにおけるPWAの取り組みの話が聞けます

UI/UX/デザインに関心のある方にお勧めします
========================================
【東京】UX JAM' 01 - UX Girls Special -
2019/08/06(火) 19:30 〜 22:00
https://uxmilk.connpass.com/event/139769/
抽選（2019/07/30）
株式会社メンバーズ　ラウンジスペース（晴海）
Girlstとありますが、今回の発表者が女性しばりという意味です。

LINE CREATIVE Meetup #1.5
2019/08/08(木) 19:00 〜 21:30
https://linedesignermeetup.connpass.com/event/137042/
抽選（2019/08/01）
LINE株式会社社内カフェ（新宿）

運用、DockerやKubernetesに関心のある方にお勧めします
========================================
Cloud Native Meetup Tokyo #9特別編 feat.Kaslin Fields
2019/08/07(水) 19:00 〜 22:00
https://cloudnative.connpass.com/event/137868/
抽選（2019/07/26）
日本オラクル株式会社（青山）
メインセッションは「漫画で分かるコンテナ技術」

ssmjp 2019/08
2019/08/06(火) 19:30 〜 21:30
https://ssmjp.connpass.com/event/139161/
抽選（2019/07/30）
DMM.com（六本木三丁目）
今回はパネルディスカッション

いろんな言語に触れたい方にお勧めします
========================================
みんなのPython勉強会#48
2019/08/08(木) 19:00 〜 21:00
https://startpython.connpass.com/event/124253/
先着順
新虎通りCORE（新橋）
初心者でも参加しやすそうです

Go 1.13 Release Party in Tokyo
https://gocon.connpass.com/event/139024/
抽選（2019/08/16）
株式会社メルカリ（六本木ヒルズ）
Go 1.13のリリースお祝い

仮想現実、複合現実に関心のある方にお勧めします
========================================
xR Tech Tokyo #17 @ メルカリ
2019/08/18(日) 12:00 〜 18:00
https://vrtokyo.connpass.com/event/137007/
抽選（2019/08/02）
株式会社メルカリ 18F（六本木ヒルズ）
夏の xR 祭り！
いろいろと体験できそうです


AIに関心のある方にお勧めします
========================================
【増席】AI勉強会～Actionable AI～ vol.2
2019/08/21(水) 19:00 〜 22:00
https://aai.connpass.com/event/133736/
先着順
MACNICA 品川オフィス
このところAI界隈でのマクニカさんは積極的です

Chainer Meetup #10 【強化学習】
2019/08/31(土) 13:30 〜 19:00
https://chainer.connpass.com/event/134839/
抽選（2019/08/16）
Preferred Networks（大手町）
ハンズオンではないので話を聞きに行くだけで大丈夫です。
事前に↓のチュートリアルを見ておくと楽しいかも
https://tutorials.chainer.org/ja/

量子コンピュータに関心のある方にお勧めします
========================================
第二回　QCX
2019/08/07(水) 17:55 〜 21:00
https://qri.connpass.com/event/136126/
抽選（2019/07/25）
Google Japan（六本木ヒルズ）
基礎と原理の解説から始まるので予備知識がなくてもOKだと思います。
でも中身は相当に濃そうです。
Rails DBの値の確認 {初心者}

#はじめに
自身の為めと同じ様な初学者向けにです。
とても当たり前の内容になっております。

#開発環境
・Ruby 2.5.5
・Rails 5.2.3
・エディタ VSCode

#今回の本題
.Railsでの開発中にサンプルでテーブルに入れたレコードを確認するときに個人的によく使うメソッドを記入していきます。

#方法
・まずお使いのエディタなどのターミナルで

```Ruby
rails console
#省略して
rails c #と書けます。
```

・railsコンソールが立ち上がります。
<img width="799" alt="スクリーンショット 2019-07-18 0.08.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426020/2ee29406-7f70-e1ca-1cfb-7de02ce369bd.png">
・そしてmodel名を入れて検索します。
・例として
・Userモデルがあったとします。

```Ruby
#Userテーブルのレコードを全件取得してる。
User.all
#Userテーブルのレコード数を取得
User.count
#Userテーブルの最初のレコードを取得
User.first
User.last #とすると最後のレコードを取得
#Userテーブルのidがn番のレコードを取得
User.find(n) #nには任意の数字を入れて下さい
#Userテーブルのid以外でのレコード検索
User.find_by(name: "admin")
#Userテーブルのレコードを全件削除
User.delete_all
```
・おまけとして
・Userモデルに1:1で紐付いているProfileモデルがあったとします。

```Ruby
#Userモデルに紐付いているProfileモデルの最初のレコードを取得
User.first.profile
#更に1:nでpostテーブルが紐付いていても同様です。
User.first.profile.posts
```

・コンソールの終了のさせかた
・control + D
または

```Ruby
exit
```
で終了出来ます。

#以上です

・今回書いたのはあくまで一部です。
・本来目的別にちゃんとメソッドがあり自分自身メソッドを使っていける様にならなければ。。。

・この方の記事がとても参考になります。
https://ruby-rails.hatenadiary.com/entry/20140724/1406142120
荒れていると思う波が、綺麗な正弦波であるかもしれない。仮説（146）

波形を見て、荒れていると思っても、フーリエ変換してみて、
綺麗な正弦波の重ね合わせにすぎないことを経験すると、
荒れているという言葉は発しなくなるかもしれない。

 <この項は書きかけです。順次追記します。>

物事を、分析するのは、分けることから始まる。

波形を周波数で分けて、それぞれの周波数ごとの波形は正弦波になるようにする。

線形なものは荒れていない。
非線形なものでも、上を線形な数値解があり、下にも線形な数値解があり、２つで挟み込むことによって、近似な数値解が求まるかもしれない。

# 理論

離散フーリエ変換、逆離散フーリエ変換
https://qiita.com/uyuutosa/items/9124d94aa56ccc136072

離散フーリエ変換
https://qiita.com/AIKI_SHI/items/772f516f4f3f97c44f0e

量子フーリエ変換の導出と高速フーリエ変換よりも早くなる理由
https://qiita.com/ground0state/items/df43cc5179b48ae72dbe

量子コンピュータでフーリエ変換すると高速フーリエ変換より高速な件
https://qiita.com/piyo7/items/d6f95876c7ec0188f991

ラプラス変換とフーリエ変換の関係
https://qiita.com/kaityo256/items/aa5b24904577de40016e

短形パルスのフーリエ変換と離散フーリエ変換の違い
https://qiita.com/yamadasuzaku/items/c7f674ab207b73480c93


# python

量子フーリエ変換
https://qiita.com/YuichiroMinato/items/e51182443febed5b429d

sympy で量子フーリエ変換
https://qiita.com/41semicolon/items/dd7f9d6edcdfa3fb82b6

Python: 離散フーリエ変換の実装
https://qiita.com/sai-sui/items/9650ff14af54dd147a39

【Python】ただひたすらにフーリエ変換【備忘録】
https://qiita.com/Kuma_T/items/74c149b00428f820b24c

# C++
OpenCV(C++)チュートリアル：離散フーリエ変換
https://qiita.com/exp/items/5c4bcd650e0e2ae26cc4

# C＃
フーリエ変換
https://qiita.com/Apeworks/items/879930c10919ea93d299

「自力で」フーリエ変換
https://qiita.com/GCLemon/items/8fd3f29a8ec8cdaf675a

# JavaScript
高速フーリエ変換FFTを理解する

https://qiita.com/bellbind/items/ba7aa07f6c915d400000

# QCEngine

http://machinelevel.com/qc/doc/qcengine_workbench.html

量子フーリエ変換 自分用まとめ

https://qiita.com/N-H-Shimada/items/335580d208b6126f4c88

# 関連資料

人生で影響を受けた本100冊。Youtube(3)

https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

アンの部屋（人名から学ぶ数学：岩波数学辞典）英語(24)

https://qiita.com/kaizen_nagoya/items/e02cbe23b96d5fb96aa1

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿　20190717
ver. 0.02 非線形追記 20190718
ver. 0.03 関連資料追記 20210904

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
ubuntu 環境でpdf 形式の画像を切り抜く方法（pdfcrop 使用）

## コマンド
入力ファイル名には適時自身が切り抜きたいpdfファイルのファイル名を入力

```
$ pdfcrop [入力ファイル名].pdf
```

切り抜き結果は[入力ファイル名-crop.pdf] に保存される

## 参考
[TeX Wiki pdfcrop](https://texwiki.texjp.org/?pdfcrop)
selectタグ　opition　都道府県一覧　（hamlバージョン）

# opitionタグ　都道府県一覧(hamlバージョン)

```
%option{ value: "1"} 北海道
%option{ value: "2"} 青森県
%option{ value: "3"} 岩手県
%option{ value: "4"} 宮城県
%option{ value: "5"} 秋田県
%option{ value: "6"} 山形県
%option{ value: "7"} 福島県
%option{ value: "8"} 茨城県
%option{ value: "9"} 栃木県
%option{ value: "10"} 群馬県
%option{ value: "11"} 埼玉県
%option{ value: "12"} 千葉県
%option{ value: "13"} 東京都
%option{ value: "14"} 神奈川県
%option{ value: "15"} 新潟県
%option{ value: "16"} 富山県
%option{ value: "17"} 石川県
%option{ value: "18"} 福井県
%option{ value: "19"} 山梨県
%option{ value: "20"} 長野県
%option{ value: "21"} 岐阜県
%option{ value: "22"} 静岡県
%option{ value: "23"} 愛知県
%option{ value: "24"} 三重県
%option{ value: "25"} 滋賀県
%option{ value: "26"} 京都府
%option{ value: "27"} 大阪府
%option{ value: "28"} 兵庫県
%option{ value: "29"} 奈良県
%option{ value: "30"} 和歌山県
%option{ value: "31"} 鳥取県
%option{ value: "32"} 島根県
%option{ value: "33"} 岡山県
%option{ value: "34"} 広島県
%option{ value: "35"} 山口県
%option{ value: "36"} 徳島県
%option{ value:"37"} 香川県
%option{ value: "38"} 愛媛県
%option{ value: "39"} 高知県
%option{ value: "40"} 福岡県
%option{ value: "41"} 佐賀県
%option{ value: "42"} 長崎県
%option{ value: "43"} 熊本県
%option{ value: "44"} 大分県
%option{ value: "45"} 宮崎県
%option{ value: "46"} 鹿児島県
%option{ value: "47"} 沖縄県
```
capybara-webkitがbundle install出来ない時の対処法

#はじめに
会社でcapybara-webkitを使っているのですが、環境構築の際ほとんどの人がcapybara-webkitのインストールで詰まっていたので再現性のある対処法を書きました


#対処
もし既にバトっていてqtをbrewインストールしてしまっていたなら、qtを削除してください

```
$ brew uninstall --force qt
```
こちらの本家から直接dmgファイルをダウンロードして、インストールしてください。
https://download.qt.io/archive/qt/5.5/5.5.0/qt-opensource-mac-x64-clang-5.5.0.dmg


qmakeのpathをbash(またはzsh)に追加してください。 e.g. ~/.bash_profile

```
export PATH="/Users/username/Qt5.5.0/5.5/clang_64/bin/:$PATH"
```

ターミナルを再起動またはsourceコマンドを実行した後、cmakeが存在するか確認してください。

```
$ wich cmake
```


Xcodeのバージョンが8.0以上の場合, qtフォルダ以下の設定ファイルを一部書き換える必要があります。

```
$ vi /Users/your-username/Qt5.5.0/5.5/clang_64/mkspecs/features/mac/default_pre.prf
```

`isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null")))`
を

`isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null")))`
に置き換えてください。


```
$ sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
```
を実行した後

```
$ sudo xcodebuild -license
```
を実行し、ライセンスの長い説明文が出てくるので、一番下に来るまで`space`を押して、最後に`agree`と入力してください。

最後に

```
$ bundle install
```
して終わりです。

#参考文献
https://github.com/thoughtbot/capybara-webkit/issues/1072
https://stackoverflow.com/questions/33728905/qt-creator-project-error-xcode-not-set-up-properly-ou-may-need-to-confirm-t
「OSError: [WinError 127] 指定されたプロシージャが見つかりません。」が出たときもしかすると役に立つかもしれない話

python の anaconda 環境を整えた後、「OSError: [WinError 127] 指定されたプロシージャが見つかりません。」とのエラーが発生し、解決まで時間がかかったので、メモしておきます。

#環境概要
・Windows7-32bit
・Anaconda3-32bit
・(Windows\System32 の)zlib.dll (1.1.4.0)
等々

#現象
・Anaconda Navigator 起動せず
・Anaconda Powershell Prompt で conda コマンドを打つと、上記のエラーが発生
・Anaconda Prompt でも同様。ただしこちらは更に以下がポップアップ
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69125/15553eb7-6b73-3d67-7e68-a0545c98496f.png)

#解決策
・(Windows\System32 の)zlib.dll を (1.2.5.0)で置き換え
MySQL Workbench で使用していたものを持ってきました＾＾；

#愚痴
Anaconda Navigator が立ち上がらないとか、諦めようかと思いましたｗ
解決のヒントが Anaconda Prompt でコマンド投入したときにしか表示されないので、たどり着けて運が良かったです。。。

環境が古いので、あまり役に立てる機会はないと思いますが、備忘も兼ねて。
Vue.js で自作した確認ダイアログで、ユーザーの返答を Promise を使って待つ

自分用の備忘録的に…

![l9xrz-uga97.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156563/0a355563-aed4-838e-2636-804cda83356d.gif)

まず、完成したのはこんなのです。よくあるTODOリストだけど、いちいち確認してくるモーダルのダイアログが追加時と完了設定時に入っています。（メンディ）

素直に実装するなら、TODO追加ボタンのonclickにダイアログの表示処理、ダイアログの「はい」ボタンのonclickにTODO追加の処理を書いていくことになると思います。でもそれだと同じダイアログを別の動作の中で使いまわすのも辛そうですし、後からコードを見た時に一連の動作が追いづらくなりますよね:cry:

そこでこんな実装にしてみました :bulb: 

```vue
<template>
  <div>
    <form @submit.prevent="doAdd">
      <input type="text" v-model="title">
      <button>add</button>
    </form>
    <ul>
      <li v-for="(todo, i) in todos" :key="i">
        <span class="todo-title" :class="{'done': todo.done}">{{todo.title}}</span>
        <button @click="doMarkAsDone(i)" v-if="!todo.done">done</button>
      </li>
    </ul>
    <div class="modal" v-if="isShowConfirmModal">
      <div class="overlay"></div>
      <div class="modal-container">
        <div class="modal-body">
          <p>マ？</p>
          <button @click="$emit('answerdConfirm', true)">はい</button>
          <button @click="$emit('answerdConfirm', false)">いいえ</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      title: '',
      todos: [],
      isShowConfirmModal: false,
    };
  },
  methods: {
    async doAdd() {
      if (!await this.askConfirm()) return
      this.todos.unshift({
        title: this.title,
        done: false,
      })
      this.title = ''
    },
    async doMarkAsDone(todoIndex) {
      if (!await this.askConfirm()) return
      this.todos = this.todos.map((todo, index) => ({
        ...todo,
        done: index === todoIndex || todo.done,
      }))
    },
    askConfirm() {
      this.isShowConfirmModal = true
      return new Promise(resolve =>
        this.$once('answerdConfirm', confirmValue => {
          this.isShowConfirmModal = false
          resolve(confirmValue)
        })
      )
    },
  },
}
</script>

<style>
...
</style>
```

いろいろ荒いけど…

ポイントは、確認モーダル表示メソッド（ `askConfirm()` ）でモーダルを開きつつ、 `Promise` を返しているところです。
ユーザーが「はい」か「いいえ」のどちらかをクリックすると、 `$emit` でイベントが発行され、それを `$once` が受け取ると、先ほど返した `Promise` が解決されます。
このようにすることで、TODO追加メソッド（ `doAdd()` ）、TODO完了設定メソッド（ `doMarkAsDone` ）のどちらでも、処理の一連の流れを分断することなく、ユーザーがダイアログで入力した値を受け取ることができます。

以上！
Gem(Cancancan, pundit,Banken)を使わずにymlを使った権限管理機能実装方法

環境
Ruby 2.5
Rails 5.2.4

##実現したいこと
以下の３種類の役割があるとします。
RoleA → フル権限(GET,PUT,PATCH,DELETE)
RoleB → 全ページの閲覧とデータが更新ができる(GET,PATCH)
RoleC → データは更新できないが、全ページの閲覧が可能

この条件で各ページ、メソッド単位で各機能ごとに細かく権限管理したい。(仕様によりがっつりとrequestパラメーター使えない)


**前提**
UserはActiveRecordを使用しておらず、外部サービスで作られ、データも外部で保持されており必要に応じてRailsから参照しています。それに伴い私にはDeviseのGemが使えなかったためYmlを使用しようと思いました。

```ruby

current_user[:role]　# roleB
で現在のユーザーのroleを取得することはできます。
```

```ruby

各ページごとのidを取得することができます。
params[:page_name] # page_a
```
この二軸で判定を行います

### 1. ymlを作成する

/config/previlege.ymlを自分で作成し権限とページの軸で記述していきます。




```ruby:previlege.yml 
1はフル権限(GET,PATCH,POST,DELETE)
2は参照と更新のみ(GET,PATCH)
3はアクセス権なし（記載がなければ自動的に3扱い）


roleA:
  page_a: 1
  page_b: 1
  page_c: 1
  page_d: 1
roleB:
  page_a: 1
  page_b: 1
  page_c: 2
  page_d: 2
roleC:
  page_a: 2
  page_b: 2
```

```ruby:config/initializers/previlege.rb

file = File.read("#{Rails.root}/config/previlege.yml")
PREVILEGE = YAML.safe_load(file, [] , [], true)

```

ここまででymlを定義し定数として使えるようになりました。
以下のようにしてハッシュで取れます。

```ruby

例
puts PREVILEGE[:roleB]
=> {  page_a: 1
      page_b: 1
      page_c: 2
      page_d: 2 }
```

```ruby:app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  helper_method :current_user # helperでcurrent_userが使える

  private
  def current_user
    # 省略=> roleが返ってくる
  end
  
  def judge_previlege
　　　if PREVIREGE[current_user[:role]][params[:page_name]] == 1 
       true
     elsif PREVIREGE[current_user[:role]][params[:page_name]] == 2 && request.patch? || request.get?
       true
     else 
       return redirect_to root_path, flash[:error] = "権限がありません"
     end
  end
end


```

before_actionでメソッドを使う

```ruby:app/controllers/posts_controller.rb
class PostsController < ApplicationControler
  before_action :judge_previlege

  def index
    省略
  end

  def update
    省略
  end

end

```
こんな感じでコントローラーの制御はできます。
備忘録で大雑把に書いていますので、気に入っていただけたらあとは応用してもらうのが良いかと思います。


viewの出し分けは

```ruby:app/helpers/application_helper.rb
module ApplicationHelper


  def showrable?
     if PREVIREGE[current_user[:role]][params[:page_name]] == 1 || PREVIREGE[current_user[:role]][params[:page_name]] == 2
       true
     else
       false
     end
  end

  def clickable?
    if PREVIREGE[current_user[:role]][params[:page_name]] == 1
      true
    else
      false
    end
  end
end
```


```ruby:index.html.erb

表示するか
 if showrable?
   表示させる
 end

クリックできるか
link_to_if(clickable?, "リンク",hoge_path)
```

以上になります
間違えている可能性ありますので(特にviewあたりは適当です....)、参考程度でお願いします...
コピペエンジニアあるある～人のふり見てわがふり直せ

# はじめに
最近、私のいる開発チーム内にコピペエンジニアが続出してます・・・:sweat_drops:
私個人としては、「コピペ＝悪」とは思ってません。
ほぼ毎回ググってる`inputStream`的なものはコピペでもいいと思うし、コピペしてもらうと、案件内のソースコードに統一性が生まれて保守しやすくなるメリットがあると思います。

だけど、何も考えずにコピペするのだけはやめてほしい:angry:
読みづらい上に、バグだらけなんですもん:droplet:

というわけで、「コピペするなら、せめてこれくらいは意識してよ」って思ってることをまとめてみます。

## おことわり
- コピペの善悪を問いたい記事ではありません。
- 個人の体験に基づく主観が **大いに** 含まれます。
- 「『あ、俺のこと・・・？』って思ってもらえたら、少しはダメコピペ減るかな」という期待を込めて書きました:sweat_smile:

# １．変数名・メソッドがおかしい。
コピペったままなので、（例えば）コピペ元が「tel」だったら「tel」のまま。
本当は「mail」かもしれないのに「tel」のまま。
「とりあえず動けばいい、思ったとおりに動いてほしい」としか考えてない人が多いと思う。
あとで読み返したときに、「なんでメアドを格納する変数がtelなんだ？」みたいになって、めちゃくちゃ混乱する。
メソッド名も同様で、`getMail()`なのに、なぜか電話番号が返ってくるようなソースをたまに見かける・・・。

# ２．エラーメッセージなどの定数が間違ってる。
プロパティファイルからkeyコードを使って固定のメッセージを取得するような処理でよく見かけます。
ひどいのだと、日本語でべた書きしてるメッセージすらコピペったままになってて、正常系なのに「エラーが発生しました」になってることも・・・。
※「メッセージの類をべた書きするな」というのは、今回はスルーします :bow:

# ３．static定数が乱立・増殖する。
とりあえずコピペってくるので、クラス定数とかがなければエラーになっちゃう。
「だったら、定数もコピペればいいじゃん:thumbsup_tone3:」って感じなんでしょうね。
そうやって、各クラスに全く同じ名前で同じ内容のstatic定数が増殖していくわけです。
最初2～3個なら、見つけ次第Enumとかプロパティファイルに押し込むんですが、保守系プロジェクトとかになると増殖しすぎてて、逆に「このまま増殖させた方がいいんじゃないか」って思い始めるくらい:disappointed_relieved:

お願いなので、定数っぽいものをコピペしたくなったら、「どこかで誰かが汎用的に使えるように定義していないか」を確認してください:bow:

# ４．JavaDocが間違ってる。
JavaDocは、「正式なプログラム仕様書として成立する」もの。
なのに、どこかからコピペってきたままだったり、デフォルトで生成されたままだったりする。
そのせいで、実際のソースの動きとJavaDocの日本語がずれていることがしばしば・・・。
手前味噌ながら、JavaDocとコメントの違いはこちら :arrow_down: を見て下さい。
:link: [【Java】コメントの種類と書き方](https://qiita.com/mtanabe/items/2e52e6e162d28df8437f)
数か月後にそのJavaDoc見て「誰だ、こんな嘘っぱち書いたやつは！」って多分自分で言いますよー！！

# ５．動作は理解してない。
当たり前のように「なんか、こう書いたら動きました」って言うよね:cold_sweat:
でも、それ「書いて」ないから。「コピペした」だけだから。
このタイプは、「これって、なんでこんな書き方したん？」って聞くとフリーズすることが多いですね。

# ６．バグが残ってても気づかない。
前述の「５．動作は理解してない。」と同様です。
理解してないから、バグも一緒にコピペっても気づかない:disappointed_relieved:
あと、「コピペ元だとそれでいいけど、コピペ先ではその仕様は間違ってるからバグになってしまった」ってこともあります。

お願いだから、ちゃんと理解してください。ホントに・・・。

# ７．エラーが出たときに最初に思うのは「コピペミスしたかも？」で、エラーメッセージは見ない。
エラーメッセージ見たほうがよっぽど早いのに、彼らはコピペミスを疑って、真っ先にコピペ元ソースと見比べに行きます:disappointed:
たいていの場合、しばらく悩んだ後で「あの・・・。ここのソースがエラー吐いてるんですけど、コピペ元とは寸分の狂いもないんですけど・・・」って質問しにくるパターンが多い気がします。
とりあえず、エラーメッセージ読んでから質問しに来てください・・・。

また手前味噌でアレなんですが、エラーメッセージの読み方の参考になれば幸いです:point_down_tone3:
:link: [【Java】エラーメッセージをちゃんと読んでいますか？【スタックトレースの読み方】](https://qiita.com/mtanabe/items/3bc2ecddd5e0c9a052f2)

# おわりに
最初に書いた通り、「コピペ＝悪」じゃないと思ってるので、コピペ自体はしてもいいと思ってます。
コピペすることで、先人たちのよいソースコードも勉強できると思うしね。

だけど、コピペであっても「作ったのはあなた」です。
うっかりバグを仕込んでしまったら、それは「あなたのせい」だと思います。
要は「自分の書いたコードに責任を持てよ」ってことです:thumbsup_tone2:

とかなんとかエラソーなこと書きましたが、自分もうっかりコピペすることあるので気を付けたいなぁと、改めて思いました:sweat_smile:
エンジニアの健康問題に対する簡単な対処法(姿勢編)

## エンジニアの健康問題について(姿勢編)
エンジニアは肉体労働ではありませんが、PCの前で同じ姿勢をキープして集中し続けることは腰や肩に大きな負担を与えます。

基本的な対処法は二つあります。（二つとも行った方が良いですが。）私はどちらも行っています。

## 1. 運動を習慣にする
基本ですね。ジムに通っても良いですし、お金をかけたくなければ、ランニングをしましょう。
## 2. 立って作業できるデスク周りの環境を構築する
スタンディングデスクというやつですね。専用のものでも良いですが、適当な場所を見つけて立って作業しても良いです。

## まとめ
他にも良い椅子を使うなどもあります。皆さんも健康にはお気をつけて下さい。体を動かすと頭も冴えますよ。

## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
[Flutter備忘録] AppBarを使用するときにステータスバーの色を変更する方法

# 概要
AppBarのbackgroundColorをwhiteにしたとき、
ステータスバーの色を白から変えることが全っ然うまくいかなかったのでメモ

正直、実装が正しいのかわからないけど
とりあえず実現したいようにはなった

## 調べてたくさん出た解決策

「Flutter status bar color」とかで調べまくったら、海外のサイトに
こうやればいいよ。的なのは簡単に見つかるんだけどAppBarを使用している自分のアプリだと反映されなかった。

``` dart
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
```
普通であれば、これをbuildの時に書けばいいらしい。
ただ、AppBarを使用しているとこのように全く反映されない。
<img width="364" alt="スクリーンショット 2019-07-17 23.21.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413778/b0dcead9-3ace-743d-616c-62e8d1d138d8.png">
背景白だと消えて見えるね。


## AppBarを使用する時
ぐぐっても見つからなかったので、とりあえずFlutterの中でなにやっているか確認してみた

```dart
    final SystemUiOverlayStyle overlayStyle = brightness == Brightness.dark
      ? SystemUiOverlayStyle.light
      : SystemUiOverlayStyle.dark;
```
app_bar.dartの中でSystemUiOverlayStyleを上書きしてるっぽくて
これのせいで、白に戻っていた。

なので、とりあえずこの条件式に合うように

```dart
    appBar: AppBar(
      backgroundColor: Colors.white,
      brightness: Brightness.light,
    ),
```
<img width="383" alt="スクリーンショット 2019-07-17 23.26.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413778/bcbb9264-6278-69e0-fe49-60db2e89f058.png">

一応うまくいっているようには見える。
ただ、`brightness`がどのような仕様かは調べてないので
自己責任でお願いします。
brightness...輝度？
[初心者]Railsで管理者権限付与してみた

今回の管理者は管理者としての行動があまり多くないため、基本はエンドユーザーと同じ画面で、管理者権限持ちのユーザーの表示が変わるようにしました。
#前提
devise を使用してのUser登録機能作成済み
#環境
Ruby 2.5.5
Rails 5.2.3
#カラム追加
Userに`rails g migration: AddColumnToUser admin:boolean`でadminカラムを追加します。

```ruby:xxx_add_column_to_users.rb
class AddColumnToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :admin, :boolean , default: false
  end
end
```
管理者権限は基本的には付与されないのでmigrationファイルに　`default: false` を追加します。

`rails db:migrate`を実行します。
#管理者権限付与
今回はすでにいるUserに管理者権限を付与させていきます。
`rails c`でコンソール画面にいき、

```
user = User.find(1)
user.admin = true
user.save
```

これでUser1に管理者権限が付与されました。
管理者権限を剥奪したい場合は`user.admin = true`を`user.admin = false`に変えてあげるだけです。

#Viewで判断
管理者権限を与えられたら、次に管理者かどうかを判断する条件分岐文をview側で書いてあげます。今回は管理者と本人ユーザーのみに編集ページへのリンクボタンを表示されるようにしました。
ボタンを置きたいページの**controller**と**view**に以下の文を書きます。

```ruby:controller
@user = User.find(params[:id])
```

```ruby:view
<% if user_signed_in? %>
  <% if current_user == @user || current_user.admin? %>
    <%= link_to "編集", edit_user_path(@user.id) %>
  <% end %>
<% end %>
```

解説します。
まず`<% if user_signed_in? %>`でユーザーがサインインしているかどうかを調べ、一つ目の条件分岐とします。これでログイン済みユーザーのみが次の`<% if current_user == @user || current_user.admin? %>`へと進めるようになりました。

`<% if current_user == @user || current_user.admin? %>`で現在のユーザーが@userかどうか、もしくはadminカラムがtrueかfalseかを調べます。
これで現在のユーザーが@userか、`admin = true`の場合は編集ページへのリンクが表示され、そうでない場合は何も表示されない状態ができました。

#Controllerで判断
管理者のみが閲覧できる特定のViewを作ります。

```ruby:users_controller
class UsersController < ApplicationController
  before_action user_admin, only: [:index]

  def index
      @users = User.all
  end

  private
    def user_admin
       @users = User.all
       if  current_user.admin == false
           redirect_to root_path
       else
           render action: "index"
       end
    end
end
```

UsersControllerに以上の記述をすることで、`index`にはadminカラムがtrueのユーザーのみがリンクできるようになり、adminカラムがfalseのユーザーは`/`に指定したページへとリダイレクトされるようになりました。
#まとめ
今回は管理者のやることが少ない前提で管理権限を付与しましたが、本来なら`devise`を使う段階で`enduser`と`admin`の二つに分けてログイン機能を作り、`namespace`を使って管理者用画面を作るべきだと思います。
【VBA】ハイパーリンクを作成するフォーム

```vb:フォーム
Private Sub CommandButton1_Click()
    Call エクセル
End Sub

Private Sub CommandButton2_Click()
    Call ファイル
End Sub

Private Sub CommandButton3_Click()
    Call その他
End Sub

Private Sub TextBox1_Change()
     Path = TextBox1.Text
End Sub

Private Sub TextBox2_Change()
     File = TextBox2.Text
End Sub

Private Sub TextBox3_Change()
    Sheet = TextBox3.Text
End Sub

Private Sub TextBox4_Change()
    Cell = TextBox4.Text
End Sub

Private Sub TextBox5_Change()
    Title = TextBox5.Text
End Sub

Private Sub UserForm_Initialize()
    Cell = "A1"
    Sheet = "Sheet1"
End Sub
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404228/b67541cf-cdaf-b154-647b-5f65b4d4359e.png)

```vb:ThisWorkbook
Private Sub Workbook_Open()
    Dim objCB As CommandBar
    Dim objCBCtrl As CommandBarControl

    Set objCB = Application.CommandBars("Worksheet Menu Bar")

    On Error Resume Next
    objCB.Controls("ハイパーリンク").Delete
    On Error GoTo 0

    Set objCBCtrl = objCB.Controls.Add(Type:=msoControlButton)
    
    With objCBCtrl
        .Caption = "ハイパーリンク"
        .FaceId = 277
        .OnAction = "ユーザーフォーム"
    End With
End Sub
```
```vb:標準モジュール
Public Path As String
Public File As String
Public Sheet As String
Public Cell As String
Public Title As String

Sub ユーザーフォーム()
    UserForm1.Show vbModeless
End Sub

Sub エクセル()
    ActiveCell.FormulaR1C1 = "=HYPERLINK(""[" + Path + "\" + File + "]" + Sheet + "!" + Cell + """, """ + Title + """)"
End Sub

Sub ファイル()
    ActiveCell.FormulaR1C1 = "=HYPERLINK(""" + Path + "\" + File + """, """ + Title + """)"
End Sub

Sub その他()
    ActiveCell.FormulaR1C1 = "=HYPERLINK(""" + Path + """, """ + Title + """)"
End Sub
```
Leetcode #445: Add Two Number II

```swift
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
    var s1 = [Int]()
    var s2 = [Int]()
    var l1 = l1
    var l2 = l2
    while l1 != nil {
        s1.append(l1!.val)
        l1 = l1?.next
    }
    while l2 != nil {
        s2.append(l2!.val)
        l2 = l2?.next
    }
    let dummyNode = ListNode(0)
    var current = dummyNode
    var carry = 0
    while !s1.isEmpty || !s2.isEmpty {
        let val1 = s1.popLast() ?? 0
        let val2 = s2.popLast() ?? 0
        let sum = (val1 + val2 + carry) % 10
        carry = (val1 + val2 + carry) / 10
        let node = ListNode(sum)
        node.next = dummyNode.next
        dummyNode.next = node
    }
    if carry != 0 {
        let node = ListNode(carry)
        node.next = dummyNode.next
        dummyNode.next = node
    }
    return dummyNode.next
}
```
Rails初心者が知っておくべきデバッグコマンド

先輩に質問したとき困らないようにこれだけは知っておけ的デバッグコマンド

## Rubyの試しうち

nodeは`node` と打てばよかったけど、
rubyは `ruby` じゃなくて `irb`！ (Interactive Rubyの略らしい）
exitかCtrl+Dで戻ります

```bash
$ irb
irb(main):001:0> 1 + 1
=> 2
$ irb
irb(main):001:0> ''.empty?
=> true
irb(main):002:0> exit
```

## コンソールで試してみて

`rails console` (エイリアスは `rails c`)
↑のirbと同じ。対話形式で、Railsアプリケーションとやり取りができます
exitかCtrl+Dで戻ります


```bash
$ rails console
irb(main):005:0> User
=> User(id: integer, uuid: string, created_at: datetime, updated_at: datetime)
```

## データベースはどうなってる？

`rails dbconsole` （エイリアスは `rails db`)
データベースの中身を確認します。
これはMySQLの例です

```bash
$ rails dbconsole
mysql > show tables; # テーブル一覧
mysql > show columns from users; # usersテーブルのカラム一覧
mysql> select * from users; # usersのデータ一覧
```

## パスはどうなってる？

`rails routes`

`config/routes.rb` で定義した全ルーティングを確認するときに役立ちます

```bash
$ rails routes
users     GET  /users(.:format)          users#index
         POST  /users(.:format)          users#create
new_user  GET  /users/new(.:format)      users#new
edit_user GET  /users/:id/edit(.:format) users#edit
```

## 変数の中身は？
`pry-byebug` を使えば、`binding.pry` を記述した地点での変数の中身を確認したり、その地点からステップ実行をしたりできます。つまりブレークポイントを打つことができる。

例えば、このようなコード（適当）を実行すると

```ruby
 def test
    hoge = 1
    binding.pry
    hoge = 2
    hoge = 3
 end
```

↓のようにコンソールで対話形式によって値を確認できます。
実際はシンタックスハイライトもついてとても見やすい！
nextで次の行へ移動、exitで戻ります

```bash
     6: def test
     7:   hoge = 1
     8:   binding.pry
 =>  9:   hoge = 2
    10:   hoge = 3
    11: end

pry> hoge
=> 1
pry> next
     6: def show
     7:   hoge = 1
     8:   binding.pry
     9:   hoge = 2
 => 10:   hoge = 3
    11: end
pry> hoge
=> 2
pry> exit;
```

使い方はこちら
[pry\-byebugでrubyをデバッグする \- Qiita](https://qiita.com/AknYk416/items/6f0bec58712edaf4940e)


## 参考
[Rails のコマンドラインツール \- Rails ガイド](https://railsguides.jp/command_line.html)
【UML】VSCode + PlantUMLでUMLを書く

## 概要
作図ツールの選択肢はいくつかありますが、下記の点に魅力を感じ、PlantUML（ http://plantuml.com/ja/ ）を選択しました。

- ソースコードから画像を出力できる
- バージョン管理できる（差分を見られる！）
- レイアウトの微調整を自動でやってくれる

## 機能
- シーケンス図、ユースケース図、クラス図、アクティビティ図、状態遷移図（ステートマシン図）などのUMLの作成だけでなく、ガントチャートやER図も作成できるようです。（私はUML以外では使用したことはありません）
- 画像の出力形式は、png, svg, eps, pdf, vdx, xmi, scxml, htmlに対応しています。
- オンラインジェネレータ（ http://plantuml.com/ja/ ）もあるので、試用の上、検討すると良いかもしれませんね！

## 準備
Visual Studio Code（VSCode）＋ PlantUMLのプラグインを使いました。

### VSCodeをインストール
https://code.visualstudio.com/ からダウンロードしてインストールします。

### Javaをインストール
PlantUMLを実行するためにはJavaが必要です。
https://java.com/ja/ からダウンロードしてインストールします。

### Graphvizをインストール
GraphvizはPlantUMLのソースファイルからUMLの画像ファイルを生成する際に必要となります。
http://www.graphviz.org/ からダウンロードしてインストールします。

### VSCodeにPlantUMLをインストール
1. VSCodeを起動
1. ウィンドウの左下にある歯車アイコンをクリックして `EXTENSIONS`を開く。
1. 検索窓に `PlantUML`と入力すると、`PlantUML Rich PlantUML support for Visual Studio Code.`が現れるので、`Install`
<img width="688" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230436/ecab1834-be7e-af71-f6fd-db26d6414164.png">
（`Ctrl + P`→`ext install plantuml`だと早いみたい）

1. VSCodeを再起動

以上で、準備は完了！

## 使い方

1.ファイルを新規作成し、`***.pu`で保存

2.試しにユースケース図を書いてみます。
詳細な説明は割愛しますが、図とサンプルコードを交互に眺めると書き方が掴めてくると思います。

```.pu
@startuml

:管理者: as admin
:一般ユーザ: as user
(ユースケース) as use

admin -> use
user ..> use

note bottom of admin : 図中にコメントを書けます
note right of use
  このユースケースは、
  サンプルです。
end note

@enduml
```

3.`Alt + D`でプレビューを見ることができます。

<img width="645" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230436/2144dcc0-91be-00aa-e46e-ffd57e3345be.png">

4.画像を出力する
`Ctrl + Shift + P`でコマンドパレットを開き、`plant`と入力すると、`PlantUML: Export Current Diagram`が表示されるので選択します。画像形式を選択すると、ファイルがエクスポートされます。

![uml.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230436/e4796095-2fb7-14ac-c687-bc29b3104de6.png)

こんな感じで簡単に図を作ることができます！

## 感想

- 最初はレイアウトが思ったように整わずもどかしいですが、慣れてくると綺麗にレイアウトできるようになると思います。（`->`を`-->`にしてみたり、`-left->`とかにしてみたり）
- gitでバージョン管理できるのは素晴らしい。切り戻しが楽！

## バージョン情報
- VSCode：1.36.1
- PlantUML：2.11.2
- Graphviz：2.38