Qiita-vim復活させた話 [完成！！！]

# PR通ってます！！！（跳ねるほど嬉しい）

随分と前のことになりますが、
PR対応をしていただいたため、Qiitaにvimから投稿できるようになりました！！！
やったね！！


[new] Todo list公開しときました、issueでできればいいのだがどうやらforkにはissueかけないようなので...
https://qiita.com/Cj-bc/items/c0bcb8e3e7de86c821b9

# 進捗報告(最新版)

なんか割と需要ありそうなので書いておきます。
現状下に貼っているgithubから入手できますが、細かい部分をケアしていないため不具合多数出る可能性もあります...

| コマンド| 状態 | 備考 |
|:-:|:-:|:-:|
| `:Qiita -l`  | O  |   |
| `:Qiita -l`のリストから項目選択 | O | |
| `:Qiita -l <user>` | O |  |
|  `:Qiita`(投稿) | O  |   |
|  `:Qiita -e`(編集) | O  |   |
| `:Qiita -d`  |  O | エラー時のメッセージがおかしいのでちょっと直す必要があります。  |
| `:Qiita XXXXXXXX`  | O  |  指定されたitem返すやつ |
| `:Unite qiita` | O | |
| `:CtrlPQiita` | O | |
| API libraryとして | O | 詳しくは下記 |

# API libraryとして

| method | 状態 | docs | 備考 |
|:-:|:-:|:-:|:-:|
| qiita#createApi | O | O | |
| qiita#createApiWithAuth | - | - |  そもそもパスワード認証用のAPIがなくなっているようなので消滅 |
| api.rate_limit | O | O | APIエンドポイントは消えているので、headerから取得する |
| api.user | O | O | |
| api.tag | O | O | 新たなエンドポイントが増えているが、描き直すべきか否か |
| api.tags | O | O | |
| api.post_item | O | O | |
| user.items | O | O | |
| user.item | O | O | |
| user.stocks | O | O | |
| tag.item | O | O | |
| item.delete | O | O | |

---


# Qiita-vimとは

@mattn 氏作の、`vim`から`Qiita`への投稿、閲覧、更新など色々できるプラグインです。
しかし最終更新日時が6年前、`Qiita API v2`に対応していないため現在使うことができません。
しかしどうしてもvimからQiitaを使いたい(Qiita書くためだけにGUI環境に出てきたくない)ので、自分でなんとか対応させてみることにしました。

