OmniAICreator/Qiita-1.07M huggingface dataset:
MAツールとline@の連携について


現在、MAツールとline@の連携を考えております。
行いたいこととして、MAツールでユーザ情報のセグメントを設定し
そのセグメント条件をもとにline@で管理しているユーザに一斉送信を行いたいと考えております。
そこでMAツールのユーザとline@内ユーザをどのようにして紐づけするかなどが課題として挙がっています。
当初はメールアドレスをキーに紐づけることを想定していたのですが、
line@から情報を引っ張るmessaage APIではユーザID、表示名、プロフィール画像のURLの
３項目しか取得できないとのことでした。
上記、MAツールとline＠を連携するにあたってなにか良い手はありませんでしょうか
logmonが暴走する話

## logmonとは
簡単にログ監視を実現できるスクリプト。
参考：[logmon でかんたんにログ監視](https://qiita.com/inouet/items/cc1eacef237f2328e98f)

## 原因/結果
先に結果を書いておくと、
**logmon.confの中身を全て消した上でlogmonをstartすると、暴走してCPUを食いつぶす**
ということだった。
存在しないファイルでも良いので監視設定を書いておくと、こんなことにはならない。


## 現象/経緯
AWS上にWeb/APサーバを立て、AP側の人に渡したところ、
何か知らんけどAPの処理がめちゃんこ遅いので調べてほしいと言われたので調査。

cloudwatchのデータを見ていると、CPU使用率が20％あたりで張り付いていることに気づく。
EC2を再起動すると一旦APの動きは直るものの、直ぐに同じ状態になるとのことだったので、
再起動してCPU使用率を見てみると、100％近くに張り付いたあと、12％程度まで落ちて張り付くことが発覚。

LPICで勉強したリソース調査コマンドを思い出しながら調査していくものの、
どのプロセスが問題なのかわからなかったため、なんとなくでlogmonを止めた所ビンゴ。
（監視対象ログファイルがまだ存在しなかったので、logmon.confはまっさらにしていた。）
（じゃあstartするなと言われると何も言えません。。。）

## 調査データ

vmstat実行結果はこんな感じ（再現させたもの）。

○ logmonのstart直後

```
[root@XXXXXX logmon]# vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 647612   2088 306896    0    0   463   404  127  408  4  2 91  1  2
 1  0      0 647364   2088 306896    0    0     0     0  255 1891 31 69  0  0  0
 1  0      0 647364   2088 306896    0    0     0     0  254 1898 32 68  0  0  0
 1  0      0 647364   2088 306896    0    0     0     0  253 1889 30 70  0  0  0
 1  0      0 647364   2088 306896    0    0     0     0  254 1889 28 72  0  0  0
```

コンテキストスイッチがとんでもないことに。
waitが0になり、us/sysともに跳ね上がる。（bi/boが高いのはEC2作成直後だから？だと思う。）

○ logmonのstart後しばらくしたあと

```
[root@ip-172-31-37-57 ~]# vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 644340   2088 310312    0    0    65    60  223 1595 26 56 13  0  5
 2  0      0 644092   2088 310312    0    0     0     0   51  294  7  7  0  0 87
 4  0      0 644092   2088 310312    0    0     0     0   52  311  5  7  0  0 88
 3  0      0 644092   2088 310312    0    0     0     0   51  275  6  7  0  0 86
 4  0      0 644092   2088 310312    0    0     0     0   52  284  7  8  0  0 86
[root@ip-172-31-37-57 ~]#
[root@ip-172-31-37-57 ~]#
```

stealされている。これは多分aws側の処理（t2.microなので、CPUクレジットかなと予想）

○ Cloudwatch

![cloudwatch.PNG](https://qiita-image-store.s3.amazonaws.com/0/290462/0ee65a8b-4128-196a-1976-d44b7f08eadc.png)
vue.jsでウィンドウ読み込み時に関数実行したいときの書き方

##  一般的にjava scriptでウィンドウ読むときは
```
window.onload = function() {
  alert('Hello World!');
};
```
と書きます。

これを、Vue.jsに適用させる場合は、

```
methods: {
  window:onload = function() {  
   alert('koko');
  },
}
```
と書きます。

`window.onload`、`window:onload`

`.`と`:`の違いでした。
capistranoでbundleがないと言われ、コケまくるとき

AmazonLinuxでruby24が入るようになった。
それを使ってrailsアプリをあげようとcapistranoでデプロイしようとしたら

```
00:08 bundler:install
      01 bundle install --path /home/ec2-user/rails_app/shared/bundle --without development test --quiet
      01 /usr/bin/env:
      01 bundle
      01 : そのようなファイルやディレクトリはありません
      01
```

で、エラーになり進まない。
いろいろと調べるとconfigを変えたり、sshのconfigを変えたり、と出てくるが
ここでcapistrano実行中での環境変数を調べた。

``` deploy.rb
# deploy tasks
namespace :deploy do
  desc 'bundle update exec'
  task :see_env do
    on roles(:app) do |host|
      execute "cd #{fetch :deploy_to}/releases/20180********; echo $PATH"
    end
  end
end
```

を見ると、`which bundle`のパスが含まれていない。

さらに`gem environment`も確認

```
RubyGems Environment:
  - RUBYGEMS VERSION: 2.7.7
  - RUBY VERSION: 2.4.4 (2018-03-28 patchlevel 296) [x86_64-linux-gnu]
  - INSTALLATION DIRECTORY: /home/ec2-user/.gem/ruby/2.4
  - USER INSTALLATION DIRECTORY: /home/ec2-user/.gem/ruby/2.4
  - RUBY EXECUTABLE: /usr/bin/ruby2.4
  - EXECUTABLE DIRECTORY: /home/ec2-user/bin
  - SPEC CACHE DIRECTORY: /home/ec2-user/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /etc
(以下略)
```

ということで、bundleは`/home/ec2-user/bin`に入っている。

なので、capistrano実行時にpathを追加する。

``` config/deploy.rb
# Default value for default_env is {}
set :default_env, { path: "/home/ec2-user/bin:$PATH" }
```

を、追加して再度実行すると無事にbundleが動いた。
Google スプレッドシートでsnake_caseをcamelCaseに変換する

Google スプレッドシートで、snake_caseで書かれたセルの文字列をcamelCaseに変換する。


## 結論

```
=REPLACE(SUBSTITUTE(PROPER`指定のセル番号`),"_",""),1,1,LEFT(`指定のセル番号`,1))
```

### 解説
関数が適応される順に説明

例） `"foo_bar_baz"`

- `PROPER`: 文字列の単語区切りの先頭文字を大文字に変えます。`_`区切りで解釈されるので、`Foo_Bar_Baz`になります
- `SUBSTITUTE`指定した文字列中に現れる指定した文字を繰り返し置換します。これにより`_`を削除して`FooBarBaz`になります
- `LEFT`: 指定の文字列の左から今回は1文字抽出します。`foo_bar_baz`なので`f`が抽出されます
- `REPLACE`: `SUBSTITUTE(PROPER`指定のセル番号`),"_","")` で組み立てた文字の最初を、`LEFT(`指定のセル番号`,1)`で抽出した文字列で置換します。


これによって最終的に `fooBarBaz` という文字列が得られます。めでたしめでたし。

### パスカルケースの場合

```
=SUBSTITUTE(PROPER`指定のセル番号`),"_","")
```

で結果が得られます。

## だめだったやつ
最初、正規表現でいけるだろうと思って

```
=REGEXREPLACE(`セルの番号`, "(_)(.)", "\u$2")
```

と書いたのだけど、 `\u` による大文字指定が効かないようで断念した。
AWSで作成したAPIのパフォーマンスを上げるケース・スタディ

自分なりに試してみたパフォーマンスアップについて書いていきます。

# はじめに（ご注意）
以下の内容は試す際に料金が発生します。（無料範囲で出来るものもありますが）

# 構成図

以下のようにAPI Gatewayで受けてLambdaでDynamoDBに書き込むor読み込むという構成で試しました。

![Untitled Diagram.jpg](https://qiita-image-store.s3.amazonaws.com/0/214400/bb5e0728-7bd9-ccb5-a4e6-e5cd157e33fd.jpeg)

# 検証方法
ApacheBenchやJMeterを使って同時接続数とアクセス数を増大させて検証します。

# ケース・スタディ

## DynamoDBの書き込みに失敗する。
同時接続数や瞬間アクセス数が増大するとDynamoDBの書き込みに失敗するようになります。

**対処法**
・キャパシティサイズを上げる
・オートスケーリングを有効にする
・書き込み失敗時はSQSに投げておき、後でリトライできるようにする

※オートスケーリングを有効にしておいてもアクセス急増時に瞬時にスケールしてくれるわけではないので、
エラーはゼロにはなりません。ゆえにSQSでのフォローが必要となります。

## 500エラーになり、Lambdaのコードまで辿り着かない

**確認するポイント**
・スロットリングサイズ（API Gateway）
・APIキャッシュが有効かどうか（API Gateway）
・同時実行数を他のLambda関数で予約しており、残量僅かになっていないか（Lambda）

**対処法**
上記の不足している部分を上げる。優先度としては
Lambda同時実行数＞スロットリングサイズ＞APIキャッシュ
です。

# 構成図（修正後）
以下のようになりました。
SQSから取得しDynamoDBに書き込む箇所はCloudWatchの定期実行で行います。

![Untitled Diagram (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/214400/2660e182-f9a1-c8d0-3c91-d56ac5b74d92.jpeg)

# 参考
https://dev.classmethod.jp/cloud/aws/fallback-queueing-pattern-on-dynamodb/
mod rewrite だけを使って、railsをサブフォルダで動かす。

PHPとかが動いてるサーバーで、apache passengerとか使うのが少々面倒なときにサクッとrailsを動かしたいときのメモ。

#### 前提
- Apache 2.4 (with mod_rewrite)
- ruby 2.4
- rails 5.2
- pumaとか

#### 方法
apacheのドキュメントルートの適当なフォルダを作成
`mkdir /var/www/html/rails_app`

そのフォルダに.htaccessを配置、内容は

```apache:.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} index\.(html|php)

# ルートディレクトリ用
RewriteRule ^index\.(html|php)$ http://localhost:3000/rails_app [QSA,P,L]

# サブディレクトリ用
RewriteRule ^(.*)/index\.(html|php)$ http://localhost:3000/rails_app/$1 [QSA,P,L]

# for assets
RewriteCond %{REQUEST_URI} \.(css|js|ico)$
RewriteRule ^(.*)$ http://localhost:3000/$1 [QSA,P,L]

RewriteCond %{REQUEST_URI} ^/rails_app
RewriteRule ^(.*)$ http://localhost:3000/rails_app/$1 [QSA,P,L]
```

もちろんポート番号、サブフォルダ名は任意に変更。

あと、`config/environment.rb`にサブフォルダ用として、
`[rails app name]::Application.routes.default_scope = "/rails_app"`
の一文を追加。


仕組みとしては、mode_rewriteでrails serverにforwardしている。
そのままだとrailsはサブフォルダがつかないルーティングをするので、environment.rbで変更。

あとはアセットパスとかがそのままだったりするので、これもうまくforward
（このへんうまく調整できそうなもんだけどなかなかうまく行かなかった。railsのサブフォルダのやり方簡単にならんかな…）

あとは`rails s`でサーバーを起動させておくだけ。
これでちゃんとrailsの画面が表示されるはず。

もしされなかったら、rewriteルールがうまくいってない可能性があるので、
rewriteのログを出してみてもいい。

``` httpd.conf
LogLevel rewrite:trace8
```

これを追記すればエラーログにrewriteのログが出てくる。（ちょっとわかりにくいログだけど）
Active Storageについて

# これは何？
Rails5.2から利用可能になったActive Storageについて記載します。
これまではRails TutorialではCarrierwaveを使ったり、Paperclipを使ったりと正式なものがなかったですが、　Rails単体で記述ができるようになりました。

クラウドストレージはS3やGCSがメインで使われることが多いと思ってますが、それらとの連携も非常に楽なようです。

[公式ドキュメント](https://railsguides.jp/active_storage_overview.html)

# セットアップ
Active Storageを使うためには、二つのテーブルを用意する必要があります。それをまずは作ります。

`bundle exec rails active_storage:install`
`bundle exec rails db:migrate`

僕の場合はMySQLを使っているので下記のように見えてます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/ffd5080b-27e5-3106-f524-75cbf5224675.png)

また、ストレージを環境によって分岐させたいため、configの中身を触ります。

```config/storage.yml
#Test環境
test:
 service: Disk #ディスク上に保存します。
 root: <%= Rails.root.join("tmp/storage") %>

# Development環境
local:
 service: Disk #ディスク上に保存します。
 root: <%= Rails.root.join("storage") %>

# Production環境
# コメントアウトされてるS3やGCSの設定に合わせてください。
```
=> 保存先の設定

```config/initializers/storage.rb
storage_type = Rails.application.config.active_storage.service

if Rails.env == "production"
 # storage_type = 
elsif Rails.env == "development"
 storage_type = :local
else
 storage_type = :test
end
```
=> 環境ごとの分岐設定

# サンプルコード
では今回は、簡単なユーザーモデルを作成して、ActiveStorageでアバターを登録できるようにしようと思います。

```shell
bundle exec rails g model User name:string
bundle exec rails db:migrate
bundle exec rails g controller Users index new
```
=> avatar用のカラムを用意しなくていいのがポイントです。

```ruby:routes.rb
resources 'users'
```

```ruby:models/user.rb
has_one_attached :avatar
```
=> モデルクラスにて、`has_one_attached`メソッドを定義する

```ruby:users_controller.rb
def index
 @users = User.all
end

def create
 user = User.new(user_params)
 user.save
 redirect_to users_path
end

def new
 @user = User.new
end

private
def user_params
 params.require(:user).permit(:name, :avatar)
end
```
=> `:avatar`をパラメータで許可する

```erb:users/index.html.erb
<% @users.each do |user| %>
 <%= user.name %>
 <%= image_tag(user.avatar) if user.avatar.attached? %>
<% end %>
```
=> `image_tag(user.avatar)`でシンプルに呼び出し可能

```erb:users/new.html.erb
<%= form_with model:@user do |f| %>
<div>
 <%= f.label :name %>
 <%= f.text_field :name %>
</div>
<div>
 <%= f.label :avatar %>
 <%= f.file_field :avatar %>
</div>
<div>
 <%= f.submit '登録' %>
</div>
<% end %>
```

これで登録したユーザー名とアバターが一覧で見えるページができると思います。

# 一体どうなってるのか
登録した後のDBを覗いてみる。（3つサンプルを登録した）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/ef7761bd-d803-ef04-b0e4-77ec9aa58bed.png)

usersテーブルには当然avatarカラムは存在していないが、
`active_storage_attachments`に`record_id`というusersテーブルと紐づくカラムが存在している。
また、実際の写真の情報に関しては`active_storage_blobs`に保管されている。
`key`カラムがファイル名となって`storage`配下に保存されているのが確認できると思います。

# まとめ
非常に使いやすくなってるので、誰も簡単に使うことができると思います。
[Unity]Imageサイズを一発で元画像と同じに変更する方法

UnityEditor上で、Imageサイズを元画像サイズに変更する作業。

よくある作業だと思います。

毎回、RectTransformでwidthとheightに手動で数値を入力していたのですが

これってワンクリックでなんとかできないのかと疑問が沸いてきました。

RectTransformを見る限りはそのような機能は見つかりませんでした。

ではImageコンポーネントではどうなのか。

ありました。

「Set Native Size」というボタンが！

英語には盲目な私は、気付くのに時間がかかりました。

↓ Imageサイズを一発で元画像と同じに変更する方法.gif
![Imageサイズを一発で元画像と同じに変更する方法.gif](https://qiita-image-store.s3.amazonaws.com/0/148922/7908c696-ab01-99c0-5d73-ab6485f682b1.gif)
Python3 で発話システムをつくる

# 声が出なくなった

カンファレンスで無理をして声が出なくなった。診察を受けると1週間ぐらい声が出ないということで、幸いにして他の人に感染するようなものではない。

しかしながらプレゼンやら、勉強会のチューターの予定がみっちり入っているため、どうにかしなくては。

# プレゼン方法

当初、プレゼンは音楽を流して、ライブプレゼンに徹しようかと思った。
しかしながらプレゼン後の質疑応答だとか、勉強会のチューターは声が出ないと仕方がない。

なので、 Ubuntu Linux 16.04 と MS-Windows 10 で発話システムを作った。

![image](https://qiita-image-store.s3.amazonaws.com/0/139524/bfc9651e-4bc2-7f96-16b9-40ecf53d7c1b.png)

こんな感じ。


# Ubuntu Linux 16.04 + JTalk 

まずは使い慣れたやつ。



## JTalkインストール

```

sudo apt-get install open-jtalk --install-suggests 
```

## 発話テスト

```

$ echo "こんにちは" | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -ow /dev/stdout | aplay
```
 
## 音響モデルの選択

年齢相応の男性の声を使いたい。

http://mahoro-ba.net/index.php?j=1875
ここで比較してみた。
結果、標準添付のm001がいい感じ、ライセンス的にも安心のメジャーライセンス。

## Python で話す

単に、subprocess でシェルを呼び出して実行するだけ。
keyに日本語文字列を入れて、以下を実行。

```

import  subproces

subprocess.run("echo \""+key+"\" | open_jtalk -x /var/lib/mecab/dic/open-jtalk/naist-jdic -m /usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice -ow /dev/stdout | aplay "
  ,shell=True
  ,stdout=subprocess.DEVNULL
  ,stderr=subprocess.DEVNULL)

```
これを、半透明、フォントサイズ、最前面に調整したターミナルで動かす。


# 作ったコード

GitHUBにて公開しました。

https://github.com/nanbuwks/mutebreak

の superc.py です。
                     
## カウントダウン表示

カウントダウン表示については勉強会のチューターでは必要ないので、別プログラムに分けた。
以下は5分をカウントダウンするもの。

```

import time
import datetime

d1=datetime.datetime.now()
td=datetime.timedelta(seconds=300)
d2=d1+td
while True:
    time.sleep(0.01)
    c = (d2-datetime.datetime.now())
    sys.stdout.write("\033[2K\033[G%s" % c)
    sys.stdout.flush()
```

![image](https://qiita-image-store.s3.amazonaws.com/0/139524/34ba0035-c156-a2cb-b89b-43d0568bb209.png)

意味のないマイクロ秒表示。

## BGMを流す

```

$ sudo pip3 install pygame mutagen

```

として、

```

import pygame
filename='dai9.mp3'
pygame.mixer.init()
pygame.mixer.music.load(filename)
pygame.mixer.music.set_volume(0.2)
pygame.mixer.music.play(1)

```

とするとボリューム0~1の間の0.2で１回第九を演奏する。



# 作ったコード

演奏とカウントダウンをまとめてcountandkick.pyとしました。

https://github.com/nanbuwks/mutebreak

# Ubuntuでの追加設定
プレゼン画面と発話字幕画面、カウントダウンを表示しておいて、発話字幕画面とカウントダウン画面を「最前面へ」でトップに表示しておく。
プレゼン画面はImpressのスライドショーだと他のアプリの「最前面へ」よりも上位にスライドショーが表示されるので、PDF画面をスクロールしてプレゼンした。

最前面に表示しているので、フォーカスが合っていると間違えて操作をミスることがあった。

それを少しでも防ぐため、マウスオーバーでフォーカスが合うようにしておく。
「Mouse over Active window」というのだそうだ。
UbuntuでMouse over Active window
を設定するやり方は、Unity Tweak Toolで、「ウィンドウマネージャー」-「その他」-「全般」の「フォーカス動作」で「フォーカスモード」を「スロッピー(Sloppy)」にする。


# Windows 10

動作検証中

# 使っているところ

https://twitter.com/CharaDenMitz/status/1040571109102387201
IntelliJ IDEA 日本語化 起動しない 問題解決

IntelliJ IDEA 日本語化 起動しない 問題
OS:windows
IntelliJ IDEA
Pleiades日本語化プラグイン

# Pleiades IntelliJ IDEA 日本語化 起動しない問題
Pleiadesを使ってIntelliJ IDEA　を日本語化すると起動しなくて困ってた。
ググると同じ失敗をしている人が多数。
どれを試してもうまくいかなかったがようやく解決

# 原因
## Lhaplusを使っていたこと
Pleiades - Eclipse プラグイン日本語化プラグイン のZIPはLhaplusで解凍してはいけない
http://mergedoc.osdn.jp/#pleiades.html 
こちらにアクセスするとpleiades-win.zipがダウンロードできるが
よく下の方まで読むとLhaplusを使うなって書いてある。

## Lhaplusを使うとどうなるか

普通に解凍できて

```
\pleiades-win\plugins\jp.sourceforge.mergedoc.pleiades\pleiades.jar
```
もできるくせにそれを読み込もうとすると

```
Error opening zip file or JAR manifest missing : plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
```
とかいうエラーをはいてくる。あるのにないっていわれるからかなり困ってた。
ちなみにこのエラーは
idea.batの最後にpauseを書いてから実行すると得られる

pleiades-win.zipの解凍時よく見ると完全に解凍できてないっていうエラーをLhaplusがはいているが気が付かなかった。
マニュアルやエラーはちゃんと読みましょう

# 対策
普通にwindowsエクスプローラーの機能でzipを解凍し直すとOK
右クリック「すべて展開」

# 参考
Lhaplus、Lhaca、jar コマンドでは解凍不可
http://mergedoc.osdn.jp/#pleiades.html#zip-notice

JetBrains 製品の日本語化マニュアル
https://pleiades.io/pages/pleiades_jetbrains_manual.html
TinyCorePlusをHDDにインストールしようとするとFormatting /dev/fd0で止まる問題(VM上)

#問題
https://qiita.com/hachisukansw/items/3556101ce532353d80d7
の記事を参照し、ESXi6.5上の仮想マシンにTinyCorePlus v9.0をインストールしようとしたけど
Formatting /dev/fd0
と表示されたまま処理が進まなくなってしまった。

#原因
SCSIのモジュールがロードされていないため
仮想マシンに作成したディスクがマウントされていない・・・
(よくみたら/dev/fd0になってるー！)

#解決方法
SCSIのモジュールをマウントするべきだが、手っ取り早く対処するなら
仮想マシンのディスクをSCSIでなくIDEで接続してしまえばいい。

下図はvSphereWebClientでの仮想マシン設定編集画面にて
HDDをIDE接続に変更しているところ
![WS000039.JPG](https://qiita-image-store.s3.amazonaws.com/0/127302/eb432091-e5a6-81b5-b7a2-112748663987.jpeg)

IDEにしたあとで
TinyCorePlusをCDブートし、tc-installを実行すれば
下図のようにsdaが表示される。これを選択してインストールをすすめればOK
![WS000040.JPG](https://qiita-image-store.s3.amazonaws.com/0/127302/8c16c24b-14f7-9859-d51e-477349fc0894.jpeg)
React開発環境構築&デバック

+ 開発環境構築
+ デバック


#開発環境構築

##Node.js / npm導入
``` 
#nvmをクローン
git clone git://github.com/creationix/nvm.git ~/.nvm
#.bashrcに、nvmを登録
echo . ~/.nvm/nvm.sh >> ~/.bashrc
#.bashrc再読み込み
. ~/.bashrc
#nodeのインストール
nvm install stable
``` 
nvm(node version manager)の使い方
http://www.tettori.net/post/1495/

#開発環境構築
``` 
mkdir プロジェクト名
cd プロジェクト名
npm init

#webpackのインストール
npm install --save webpack

#React / Babelのインストール
#react、react-dom
npm install --save react react-don

#babel-core 、babel-loader、babel-preset-es2015、babel-preset-react
npm install --save babel-core babel-loader babel-preset-es2015 babel-preset-react

#トップページのhtmlを自動生成するPlugin
npm install --save-dev html-webpack-plugin

``` 

#もっと楽な開発環境構築
こっちをやれば一つで上記の準備をしてくれる
https://qiita.com/naohikowatanabe/items/71a8bf477216ef56a5b7

``` 
#create-react-appでいろいろ入れてくれる
npm install -g create-react-app
create-react-app [name]

cd [name]
#アプリ入れたところでNodeを立ち上げる
npm start
``` 



#デバック
vc codeで設定をする
+ debugger for chromeを入れる
+ デバックの設定
+ サーバー立ち上げ

## debugger for chromeを入れる
左メニューの`Extension`から「debugger for chrome」をインストールする

## デバックの設定
下にある`Add Cionfiguration...`でchrome launchとchrome attachを選ぶと勝手に入ってくれる

``` 
     {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome",
            "url": "http://localhost:3000",
            "webRoot": "${workspaceFolder}"
        },
        {
            "type": "chrome",
            "request": "attach",
            "name": "Attach to Chrome",
            "port": 9222,
            "webRoot": "${workspaceFolder}"
        } 
```
FIDO U2FデバイスなしでMacbookだけでFIDO U2F対応してみた

#FIDOの仕組み

> FIDOのプロトコルでは、標準的な公開鍵暗号方式を用いて堅牢な認証を実現しています。オンラインサービスへの登録時に、ユーザーのクライアントデバイスは新しい鍵のペアを生成します。秘密鍵はクライアントデバイスに保持され、公開鍵がオンラインサービスに登録されます。クライアントデバイスがチャレンジに署名することにより、秘密鍵を保持していることをオンラインサービスに証明すると、認証が完了します。クライアントデバイスに保持された秘密鍵は、ユーザーがデバイス上でロック解除を行うことで始めて使用することができます。ロック解除には、指紋の読み取り、暗証番号の入力、マイクに対する発話、2段階認証デバイスの挿入、ボタンの押下など、ユーザーにとって使いやすく安全なアクションを採用することができます。

-- [FIDO Alliance](https://fidoalliance.org/fido%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF/?lang=ja)より

TouchID(Secure Enclave Processor)はFIDOに参加していないため、互換性がないため、TouchIDあり（Touchbarあり）のMacbookでもFIDO U2Fには対応できていません。

# SOFT U2Fを使う

Githubが、FIDO U2Fのソフトウェアトークンを作っています。OSX Keychainを使ってデバイスをエミュレートしたものになるので、mac以外で利用することはできません。
これによって、FIDO U2Fのデバイスを持っていなくても、FIDO U2F

https://github.com/github/SoftU2F

## インストール

```bash
brew cask install softu2f
```

## デフォルト
デフォルトでは、FIDO端末を使わずに必要に応じて、キーが生成され、それを認証時に使用するという流れになります。

## TouchIDをつかう
SoftU2Fには、TouchID(Secure Enclave Processor)の指紋認証を間借りするオプションが用意されています。
これによって、FIDOデバイスを使っているときと同等な状態にする事ができます
READMEには記載されていないようです： https://github.com/github/SoftU2F/pull/29

使用前に下記を実行してください

```bash
/Applications/SoftU2F.app/Contents/MacOS/SoftU2F --enable-sep
```

# 実際にやってみる

## デフォルト
1. yubicoのテストページにアクセスします
<img width="1025" alt="001.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/165d680a-9a3f-3caf-8218-93fbdb89ce24.png">
2. 許可を求められるので許可します（初回のみ）
<img width="1680" alt="002.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/e98354f2-9538-d6c6-13bf-8a814373b7d7.png">
3. 認証するかどうか求められるので、`Approve`を選択します
<img width="1680" alt="003.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/711aff12-0077-dc41-bded-63e0d2ae27c6.png">
4. 認証できました
<img width="1680" alt="005.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/5882ffba-4fd1-bf68-d469-1e6749760696.png">

## TouchIDを使う
1. yubicoのテストページにアクセスします
<img width="1025" alt="001.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/165d680a-9a3f-3caf-8218-93fbdb89ce24.png">
2. 許可を求められるので許可します（初回のみ）
<img width="1680" alt="002.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/e98354f2-9538-d6c6-13bf-8a814373b7d7.png">
3. TouchIDを求められるので、TouchIDで指紋認証します
<img width="1680" alt="004.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/c118306f-a9cb-98b9-ca29-89d33d7dc649.png">
4. 認証できました
<img width="1680" alt="005.png" src="https://qiita-image-store.s3.amazonaws.com/0/9094/5882ffba-4fd1-bf68-d469-1e6749760696.png">

# ハードトークンとソフトトークンどちらを使うべき？

## softU2Fの使用上の注意
ブラウザのエクステンションとして動くため、ブラウザでは正常に動作しますが、ローカルのアプリケーションでFIDO U2F認証を求められた場合は正常に動かない場合があります。

## ハードトークン
使用時にUSBに挿さなければいけない。管理が面倒などの問題がありますが、物理的にも認証に使う端末が2要素に分かれるので、セキュリティが重視されるケースではハードトークンを利用するのがいいと思います。

## ソフトトークン
利用時に別途何かをしなければいけないわけではなく、1デバイスのみ管理すればいいので、利便性を求めた場合は、ソフトトークンを使うといいかと思います。ただし、デバイスの盗難にあった場合に乗っ取られるという危険性はハードトークンよりは上がると思います。
api blueprintでData Structuresを利用する際の注意点

## 概要

restfulなapiを設計すっぞ。となっても、「けど同じ戻り値を何回も書きたくない！めんどくさい！」ってなりますよね。

そんなときに、Data Structuresというデータ型定義の方法が使えると知ったのですが、一部ハマったので書き留めておきます。

Data Structuresについては下記を参考にさせてもらいました。感謝！

api blueprint でData Structuresを用いてIFを定義する
https://qiita.com/haseshin/items/1394b0c70e25c9f51762


## Data Structuresを利用してみる

Data Structuresを利用しない場合、```/hoges``` のGETはリストで、```hoges/{id}``` のGETはオブジェクトで返すわけですが、オブジェクトの内容は同じになります。
今回はサンプルなので、```id``` と```name``` しかないですが、実際はもっと項目は多いわけで。。。
あとは分かりますよね。。。

```md
# hogeリソース

## hoge情報 [/hoges]

### hoge情報を取得する [GET /hoges]

+ Response 200 (application/json)

    + Attributes
        + items (array, fixed-type)
            + (object)
                + id : 1 (number) - ID
                + name : hoge (string) - 名前

## hoge情報 [/hoges/{id}]

+ Parameters

    + id : 1 (number) - ID


### hoge情報を取得する [GET]

+ Response 200 (application/json)

    + Attributes
        + id : 1 (number) - ID
        + name : hoge (string) - 名前
```

で、Data Structuresを利用して戻り値をデータ型定義するとスッキリする！
というわけで、先の記事が参考になります。

api blueprint でData Structuresを用いてIFを定義する
https://qiita.com/haseshin/items/1394b0c70e25c9f51762


記事に習って、まずはData Structuresを定義します。

```md
# Data Structures

## Hoge (object)
+ id : 1 (number) - ID
+ age : hoge  (string) - 名前
```

```hoges/{id}``` の戻り値に指定してみます。

```md
## hoge情報 [/hoges/{id}]

+ Parameters

    + id : 1 (number) - ID


### hoge情報を取得する [GET]

+ Response 200 (application/json)

    + Attributes
        + hoge (Hoge)
```

これで、戻り値はData Structuresを参照することになるので、楽で良いね！

それでは、良きapi blueprintを利用した設計ライフを^^

・
・
・

となれば良かったのですが、実際にjsonの戻り値を見てみます。

```json
{
  "hoge": {
    "id": 1,
    "age": "hoge"
  }
}
```

はい。
おわかりいただけるでしょうか。。。

```"hoge": { ... }```　はいらないんやー。となります。

どうすればよいのか小一時間悩んだ挙げ句、下記のようにすれば良いことがわかりました。

```md
## hoge情報 [/hoges/{id}]

+ Parameters

    + id : 1 (number) - ID


### hoge情報を取得する [GET]

+ Response 200 (application/json)

    + Attributes (Hoge)
```

結果を見てみます。

```json
{
  "id": 1,
  "age": "hoge"
}
```

はい。
期待していた戻り値となりました。

以下がData Structuresを適用したバージョンとなります。

```md
# Data Structures

## Hoge (object)
+ id : 1 (number) - ID
+ age : hoge  (string) - 名前


# hogeリソース

## hoge情報 [/hoges]

### hoge情報を取得する [GET /hoges]

+ Response 200 (application/json)

    + Attributes
        + items (array[Hoge], fixed-type)


## hoge情報 [/hoges/{id}]

+ Parameters

    + id : 1 (number) - ID

### hoge情報を取得する [GET]

+ Response 200 (application/json)

    + Attributes (Hoge)
```

それでは、良きapi blueprintを利用した設計ライフを^^

PS) hogeに複数形はあるのでしょうか・・・知りたい

## 参考

api blueprint でData Structuresを用いてIFを定義する
https://qiita.com/haseshin/items/1394b0c70e25c9f51762
WSLで.bashrcをいじって起動できなくなった話

WSLにGUI入れようとしたらuim-fep is already runningって出て起動できなくなった。.bashrcを編集しようにもubuntuが起動できない!ってときのコマンド
コマンドプロンプトを開いて

```
ubuntu run vim ~/.bashrc
```

備忘録です
【Railsエラー】SQLite3::CorruptException: database disk image is malformed: ...etc

[Railstu Torial](https://railstutorial.jp/)で、間違ってデータベースを削除してしまい以下のエラーで怒られて調べた結果、解決できたので備忘録として残します。

```irb
SQLite3::CorruptException: database disk image is malformed: SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence' AND name = 'schema_migrations' AND type IN ('table')
```

<img width="1399" alt="Action_Controller__Exception_caught.png" src="https://qiita-image-store.s3.amazonaws.com/0/97880/6f35dad3-1159-7aaa-8655-480d074e4f63.png">

###原因
調べたところ、データベースが破損しているとのことで色んな記事で以下のコマンドを試すとOKとあり、<font color="OrangeRed">試してみるも解決できず</font>。


```irb
$ bundle exec rails db:drop
$ bundle exec rails db:create
$ bundle exec rails db:migrate
```

###解決方法
①**「development.sqlite」**と**「test.sqlite」**のファイルを削除する。

②その後、ターミナルで以下を順にうってみる。

```irb
$ bundle exec rails db:create
$ bundle exec rails db:migrate
```

これで復旧できました。
<img width="920" alt="DB_Browser_for_SQLite_-__Users_ysato_enviroment_sample_app_db_development_sqlite3.png" src="https://qiita-image-store.s3.amazonaws.com/0/97880/46dd2cea-d4e3-ced3-ffbd-c1a33a76b7cc.png">


###参考記事
[Railsのデータベースのエラー](https://teratail.com/questions/127887)
AndroidデバイスからSSHでRaspberryPiを操作する方法

# 概要

Android端末があれば、Raspberry piをモニターに繋げることなくRaspbianのターミナルを使用することができます。
手軽にプログラムを動かせますのでオススメです。

# 用意するもの

 - Androidスマートフォン or タブレット(Android5.0以上)
 - Raspberry pi 3 Model B or B+
 - USBケーブル（Aオス-microBオス）

# 手順

1. Raspberry piにRaspbianをインストール&sshを有効化([参考](https://qiita.com/Halhira/items/1da2ae543217be26988a))
2. Android端末に以下の2つのアプリをインストール
 - **Termux** (Playストア: https://play.google.com/store/apps/details?id=com.termux&hl=ja)
 - **ConnectBot** (Playストア : https://play.google.com/store/apps/details?id=org.connectbot&hl=ja)
3. Android端末をRaspberry piのUSB端子に接続する。
4. Android端末の**USBテザリング機能**を有効にする。
<img width="400" alt="Screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/189802/efa35f61-a64f-2f3d-1dfa-386cb58372c0.png">

5. **Termux**を開いて次のコマンドを実行 `arp -a`
6. **rndis**に表示されるIPアドレスをメモる。
<img width="400" alt="Screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/189802/197448b7-cd7e-3306-9b78-91b6af8e223f.png">

7. ConnectBotを起動して、右下の＋マークをタップして出てくる画面で、一番上の欄に `pi@(IPアドレス)` を入力する。入力後右上の+マークをタップ
<img width="400" alt="Screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/189802/2ae773c5-0ada-881a-d5e5-e0401953f885.png">

8. 追加したコネクトから起動し、メッセージに対しYesをタップ
9. パスワードを求められるので、ssh用パスワードを入力(デフォルトは**raspberry**)。
10. これでAndroid端末からRaspbianのターミナルを操作できる。

# 参考

https://qiita.com/MarieKawasuji/items/b088ffb252a92eee8f5d
adbコマンドに＆が入っていたら\(バックスラッシュ)を付けろ

adbには`&`から後ろが切り捨てられるバグがあるらしい

`\`を`&`の前につけてあげよう

## NG
```
adb shell am start -a android.intent.action.VIEW -d "https://example.com/?a=1&b=2"
```

## OK
```
adb shell am start -a android.intent.action.VIEW -d "https://example.com/?a=1\&b=2"
```
無事に`&`を認識してくれた

![2018-09-14-12-12-02.png](https://qiita-image-store.s3.amazonaws.com/0/52227/7c5d6995-60f9-6f50-3f46-73b38fd8311c.png)
Nuxt.js でスクロールでふわっと要素が出現するやつを「カスタムディレクティブ」で実装する

Nuxt.js でWEBサイト作っていると、スクロールで何か処理をしたいことがある。
そんなときはカスタムディレクティブが便利。特にスクロールでふわっと要素が出てくる系は、様々な箇所で同じアニメーションロジックを再利用する為、カスタムディレクティブは相性が良いです。

## Nuxt.jsでの実装上でのポイント

ポイントはドキュメントにも書いてある通り、「カスタムディレクティブは Vue インスタンス作成前に登録されなければならない」という点。Nuxt.js では Vue インスタンス作成前に実行したい処理は plugins ディレクトリがその責務を担います。```plugins/README.md``` に書いてある通りです。

> This directory contains your Javascript plugins that you want to run before instantiating the root vue.js application.

なので、まずは```plugins```ディレクトリの中で```scroll.js```を作成し、カスタムディレクティブを作りましょう。

```js:plugins/scroll.js
import Vue from 'vue'

Vue.directive('scroll', {
    inserted: function (el, binding) {
        let f = function (evt) {
            if (binding.value(evt, el)) {
                window.removeEventListener('scroll', f)
            }
        }
        window.addEventListener('scroll', f)
    }
})
```

コードはVueの公式ドキュメントから拝借しました。
[カスタムスクロールディレクティブの作成](https://jp.vuejs.org/v2/cookbook/creating-custom-scroll-directives.html)

```inserted``` はひも付いている要素が親 Node に挿入された時に呼ばれるもの。
他のカスタムディレクティブのフック関数は下記ドキュメント参照。
[カスタムディレクティブ](https://jp.vuejs.org/v2/guide/custom-directive.html)

そして、```nuxt.config.js```内の plugins に作成した ファイルへのパスを追加します。

```js:nuxt.config.js
module.exports = {
  // ~
  plugins: [
    '~plugins/scroll.js'
  ]
}
```

これで```v-scroll```というカスタムディレクティブがtemplate内で使えるようになります。

## 作ったカスタムディレクティブを使ってみる

もしあなたが　Nuxt.js　のプロジェクトを作りたてなら```pages/index.vue```で試して見ましょう。

```vue:pages/index.vue
<template>
  <section class="container">
    <div>
      <div class="box" v-scroll="handleScroll">scroll hock</div>
    </div>
  </section>
</template>

<script>
export default {
  methods: {
    handleScroll: function(evt, el) {
      console.log(window.scrollY);
      if (window.scrollY > 50) {
        el.setAttribute(
          "style",
          "opacity: 1; transform: translate3d(0, -10px, 0)"
        );
      }
      return window.scrollY > 100;
    }
  }
};
</script>

<style>
.container {
  min-height: 150vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

.box {
  opacity: 0;
  transition: 1.5s all cubic-bezier(0.39, 0.575, 0.565, 1);
}
</style>
```

v-scrollで発火するメソッドを指定しています。
これでスクロールイベントを```v-scroll```と宣言するだけで行えるようになりました。
【PHPStorm】超簡単２ステップ Windows IntelliJ の日本語化【RubyMine】

### 2019.09.06 現在、この方法では日本語化できない場合があります

私の環境では Rubymine 2019.1 より この内容を適用するとRubymineが起動しませんでした。
pleiades公式インストーラで日本語化できるようなので、そちらをお試しください。

pleiades http://mergedoc.osdn.jp/
参考記事 https://qiita.com/daigoro7/items/00819e5686f6c4d682f8

----

IntelliJ IDEA の日本語化手順を自分なりに最適化してみた。
たぶんこれが一番早いと思います。

### 1. pleiades日本語化プラグインをDL、解凍する

powershellを **管理者実行** し、以下のコマンドを実行する。
※ [プラグイン](http://mergedoc.osdn.jp)のダウンロードとCドライブへの解凍が行われます。

```powershell
Invoke-WebRequest "http://ftp.jaist.ac.jp/pub/mergedoc/pleiades/build/stable/pleiades-win.zip" -OutFile "${Env:TEMP}\\pleiades-win.zip"; Expand-Archive -Path "${Env:TEMP}\\pleiades-win.zip" -DestinationPath "C://pleiades-win" -Force
```

### 2. IDEAの カスタム VM オプションファイルに書き込む

1. メニューの Help > Edit Custom VM Options... をクリック
2. 表示されるテキストファイルに、以下の設定を追記し保存する。

```
-Xverify:none
-javaagent:C:\\pleiades-win\\plugins\\jp.sourceforge.mergedoc.pleiades\\pleiades.jar
```

以上です。IDEAを再起動すると日本語化されます。
うまくいったら いいね👍 おねがいします。

----

参考にしました

- [JetBrains 公式マニュアル日本語版 JetBrains 製品の日本語化マニュアル](https://pleiades.io/pages/pleiades_jetbrains_manual.html)
- [PhpStormの日本語化(Windows環境・Pleiades利用）](https://qiita.com/tmak_tsukamoto/items/95a32a1d36094cb44f1b) (以前書いた記事です)
gitのbranchを新しい順に並べる方法(git v2.19以降)

gitのversion 2.19でbranchのsortオプションに新しく`authordate`が追加された
これを使えばgit branchコマンドの結果がauthordate順に並ぶようになる。

いろんなbranchを行き来していてどのbranchを作業していたか忘れがちなので
これを使えば前に作業していたbranchが見つけやすくなる

```
git branch --sort=authordate #古い順
git branch --sort=-authordate #新しい順
```

defaultでsort順を変えたい時はgit configで設定しておくと便利

```shell
git config --global branch.sort -authordate
```

# 参考
https://blog.github.com/2018-09-10-highlights-from-git-2-19/
ask-sdk で非同期処理してからレスポンス

## About
知ってる人には当たり前なんでしょうが、 
[Alexa Skills Kit (ASK) SDK for Node.js バージョン2](https://developer.amazon.com/ja/blogs/alexa/post/51f6f6eb-a6cb-4d2e-82ca-166bdfee61be/ask-sdk-v2-release-japanese) で非同期処理をしてから、
 Alexa にレスポンスを返す方法。

## 問題点
v1 は、 `this.emit` のタイミングでレスポンスを返すので、非同期の最後で emit して動作していたのだが、
v2では handler で同期的に `Response` を return する必要がある。
・・・と勝手に思っていたんだけど、 interface の定義を見ると `Promise<Response> | Response` となっていました。

```
export interface RequestHandler {
    canHandle(handlerInput: HandlerInput): Promise<boolean> | boolean;
    handle(handlerInput: HandlerInput): Promise<Response> | Response;
}
```

なので、これみたら、 async して await しちゃおう、って気付けるんですがはじめ気づけませんでした。

## 実装
```
function execute(msg) {
  return new Promise(resolve => {
    setTimeout(() => {
        resolve();
    }, 1000);
  });
}

const MyIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'MyIntent';
  },
  async handle(handlerInput) {
    await execute('なんか非同期処理');
    return handlerInput.responseBuilder
      .speak('Hello My Intent')
      .reprompt('Hello')
      .getResponse();
  }
};
```

こうすると非同期処理を実施して `resolve or reject` すると、
await のブロッキングから抜けるので、なんか後続処理するなり return すると OK です。

サンプルスキルとかで、わりと当たり前に実装されているので今更なんですが。

## Reference
[[日本語Alexa] Alexa-SDK Ver2(その4) スキル属性 ｜ Developers.IO](https://dev.classmethod.jp/cloud/alexa-sdk-v2-fourth/)
[ask-sdkでdynamodb - Qiita](https://qiita.com/imajoriri/items/7a30d68daf603357883c)

おわり。
slack slash custom command + google calendar api + aws lambda/apigateway + golang(2)

続き

## シークレットキーセットアップ
前回記事の `googleCalendarAPIの有効化` で落としたjsonファイルの内容をコピって適当なパッケージ変数に詰めます。

```go
package sample

var secretJsonBytes = []byte(`
{
json maji json
}`)

```
別に実行時にこの内容を読めれば良いので、このやり方にこだわる必要はありませんが多分1番楽。多分ね。
ただこれシークレッツな情報なので、gitとかにあげるときはgit-cryptなりopensslなりで暗号化しときましょう。

## てきとうなサンプル
動いてるものから色々省いて転載したので動かなかったらゴメンな

```go
package sample

import (
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/calendar/v3"
	"fmt"
)

const CALENDARID string = "yourcalendarID@group.calendar.google.com"

func sample() error {
	config, err := google.JWTConfigFromJSON(secretJsonBytes, calendar.CalendarScope)
	if err != nil {
		// error handle
	}

	client := config.Client(oauth2.NoContext)
	srv, err := calendar.New(client)
	if err != nil {
		// error handle
	}

	task := "add" // 実際にはこんなことしてないよ！
	switch task {
	case `add`:
		_, err = srv.Events.Insert(CALENDARID, sampleEvent()).Do()
		if err != nil {
			// error handle
		}
	case `see`:
		// Do以外はoptionalやで
		// mix/maxのフォーマットはRFC3339っぽい JSTじゃない場合は適宜変えてやってくれよな
		list, err := srv.Events.List(CALENDARID).
			Q("フリーワード的な").
			TimeMin("2018-09-15T00:00:00+09:00").
			TimeMax("2018-09-16T00:00:00+09:00").
			Do()
		if err != nil {
			// error handle
		}
		fmt.Println(list)
	}

	return nil
}

func sampleEvent() *calendar.Event {
	return &calendar.Event{
		Summary:     "予定タイトル部分",
		ColorId:     "5", //予定の帯の色 docによると1-11の間で指定
		Description: "予定内容部分 ぶっちゃけSumarryが本体でここが補足だと思う",
		Start: &calendar.EventDateTime{
			Date:     "2018-09-15",
			TimeZone: "Asia/Tokyo",
		},
		End: &calendar.EventDateTime{
			Date:     "2018-09-15",
			TimeZone: "Asia/Tokyo",
		},
	}
}

```

あとは前回記事と適当に辻褄合わせればいけます。
SAMも全部組み合わせてみた人はそっと動いたかどうか教えてください。
Git 管理下のファイルを一括置換する git-sed コマンドを作った

> `.find_by_admin` よりも `.find_by(type: :admin)` の方が自然な書き方だった

開発中にこんな風に気づいてコードを直したくなった、
しかし `.find_by_admin` とすでに色々なファイルに書いてしまっている、という時は `sed` で一括置換するのが簡単です[^1]。

```shell
$ git ls-files | xargs -n 1 sed -i 's|find_by_admin|find_by(type: :admin)|g'
```

これは大変よく行う作業なので[^2]、専用のコマンドにしてみました。

[^1]: IDEやフォーマッタが使える場合は、それらを使いましょう。

[^2]: 私の場合。不惑に達していないので。

# 使い方

```shell
$ git sed 's|find_by_admin|find_by(type: :admin)|g'
```

また、特定のディレクトリのファイルのみを置換したいことがあります（例えば、テストコードのみを変更したい場合）。ファイルを検索するディレクトリ名を後ろに指定できます。

```shell
$ git sed 's|find_by_admin|find_by(type: :admin)|g' spec/ test/
```

# ソースコード

以下のファイルを `~/bin/git-sed` などに保存してください。

```bash
#!/bin/bash
set -euC
if [ "$#" -eq 0 ]; then
  echo 'git sed COMMAND [PATH [PATH[...]]]' >&2
  exit 1
fi

if which gsed > /dev/null; then
  SED=gsed # for macOS
else
  SED=sed
fi

CMD=(-e "$1")
shift

apply_sed() {
  f="$1"
}

while read -r f; do
  [ -f "$f" ] && [ ! -L "$f" ] && "$SED" -i "${CMD[@]}" "$f"
done < <(git ls-files -- "$@")
```
スマホアプリ学習のために用意した環境と言語選択(+初心者の意気込み)

$\color{green}{\rm 最初の投稿！}$
$\color{green}{\rm モチベーションも大事だと思うので覚書として使用します。}$
#1.開発環境
VisualStudio、Android実機(DignoG)、接続端子TypeC、iPhone7Plus(元から)
PC(自作)、キーボードK360(US)、マウスその他周辺機器、本(猫でもわかるC#)
画像はワークロードなる画面(XamarinやUnityも含めた)![VisualStudioワークロード.png](https://qiita-image-store.s3.amazonaws.com/0/252588/4fc08e41-e5ac-dee7-cb02-e5ac7c9f5122.png)

#2.言語選択

<b>`C#`を選択しました。</b>
スマホ～サーバシステム等汎用性と将来性あり
`Xamarin`の追い風もありそれが今だったから。
(結局他言語特に`JAVA`と`Swift`の仕様も理解必要な時もあるけど幅広く身につくからよし！)
$\color{green}{\rm 参考：}$[redmonk最新言語ランキング](https://redmonk.com/sogrady/2018/08/10/language-rankings-6-18/)

#2.自己紹介

<b>正直、ニートで起床後寝るまでPC張り付き生活でした…。</b>
職歴は営業(倒産その後ニート)や以前は塾講師(明光)家庭教師(WILL)
バイトや派遣で旅館・ホテル・パチンコ屋・自分を試すためブラック太陽光営業。
色々したけど基本全て接客。

以上から周りからPCの先生なればとリアルに言われたりしています。
でも、やりたい事がありプログラミングの世界に踏み入れる事にしました。
これまで趣味で絵や暗号通信、`Muse`でHP制作奥が深そうなものしたけど、
プログラミングも同じく深い印象です。一番深いかもしれない…
けど挫折はしないでやり遂げたいと思います。
ここまで読んでるもの好きな方はフォローして頂き生暖かく見守ってください！

#3.やりたいこと

<b>やりたい事はモバイルアプリ制作です。</b>
特に通訳や翻訳関係で、あるモデルでスキーム組んで通訳をマッチングするアプリにしたいです。
在学時英会話同好会副部長だったのもあり、元々好きだったので思いたちました。
追い打ちできっかけを与えてくれたのはキリスト教の勧誘…。よく無料英会話教室開いてますよね。
素直に素晴らしい活動だと思い、真面目に考える事にしました。
詳しく想像しているので、興味ある方は連絡ください！

#4.意気込み
もちろんアプリは作って満足ではなくリリースするしビジネスとしても軌道にのせたいと思ってます。
学習しある程度したら制作、企画、営業、VCや持込でのせる。
全てのセクターが簡単には行かないと思うしニートがこれやろうとしたら
多少端折っても決心して最後までやり遂げる気持ちじゃないと無理でしょうな…
実際今の状態で県のベンチャー支援通って知的好奇心満たして張り切ったりしたけど、
東京から民間のベンチャー支援きた時、ニートが持ち込む妄想なんて誰も聞かない事を痛感したし、
マネーの虎世代？の方々に圧迫面接くらって、そんなの知らない僕は結構ズタボロになった。

けど情熱は全く冷めないしむしろクリアが難しそうでのめり込む事になった。
これまで難しかった経験は、何度かあったが…そういうものこそのめり込むし自信がある(好きという前提)。
サッカーは中1まで補欠で逆にのめり込み、地区選県選とあがりU-18日本代表予備選抜になれた。
小中高大サッカーしたが大学にサッカー部はなく、その部活を作成し運営したこともある。
ニート時代でも学ぶ事はあった、FPSゲームでクラン所属して遊んでいたので、
影響するのは仲間との連携、対象の仕様やフレーム、プログラムされたアルゴリズム…etc
サッカーも人脈、コミュニケーション、選手以外も色々な人と連携することが大事だと分かった。
以上から結局自分の力は微々たるもので人との協力が大事ということ。
今回学習することでモックは作成可能と思うけど、軌道にのせる所まで考えるとそれが効いてくると思う。

そう考えてみれば、圧迫面接の人も好きで圧迫するわけじゃないし逆に考えればどうでもよくないからこそ、
ガンガン言うのであって全体で見れば軌道にのるための協力者、先生と言える！

てことでとにかく挫折はしないと決めたけど精神は脆いので、基礎やりつつ多少端折りながらやります。
その度にこちらでコメントくださる方やteratailの回答者様に助けられつつ臨みたいです！
(と言いつつ見た感じブログ的使用でコメントもらってる方を発見できないしC#記事少な…)
<b>個人的には最低でも挫折をしない事を念頭に頑張ります。</b>

#5.具体的な目標

<b>`C#`1日1項目</b>
その他の時間`Xamarin`、`JAVA`/`Kotlin`、`Swift`最終的に通訳モバイルアプリ制作。
学習方法はQiitaと、本1冊(猫でもわかるC#)とteratailで質問中心。あとは気合でググりまくる。
(ワード選定、MSDNや大手サイト、Google多く見て共通点や裏付け探して信憑性あげ)

現状サーバ周り調べながらXAMPP弄ったり学習アプリ遊んだり徐々にプログラミングに触れていきました。
`C#`はVSをDLしぼちぼち始めているので、今後初心を忘れず頑張ってこう！と思います。
React

+ Reactとは
+ Visual DOM
+ まとめ


# Reactとは
ReactはFacebookが開発しているJavaScriptライブラリ
Virtual DOMいうレンダリング機能がついている
コンポーネント指向

# Visual DOM
Jqueryは読み込み時のDOMに対応するもの

Visual DOMはDOMのレンダリングに紐づいて反応する感じ

phpはリクエスト送ったタイミング


# まとめ

ページ内で再読み込みせずにDOMを変化させるようなものに適していそう
Facebookはポップアップとか多いから使えるのかも
ページ内でリクエストしてリアクションが返ってくるような感じかな(だからReactっていうのかなぁ)


#参考
http://creator.dwango.co.jp/3413.html
VS Code 1.27 の新機能 - 階層リンク機能の改善

https://code.visualstudio.com/updates/v1_27#_breadcrumbs-improvements

１つ前のリリースで実装された階層リンク機能に対しいくつかの改善があった。

# シンボル該当箇所のハイライト
階層リンクで選択シンボルを移動させると、それに対応するエディタ箇所がハイライト表示されるようになった。

![bread_indicate.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/1ae3085a-5205-eecd-5a02-ab8433cd33d1.gif)

# 機能の自動有効化
前バージョンでは、階層リンクの機能をあらかじめオンにしておかないと階層リンクへのフォーカス移動ができなかったが、階層リンクの機能がオフの状態であっても階層リンクへフォーカス移動するショートカットキー(`Ctrl`+`Shift`+`.`や`Ctrl`+`Shift`+`:`)を押すと、設定が自動的にオンになり、同時にフォーカス移動するようになった。

![bread_auto_on.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/0392178e-33eb-a0bf-889c-accad9239359.gif)

あと、メニューの項目名も`breadcrumbs`から`階層リンクの切り替え`に変わった。
ios11でハイフンがうまく入力できない時にした事

iOS11にしてから連続したハイフンがうまく入力できなくて不便に感じてましたが、解決方法が見つかり快適になりました。(ただ普通に戻っただけ)

# Before
`---`と入力したくても、`—`に変換されてしまい、[-]を何度タップしても変わりません。
`'`や`"`も`‘’`や`“”`に変換されてしまいます。

# After
[-]をタップした分だけ入力されます。  
`----------------`  
`'`や`"`も自由自在に入力できます。  
`''""`

# した事
ソフトキーボードの[地球儀マーク]を **長押し**  
または、[設定アプリ] > [一般] > [キーボード] を開きます。
[スマート句読点]を **オフ** にします。

たったこれだけで快適にコードが書けるようになりました。
Python仮想環境構築

# venvによる仮想環境構築
* 管理者権限でコマンドプロンプトを起動
* 仮想環境を作成するフォルダに移動
* 以下のコマンドで仮想環境フォルダを作成

```
workspace > python -m venv notebook
```

* 仮想環境を有効にする

```
workspace > cd notebook
workspace\notebook > Scripts\activate.bat
```

* 仮想環境毎に必要なパッケージをインストールする 

```
(notebook) workspace\notebook > pip install jupyter
```
RMarkdownでLeafletを使った地図描画と配布

R言語のR MarkdownでLeafletを使った地図描画をして、出力されたHtmlファイルを人に配布したい時、というとんでもなくニッチな時に役立つTipsです。

# 地図の描画ができない時の対処法
サクッと行きましょう。
Leafletは地図の描画が簡単にできるライブラリです。詳しい使い方は下部の参考リンクの解説がとてもわかりやすいです。

以下のようにシンプルに書くと、R Studio上で実行した場合は地図が描画されますが、出力されたhtmlファイルをブラウザで開くと地図が描画されないという現象がおきます。

```r:シンプルな実装
library(magrittr)
library(leaflet)

# data.leaflet がデータの入ったデータフレームとします
# 列としてlongitude, latitude, name, radius があるというようなイメージでご覧ください

# width, heightで出力される地図部分の大きさを調整できます
m <- leaflet(data.leaflet, width = 900, height = 700)

m %>% 
  addTiles() %>%
  addMarkers(lng=~longitude, lat=~latitude, popup=~name, group = "マーカー") %>%
  addCircleMarkers(lng=~longitude,lat=~latitude,radius=~radius, color = "#0f3") %>% 
  addPolylines(lng=~longitude,lat=~latitude,color="#03f",weight="5") %>%
  addLayersControl(overlayGroups=c("マーカー")) %>%
  setView(lng=139.7,lat=35.7,zoom=11)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/ed66086a-e3cc-1d54-f6ac-effb4d5db589.png)

こんな感じに地図のみ表示されない。

ちなみに、addMarkersがマーカーの描画、addCircleMarkersが円の描画、addPolylinesが点を結ぶ線の描画、addLayersControlがレイヤの設定です。上のようにかくとマーカーの表示非表示が切り替えられる状態になります。
とりあえずこれだけあればそれっぽい地図描画ができて素晴らしいです。

## 回避方法

本題です。
結論としてaddTitles()の引数に以下を設定します。

```r:url設定
m %>% 
  addTiles(urlTemplate = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png") %>%
  （略）
```

## 原因

もともとLeafletではOpenStreetMapを利用しており、そこにアクセスしているわけですが、ライブラリ内でアクセス先として`//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png`という指定がなされています。
httpの部分を省略しているのですが、これはhttp/https両方に対応できるためであり、ミスではないです。（最近ではGoogleでは非推奨ということになっているようではある。）

このため、htmlをローカルで開いた場合は、file://{s}.tile.openstreetmap.ort/... にアクセスしに行こうとし、表示されないのが原因です。

# おまけTips

R Markdownを実行するときにパラメータを渡して実行することができます。
R Markdownの設定に以下のようにパラメータを定義することができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/b9c996c8-0e10-e1d0-b8e1-9756f0cc08a7.png)

Knit実行する際に、Knit with Parametersを指定すると、入力フォームが現れ、設定することができます。
レポート作りの際にとても便利ですね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/1d93c883-1561-507c-59c3-019b95538c91.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/adbd7f17-8188-ff55-47ca-b95498fc8c4b.png)


# 参考リンク

[Leaflet for R](https://rstudio.github.io/leaflet/)
[leafletではじめるRによる地図プロット](https://kazutan.github.io/JapanR2015/leaflet_d.html)
[参考issues](https://github.com/rstudio/leaflet/issues/192)
Keyboard shortcuts for the main calibre program for Mac

Keyboard shortcuts for the main calibre program for Mac
========================================================

```
Keyboard    | 
shortcut    | Action
------------+-----------------------------------------
Alt+Shift+D | Toggle Book details panel
Alt+Shift+T | Toggle Tag browser
 E          | Edit metadata of selected books
 O          | Open containing folder
 S          | Save to disk
Alt+V       | View specific format
Alt+A       | Show books by the same author as the current book
Alt+T       | Show books with the same tags as current book
Alt+Shift+F | Toggle Search Bar
Esc         | Clear the current search
Shift+Esc   | Focus the book list
 N          | Find the next book that matches the current search
            | (only works if search highlighting is turned on in search preferences)
Shift+N     | Find the previous book that matches the current search
            | (only works if search highlighting is turned on in search preferences)
Cmd+M       | Toggle mark/unmarked status on selected books

__AND_SO_ON__
```
Filebeatで、「Shift_JIS(CR)」をElasticStackに取り込む

# 概要
Windowsサーバを利用しているJavaっぽいプロジェクトに関わると、文字コードがWindowsっぽくないログファイルに会うことが、多々有ります。
Filebeatを利用している場合、Filebeat側で対応できるので、その記録を残しております。

# 想定状況
構成

- ファイル送信元
    - Windowsサーバ
    - Filebeatを利用している
    - Shift_JISでLF改行の ログファイルを転送する
        - メモ帳等で開くと、改行がないように見える(Winodws的にはCRLFで改行なので、CRが足りない)
- ファイル受信
    - Linuxサーバ
    - logstash
    - 受け側はあまり関係がない

# 状況
そのままファイルを転送すると、文字化けする。

- 改行記号は認識してるらしく、レコードは正しく分割される
- 日本語文字が、化ける（ひし形？の黒四角とか。環境による)

受け側のlogstashで処理しようとしたが、うまく行かず。

```
filebeat.inputs:
- type: log
  enabled: true
  paths
  - C:/tmp/Shift_JIS_with_LF.log
  fields:
    logtype: javaApplicationLog
```

# 対応策

Filebeatで、input毎に endocing が指定できるので、そこで指定する。
送信元で正しくencoding認識しておくべき、は当たり前でしたね。(が、どのオプション記載をすればいいのか分からなかった)

```
filebeat.inputs:
- type: log
  enabled: true
  encoding: Shift_JIS    # <----ここを追加
  paths
  - C:/tmp/Shift_JIS_with_LF.log
  fields:
    logtype: javaApplicationLog
```

; ログで日本語使うなよ…、せめて文字コードや改行記号は揃えてログを出そうよ…

以上。
githubで初回push時にパスワード間違えて詰んだ話

#はじめまして。
タイトル通りです。

当方お恥ずかしながら、かなりの高確率でIDとPasswordを紛失するのですが
今回はそれでかなり痛い目を見たので自戒を兼ねた投稿です。



#なにがおこったか
GitHubに、CUIで初回push時、出てきたポップアップに間違えたパスワードを入力しました。

同じ動作をしたらまたポップアップ出てくるやろｗｗｗと高をくくっていたのですが、
それきり何をしてもポップアップが出ず、正しくログインができなくなってしまいました。

焦りすぎてスクショも撮っていませんでした。反省。





#原因と解決
Gitの認証情報を誤ってPCに登録したことでエラーになっていたため、そこを変更します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/272658/d84e0cbd-2972-8bcd-3151-5503030a4495.png)
ユーザアカウントから資格情報マネージャに飛び、
windows資格情報の欄にあるGitHubの情報を削除。
（編集でもいけたのかもしれません　が、ひとまず私は削除しました）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/272658/f7c1dc5c-cfea-35c1-3512-bb8f1d574736.png)



これで、再度push作業をしたところポップアップが出てきました。めでたしめでたし。





##参考
https://cpoint-lab.co.jp/article/201804/windows%E7%89%88git%E3%81%A7%E8%AA%8D%E8%A8%BC%E6%83%85%E5%A0%B1%E3%82%92%E6%B6%88%E3%81%99%E6%96%B9%E6%B3%95/


その後ここじゃないmerge関係で詰みまくったので、
その際に参考にしたサイトも併せて以下に置いておきます。よろしければ…
https://qiita.com/hijion/items/ae2cccebf5d28ff733f3
https://qiita.com/takanatsu/items/fc89de9bd11148da1438
Laravelのenv関数で値が取得できない原因と対策

# 前置き

なんか実行環境が変わったらenv関数で値が取得できてないっぽいんだけど？みたいな経験ありませんか？この問題の原因と解決方法をまとめて見たいと思いますです。

# まずはenv関数の紹介

Laravel5では環境依存するような値は環境変数として.envファイルに記述しますが、コード上からそれらの変数を参照する場合はenv関数を使います。実際にこのenv関数を使っている箇所として、config/app.phpがありますので、見てみましょう。

``` config/app.php

return [
    'name' => env('APP_NAME', 'Laravel'),
    'env' => env('APP_ENV', 'production'),
];
```

env関数の第２引数はデフォルト値です。上記の例ですと、APP_NAMEという環境変数が.envに設定されていない場合、env関数は'Laravel'という値を返します。

# 本題「env関数で値が取得できない」理由

.envファイルに環境変数が設定されているにも関わらず、env関数がnullを返す場合があります。それは、**設定ファイルがキャッシュされている**場合です。「設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しは全てnullを返す」仕様らしいです。[参考](https://readouble.com/laravel/5.7/ja/helpers.html#method-env)はこちら。

``` php

/// 前提：.envにAPP_NAME=laravelを設定している

/// 設定ファイルがキャッシュされていない場合
echo env('APP_NAME');            /// laravelと出力
echo env('APP_NAME', 'ほげほげ');  /// laravelと出力

/// 設定ファイルがキャッシュされている場合
echo env('APP_NAME');            /// nullなので何も出力されない
echo env('APP_NAME', 'ほげほげ');  /// 第2引数のほげほげが出力される

```

# 対策など

手っ取り早い解決としては設定ファイルのキャッシュを消せば直ります。消すのは以下のコマンドです。

```
php artisan config:clear
```

ちなみに設定ファイルをキャッシュするのは以下のコマンドです。

```
php artisan config:cache
```

一般的に設定ファイルはキャッシュしておいた方が無難なはずです。本番環境などでは当然のようにキャッシュしておくかと思います。ただし、コード上でenv関数を使っていたりすると、設定ファイルをキャッシュした途端に動かなくなるといった現象が起ります。こうした事態を避けるため、上記の例としてあがっているconfig/app.phpでやっているように、config/*.phpに環境変数の値を入れて、コード上ではenv関数ではなくconfig関数を使うようにしたほうが良いようです。
【PostgreSQL】実行中のプロセスを停止する方法

何らかの理由で実行中のプロセスが溜まり、動作が遅くなる症状が発生した時の対応手順です。

##実行中のプロセスを確認
下記のSQLで実行中のプロセスを経過時間順に取得します。

```sql:実行中のプロセスIDを取得
SELECT
    procpid,
    start,
    now() - start AS lap,
    current_query
FROM
    (SELECT
        backendid,
        pg_stat_get_backend_pid(TMP1.backendid) AS procpid,
        pg_stat_get_backend_activity_start(TMP1.backendid) AS start,
        pg_stat_get_backend_activity(TMP1.backendid) AS current_query
    FROM
        (SELECT pg_stat_get_backend_idset() AS backendid) AS TMP1
    ) AS TMP2
WHERE
    current_query <> ''
ORDER BY
    lap DESC;
```

##プロセスを停止する
下記のSQLを実行し、プロセスを停止します。
[procpid]は上記のSQLで得られたprocpidを入れます。
lap（経過時間）とクエリの内容（current_query）を見て、停止しても問題ないプロセスを選びました。


```sql:プロセスを停止
SELECT pg_cancel_backend([procpid]);
```

または、

```sql:プロセスを強制的に停止
SELECT pg_terminate_backend([procpid]);
```

*処理の成否がbool値で返ってきます。
[ エラー ]jekyll インストールできない

#jekyllをインストール

先日案件でjekyllを使うことがあってのですが、
エラーでインストール出来なかったので、解決法をメモ

- まずRubyを使用しているので、Rubyをインストールしているか確認
- jekyllをコマンドでインストール

```
$ gem install jekyll
```

上記のコマンドだとなぜかエラーが発生しました。

```
$ sudo gem install jekyll
```

sudoを前に付けると、インストールできました。
（プラグインのインストール時も同じやり方）
5分でvueのアプリを作りfirebaseにhostingする

## はじめに
[こちらの記事](https://qiita.com/Satachito/items/4a00b402970d657a88f3)を参考にvueアプリをfirebaseにhostingできたのでメモ


## 準備

グローバル環境にvue-cliを導入

```
$ npm i vue-cli -g
```
firebase CLIをグローバル環境に導入

```
$ npm install -g firebase-tools
```

firebaseにログイン

```
$ firebase login
```
firebaseのプロジェクトを作成する
https://firebase.google.com/

## Vueアプリの作成

テンプレは色々あるが、今回は`webpack`を使用

```
vue init webpack ＜アプリ名＞
```
その後色々聞かれるが、手っ取り早くhostinbgしたい方は全てenterで大丈夫です。


## ローカルサーバーでホストできるか確認

`<アプリ名>`のディレクトリに移動後、プロジェクトが作成されていることを確認。
下記のコマンドを実行し、ローカルサーバーを立ち上げる。

```
$ npm install  # 少し時間かかる
$ npm run dev
```

サーバーが立ち上がっているか`localhost:8080`から確認。


## firebaseにホストする
vueアプリをデプロイができる形に変えるためビルドする。

```
$ npm run build
```

`dist`フォルダが生成される。

## firebaseの初期化＆デプロイ
firebaseにホストできるように初期化

```
$ firebase init
```
下記の質問では`dist`を指定する。

```
? What do you want to use as your public directory? dist
```

なお、間違ってしまっても下記ファイルから編集できる。

```firebase.json
{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

```

デプロイは下記コマンドで一発

```
$ firebase deploy
```

## 出来上がったもの

工事中ですが、一応完成したアプリ
https://aboutme-dc98f.firebaseapp.com/
https://toruokada.tokyo/


firebaseだと簡単にドメインの設定もできる。
あと、vue-routerに`mode: 'history'`を追記するとURL末尾の#を取り除くことができる。
[HTML5 History モード
](https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B)

```js

export default new Router({
  mode: 'history',
  routes: [
    //省略
  ]
})
```
processmakerのＡＰＩをＣＬＡＳＰとＣＬＯＵＤ９で作成

#ＢＰＭから呼び出すＧＡＳのＡＰＩをCLOUD9で作成するときのtypescript設定

#プロセス（業務フロー）のタスク（業務）分岐の際の際にＧＡＳを呼び出し
ＣＬＡＳＰでＧＡＳをローカルで作成できる様にしてtypescriptで作成
![googlelogger.JPG](https://qiita-image-store.s3.amazonaws.com/0/37985/fd3e22e1-98da-2ef0-20ed-b4e694f7dd22.jpeg)

#cloud9 ⇒ user setting で tsを追加
```acrsetting
 "custom-types": {
            "json()": {
                "^searchresults": "c9search",
                "settings": "javascript",
                "gs": "javascript",
                "ts": "javascript"
            }
        },

```
#コード整形などできるようになるので便利
![cloud9.JPG](https://qiita-image-store.s3.amazonaws.com/0/37985/7c13f5fa-48a9-47a0-2961-ee2eb192db65.jpeg)