Qiita: [mattn/Qiita.vim 作りました!](https://qiita.com/mattn/items/4b31a7ecd0a1fd761fe1)
Github: [mattn/qiita-vim](https://github.com/mattn/qiita-vim)
作業中のfork: [Cj-bc/qiita-vim](https://github.com/Cj-bc/qiita-vim), `feature/v2` branch

# デバッグ方法

主には、`:debug`と変数の定数置き換えによってデバッグしました。
`:debug`についてはちょっと書いたのでこちらを: [Cj-bc/vim scriptデバッグ方法](https://qiita.com/Cj-bc/items/4a2b62212cd753ff7ec8)

## 定数書き換えとは

勝手に呼んでいるだけです()
挙動が怪しいなと思ったところを定数に書き換え、同時に複数の不具合が起こらないようにしました。
今回は、固定できるところ、つまり`self.url_name`(QiitaのURLにある名前。`@`以下のやつ。)を自分の名前(`Cj-bc`)に固定したり、
今回のケースでは省いてもそこまで問題がなさそうな処理を省いたりしました。

<details> <summary> 具体例ですがほんのちょっとだけ長くなるのでしまっておきます </summary><div>

例を置いておきます、コメントアウトされているのがテストのためにいじったコードです。
実際のデバッグ時にはそれらのコメントアウトを外し、既存の該当する部分と置き換えて走らせました。


```vim:list_user_items()
    ...
  try
    let old_undolevels = &undolevels
    silent %d _
    redraw | echon 'Listing items... '
    let items = a:api.user(a:user).items()
    "call setline(1, split(join(["this is test", "second line"], "\n"))) " for debug
    "call setline(1, split(join(map(items, 'v:val.uuid . ": " . v:val.title'), "\n"), "\n")) " for debug 2
    call setline(1, split(join(map(items, 'v:val.uuid . ": " . webapi#html#decodeEntityReference(v:val.title)'), "\n"), "\n"))
  catch
    bw!
    ...
```

```vim:user.items()
function! s:user.items()
  "let res = webapi#json#decode(webapi#http#get(printf('https://qiita.com/api/v2/users/%s/items', 'Cj-bc'), {'token': self.token}).content)
  let res = webapi#json#decode(webapi#http#get(printf('https://qiita.com/api/v2/users/%s/items', self.url_name), {'token': self.token}).content)
  if type(res) == 4 && has_key(res, 'error')
    throw res.error
  endif
  if type(res) != 3
    throw 'invalid response'
  endif
  ...
```

</div></details>



# APIをv2に書き換える

これは至極単純で

```vim
:%s/v1/v2/g
```

で行いました。
一応、間違って置換されてないか確かめるために`/v2`で確認もしました


# 2. うまく走らないのをなんとかする

大雑把ですがめっちゃ時間かかりました...
ちなみに、大掛かりにデバッグとかしてますが遠回りしただけだったりします(単純に仕様変更のせいだったりした)


## 2.1 `Vim(call):E716: Key not present in Dictionary: uuid . ": " . v:val.title`

これです

![qiita-vim-err-uuid.gif](https://qiita-image-store.s3.amazonaws.com/0/222594/00c76003-b34a-17c9-bea1-8f4f1bcbf0f8.gif)
)


これは結局、APIの仕様変更に伴い削除された値を読みに行っていたのが問題でした。
具体的にはここ

```vim:list_user_items()
call setline(1, split(join(map(items, 'v:val.uuid . ": " . webapi#html#decodeEntityReference(v:val.title)'), "\n"), "\n"))
```

[github](https://github.com/mattn/qiita-vim/blob/73235dc95a7b12b862112eddd059efe3b25380d3/autoload/qiita.vim#L325)
使用されているAPI: `/api/v2/users/:user_id/items`

前後のコード読まないとなんともわからないとは思いますが、`v:val.uuid`の部分が違っていました。
これ、`uuid`は削除されてるんですね...`v2`だと...
代わりに`id`なるものがありましたので、置き換えたら動きました。やったね。

### 解決までの道のり

```vim
call setline(1, split(join(["this is test", "second line"], "\n")))
```
まずこれで置き換えてエラーが出ないことを確認。置き換える前の部分に問題があるなと推定(ちょっと雑すぎるかも?)

```vim
call setline(1, split(join(map(items, 'v:val.uuid . ": " . v:val.title)'), "\n"), "\n"))
```

`webapi#html#decodeEntityReference`の部分は、URLエンコードを外すためのものらしく、今回の件とは関係なさそうなのでとりあえず外す。
この時点で文字列は表示されてなかったため、URLエンコードされたままでもまぁ問題ないと判断。
これでもエラーが出る& エラーが`.uuid`で始まることから、`uuid`を疑う。
ここでリファレンス見たら`uuid`なるものが存在せず、代わりに`id`なるものがあるので使って見た。
そしたら動いたので置換しておいた。
ここまで約1日かかった...エラーからすぐに見破れなかったのはちょっと悲しい

この後`webapi#html#decodeEntityReference`ももとに戻してエラーが出ないことを確認、この部分についてはおそらくこれで完了

### 現状

`:Qiita -l`コマンドを実行すると

<img width="1440" alt="Qiita -lコマンド実行結果1" src="https://qiita-image-store.s3.amazonaws.com/0/222594/09686ad7-7a15-35c8-8302-26bd23424955.png">
こうなる。

ここで項目を選択すると
<img width="1440" alt="Qiita -lコマンド実行結果2" src="https://qiita-image-store.s3.amazonaws.com/0/222594/28ae0c58-e248-1ea9-dd6e-5271b5900d16.png">
開ける!!



## 2.2 `E716: Key not present in Dictionary: url`

<img width="1440" alt="Qiita-vim 2.2実行結果1" src="https://qiita-image-store.s3.amazonaws.com/0/222594/4d8ef216-6ec2-2f8c-4b8b-44f041145103.png">


こいつはなかなかトリッキーでした
トリッキーというか、`:debug`をみるまではわかりづらかった...

これは`write_item()`を実行している間に出たものなのですが、ここで使用されているAPIを調べると、引数に`url`パラメータは存在している。おかしい。
結局をいうと、実は*認証がうまく行っていなかったのだ*ということがわかった


<img width="1440" alt="Qiita-vim 2.2実行結果2" src="https://qiita-image-store.s3.amazonaws.com/0/222594/e7b68f42-368c-1af6-ff85-4e4c8dc4595c.png">

とりあえずtokenを変えてみたりはしたがうまくいかない。この解決策に関しては後述する(未作成なので作成次第リンク貼ります)として、何よりこのエラーを消そうと思う（認証できなかった場合ははっきりそう明記させたい）。
つまり、**エラーハンドリングをする。**

### エラー判別を直す

APIの仕様変更により、API側からのエラーの返り方に変更があったようです。
そのため、きちんとエラーが捕捉されずに放置されてしまったわけです...
なので、[リファレンス](https://qiita.com/api/v2/docs#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9)をみながら該当箇所を直します
具体的には、エラーのレスポンスが以下のように変更されています:

```json
{
  "message": "Not found",
  "type": "not_found"
}
```

元のコードでは`error`が含まれる場合をエラーとみなしていたので、すり抜けていたわけですね。
直します

```diff
- if has_key(res, 'error')
+ if has_key(res, 'type')
-  throw res.error
+  throw res.type
  endif
```

捕捉するのは`type`でいいのか悩んだのですが、他に`type`が返ってくることはなさそうだったのでこれにしました。
問題ないといいな...?

### 脇道に逸れて例外捕捉

本題とは逸れますがこれも改善の一歩ということで...(というか、きちんとハンドリングしてくれた方がデバッグも楽)

さて、一箇所だけtry-catch使っている部分がありますので

```vim:list_user_items()
try
  ...
catch
  bw!
  redraw
  echohl ErrorMsg | echomsg v:exception | echohl None
  return
finally
  ...
endtry

```

ここを参考にして、例外捕捉を行いました
具体的な設置箇所:

|箇所|いつ|
|:-:|:-:|
| qiita#login() |` qiita#createApiWithAuth`実行時 |
| write_item() | `api.post_item`実行時 |
| list_user_items() | `a:api.user(a:user).items()`周り実行時 |
| qiita#Qiita() 　| `qiita#login`実行時 |

この結果、きちんとエラーを表示できるようになりました。

`~/.qiita-vim`(設定ファイル)が存在するけどtokenが違う/ない
などで認証できない場合:
![qiita-vim-err-add-trycatch1.gif](https://qiita-image-store.s3.amazonaws.com/0/222594/2af5a2b2-3ab9-7eb9-537d-94886188a7b4.gif)

`~/.qiita-vim`がなくて、プロンプトから入力してるけど認証できない場合:
![qiita-vim-err-add-trycatch2.gif](https://qiita-image-store.s3.amazonaws.com/0/222594/33d2cba7-db1d-2a3f-4289-a176eaa8ad68.gif)


もうちょっとわかりやすくできそうだけど...今はとりあえずこんなもんでいいかなと(エラー情報どのくらい表示するかは悩む)
一つ目の方のエラーメッセージは、「tokenが違います」的なのを出せたら良いかもしれない。


### 認証できない問題

やっと解消できました...
これもまた、APIの仕様変更によるものでした。

| APIバージョン | token送信方法 |
| :-: | :-: |
| v1 | Jsonで`body`の中身として送信 |
| v2 | Headerに`Authorization: Bearer <token>`として埋め込み |

これを直して一件落着...かと思いきやまだダメだった！
とりあえず認証は通るようになり、代わりに[2.3](https://qiita.com/Cj-bc/items/74c1f80745a7e2a5bd69#23-bad_requestinvalid_json)のエラーが出るようになりました

### 現状

| コマンド| 状態 | 備考 |
|:-:|:-:|:-:|
| `:Qiita -l`  | O  |   |
| `:Qiita -l`のリストから項目選択 | O | |
| `:Qiita -l <user>` | X | 何故か自分のものが表示されてしまう |
|  `:Qiita`(投稿) | △  |  作業中 |
|  `:Qiita -e`(編集) | X  |   |
| `:Qiita -d`  |  X |   |
| `:Qiita XXXXXXXX`  | O  |  指定されたitem返すやつ |
| `:Unite qiita` | X | |
| `:CtrlPQiita` | X | |
| qiita-interfaceとして | X | まだきちんと調べてない、コマンド系終わったら対応 |



## 2.3 `bad_request`/`invalid_json`

ま〜、ヒントの少ない問題だこと...
APIの認証は無事に通るようになりましたが、今度はJSON書式がなっていないのだそうです。
与えられた情報はこれだけ

```json
{
  "message": "invalid_json",
  "type": "invalid_json"
}
```
```json
{
  "message": "bad_request",
  "type": "bad_request"
}
```

まー情報の少ないこと...でも逆に楽しくなってきてガシガシやってました。

### 先に結論

`body`の`private`キーに与える値がbool値でなかったことが問題だったようです。
これは、vimの仕様変更に伴うものなのか、それともQiita側の仕様変更に伴うものなのか...わかりませんがとりあえず直しました。

```diff
-   \ "private": 0,
+   \ "private": v:false,
```

そして、vim8から搭載された、`json_encode`と`json_decode`を`webapi#json#encode`/`webapi#json#decode`の代わりに採用しました。
（そうでないと`webapi#json#encode`/`webapi#json#decode`のアップデートに時間がかかってしまうため。）

### 解決までの道のり

まず、怪しいのは`body`部分ぽかったので、何か必要な値が足りなかったり、不要なものが入ってたりしないか？とリファレンス見ながら探してました。
が、特になし。(`tweet`や`gist`を追加してみたりしたが変化なかった)

上記作業中に、`private`の値について疑問を持ちました。
リファレンスによればbool値なのに何故`0`で指定されていたからです。
まぁおそらく、`0`と`1`（もしくは`0`とそれ以外)などで真偽を書いているのだろうと推測したものの気になって調べました。
すると、vim8になってから真偽値が追加されたとの情報が！！

引用:
>Vim script には、true/false などの bool 値や、null などの値は存在しませんでした。
>このままだと JSON と相互に変換するのに支障が出るため、新しくこれらを表す値が追加されました。
>
>v:false
>v:true
>v:null
>v:none
>これらによって、bool 値や null を含む JSON も正しく相互変換されます。
>
>[Vim 8.0 Advent Calendar 4 日目 JSON サポート](https://qiita.com/thinca/items/07499aa07dddb584e6c2)

これにならい、`v:false`/`v:true`に書き換えて動かすと、
うご...きそうなんだけど動かない...
今度は`invalid_json`って言われる。
どうやらJSONの書式か何かがおかしいようです。

...お？そういえばさっき何か見たな？？

>これだ
>>引用:
>>Vim script には、true/false などの bool 値や、null などの値は存在しませんでした。
>>このままだと JSON と相互に変換するのに支障が出るため、新しくこれらを表す値が追加されました。
>>

`Qiita-vim`では、JSONのエンコード・デコードに`webapi-vim`の関数が使われていました。
しかしそれらはvim8以前の更新が最後となっているため、vim8で追加された`v:false`/`v:true`などに対応していませんでした。そのためうまくエンコードしてくれなかったわけです。
`webapi`に手直しをするか...?本来はそれもしたいけど、あまり割いている時間はなかったので、先ほどのページで見かけた`json_encode`/`json_decode`を使用することにしました。
すると...

<blockquote class="twitter-tweet" data-theme="light"><p lang="ja" dir="ltr">Qiita-vim v2対応進捗です<br>現状できることは<br>:Qiita で投稿<br>:Qiita -l で自分の投稿の閲覧<br><br>何気に更新している、これに関するQiita記事<a href="https://t.co/KzleqQywIq">https://t.co/KzleqQywIq</a> <a href="https://t.co/yzEs4D0rsT">pic.twitter.com/yzEs4D0rsT</a></p>&mdash; Cj-bc_sd.sh (@Cj_bc_sd) <a href="https://twitter.com/Cj_bc_sd/status/1051397753417256961?ref_src=twsrc%5Etfw">October 14, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

綺麗にできた！！！


### 現状

| コマンド| 状態 | 備考 |
|:-:|:-:|:-:|
| `:Qiita -l`  | O  |   |
| `:Qiita -l`のリストから項目選択 | O | |
| `:Qiita -l <user>` | X | 何故か自分のものが表示されてしまう |
|  `:Qiita`(投稿) | O  |   |
|  `:Qiita -e`(編集) | X  |   |
| `:Qiita -d`  |  X |   |
| `:Qiita XXXXXXXX`  | O  |  指定されたitem返すやつ |
| `:Unite qiita` | X | |
| `:CtrlPQiita` | X | |
| qiita-interfaceとして | X | まだきちんと調べてない、コマンド系終わったら対応 |


## 2.4 `:Qiita -l <username>`で自分の投稿一覧が表示されてしまう

謎だったものの一つ...
何故か、`:Qiita -l <username>`としても`:Qiita -l`と同じ動作になってしまっていました。
わかってしまったら簡単だったんですがね...

### 解決までの道のり

とりあえず、`qiita#Qiita`からコードを辿り、その後`:debug Qiita -l <username>`でステップ実行しながら確認しました。
初めは、`qiita#Qiita`から`<username>`がうまく伝えられてないのかな？と思ったのですが問題ありませんでした。
その後も`list_user_items`内でも問題はなく...
若干書くのがめんどくなってきた（単純作業でしかなかったので）ので結論を書きます。
....まさかの自分のミス....
前、問題解決する為に付け足したコードが悪さをしたようです...
具体的には、これまでは`url_name`というパラメータが存在していたのに`v2`にてなくなっていたことが原因でした。
`url_name`はつまり、`@cj-bc`などの名前に当たるわけで、それを*tokenの持ち主のものに設定する*ように書いてしまっていた...（元はそもそも存在していなかった)
なので、これをきちんと正しいユーザーの情報になるように変更を入れました。

そしたら...きちんと動くようになった！！！
<img width="1440" alt="スクリーンショット 2018-10-14 22.46.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/222594/d4c3b916-9f52-1529-c241-c81baafabd0d.png">

(テスト用にmattnさんの名前で調べてみました。)

## 2.5 `:Qiita -e`が動かない

`:Qiita -e`を実行すると

```vim
write_item: updating item: Vim(let):E474: Invalid argument
```
こんな感じのこと言われます。（ログのプレフィックスは適当）

### 先に結論

[編集するためのAPI](https://qiita.com/api/v2/docs#patch-apiv2itemsitem_id)に渡すパラメータが不要に多かったのと、HTTP methodが違っていたのが問題でした。
そのため、リファレンスに合わせてパラメータを減らし、HTTP methodの修正をしました。

```diff
+ let content = {'body': self['body'],
+              \ 'id': self['id'],
+              \ 'title': self['title'],
+              \ 'tags': self['tags'],
+              \ 'private': v:false,
- let res = json_decode(webapi#http#post(printf('https://qiita.com/api/v2/items/%s', self['id']), json_encode(self), {'Content-Type': 'application/json', 'X-HTTP-Method-Override': 'PUT', 'Authorization': 'Bearer ' . self.token}).content)
+ let res = json_decode(webapi#http#post(printf('https://qiita.com/api/v2/items/%s', self['id']), json_encode(content), {'Content-Type': 'application/json', 'X-HTTP-Method-Override': 'PATCH', 'Authorization': 'Bearer ' . self.token}).content)
```

### 解決までの道のり

`invalid argument`と言われているのでとりあえずリファレンスを参照します。
するとHTTP methodが`PATCH`である事がわかったので変更。
HTTP methodが規定されているのはここ

```vim:item.update()
  let res = json_decode(webapi#http#post(printf('https://qiita.com/api/v2/items/%s', self['id']), json_encode(self), {'Content-Type': 'application/json', 'X-HTTP-Method-Override': 'PUT', 'Authorization': 'Bearer ' . self.token}).content)
```
`'X-HTTP-Method-Override': 'PUT'`として指定されているので、これを`PATCH`に変更します。
`webapi#http#post`の仕様上、第四引数にHTTP methodを指定することもできますが、元のスタイルに合わせておきました。
しかしこれでも動かない...
`invalid argument`なので`:debug Qiita -e`でトレースして見ると、どうやら`json_encode`でエラーを吐かれているらしい。
`json_encode(self)`となっているが、`self`を覗いてみると、リファレンスをみる限り不要な情報も同時に投げているようでした。
そこに意図があったのか、（それともただ単に綺麗なコードだからか）わかりませんが、渡す内容を削ってみることにしました。

```vim
  let content = {'body': self['body'],
               \ 'id': self['id'],
               \ 'title': self['title'],
               \ 'tags': self['tags'],
               \ 'private': v:false,
               \}
```
このように定義し、`json_encode(self)`の代わりに`json_encode(content)`として動かすと...

  [後でここに画像が多分きます。wifiないのでおうち帰ってから。]

うまく動いた!!
元々は、APIに渡す情報が過多だったのかなと思い、必要最低限と思われるところまで削ったわけですが、
おそらく情報過多なわけではなかったと思います(そもそもAPIを叩きに行っていなかったため)
結果オーライなのですが、きちんと検証した方が良いかも...?
ということで...

### 現状

| コマンド| 状態 | 備考 |
|:-:|:-:|:-:|
| `:Qiita -l`  | O  |   |
| `:Qiita -l`のリストから項目選択 | O | |
| `:Qiita -l <user>` | O |  |
|  `:Qiita`(投稿) | O  |   |
|  `:Qiita -e`(編集) | O  |   |
| `:Qiita -d`  |  X |   |
| `:Qiita XXXXXXXX`  | O  |  指定されたitem返すやつ |
| `:Unite qiita` | X | |
| `:CtrlPQiita` | X | |
| qiita-interfaceとして | X | まだきちんと調べてない、コマンド系終わったら対応 |


## 2.6 `:Qiita -d`の修正

これは割と簡単だった。ってかほんと単純に直ったのであまり書くことありません。
徐々に記事更新がだるくなってきており(主にはリアルタイムで書いていないのとSS撮り忘れていて資料がなかったりするため)、
若干雑になってきてるけどゴメンなさい(雑でも最後まで書きあげる方を優先したい)

まず、HTTP methodの指定方法がよくなかったので直します。

`webapi#http#post`への引数内で、method指定する引数が`{X-HTTP-Method-Override: 'DELETE}`となっていた部分を修正しました。
二通り方法がある(methodへの引数として`DELETE`のみを指定するor先ほどの辞書をheaderのリストに追加する)のですが、
他の箇所との一貫性を考え後者にしました。

エラー捕捉の修正

前は、リクエストの戻り値の`header`にHTTP status codeがあったようですが、現状だと`status`として分離されていたので、それに合わせて書き直しました。
とりあえずそんなところです。

### 現状

| コマンド| 状態 | 備考 |
|:-:|:-:|:-:|
| `:Qiita -l`  | O  |   |
| `:Qiita -l`のリストから項目選択 | O | |
| `:Qiita -l <user>` | O |  |
|  `:Qiita`(投稿) | O  |   |
|  `:Qiita -e`(編集) | O  |   |
| `:Qiita -d`  |  O | エラー時のメッセージがおかしいのでちょっと直す必要があります。  |
| `:Qiita XXXXXXXX`  | O  |  指定されたitem返すやつ |
| `:Unite qiita` | X | |
| `:CtrlPQiita` | X | |
| qiita-interfaceとして | X | まだきちんと調べてない、コマンド系終わったら対応 |


## 2.7 `Unite`/`CtrlP`対応

これは単純に`uuid`を`id`に変更しただけで動きました。
ただ、自分は普段どちらも使っていないため、見つかってない不具合がまだある可能性があります...
PRのコードレビューの時に見つかってほしい...(投げやりorz)

### 現状

| コマンド| 状態 | 備考 |
|:-:|:-:|:-:|
| `:Qiita -l`  | O  |   |
| `:Qiita -l`のリストから項目選択 | O | |
| `:Qiita -l <user>` | O |  |
|  `:Qiita`(投稿) | O  |   |
|  `:Qiita -e`(編集) | O  |   |
| `:Qiita -d`  |  O | エラー時のメッセージがおかしいのでちょっと直す必要があります。  |
| `:Qiita XXXXXXXX`  | O  |  指定されたitem返すやつ |
| `:Unite qiita` | O | |
| `:CtrlPQiita` | O | |
| qiita-interfaceとして | X | まだきちんと調べてない、コマンド系終わったら対応 |

---
この先も随時更新しまふ