OmniAICreator/Qiita-1.07M huggingface dataset:
input type="file"の「ファイル名」を表示させたくない時はbutton要素で装飾しよう！

# はじめに
HTMLでファイルアップロードを行う際に使用する`input type="file"`の話です。
通常だとボタンの右側に「ファイル名」もしくは「選択されていません」のメッセージが表示されますよね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434874/40ba56d1-1faf-dbc6-a6f6-e494dc744f9b.png" width="300">
「**オレは選択したファイルのプレビューを表示させるからファイル名の表示はいらねェ！（ドン）**」

そんな時ありますよね。
そういった時にこのファイル名を消し去るTipsの紹介です。

# 方法
`input要素`のファイル名のみを表示する方法は、公式では用意されていないようです（多分）。

そこで「**`input要素`を`label要素`もしくは`button要素`でラップする方法**」で対応します。

[MDNのドキュメント](
https://developer.mozilla.org/en-US/docs/Web/API/File_API/Using_files_from_web_applications#using_hidden_file_input_elements_using_the_click_method)では、`button要素`でラップする方法を推奨しています。
そのため今回はこちらの方法をそのまま流用します。

- HTML
```HTML
<input
  type="file"
  id="fileElem"
  multiple
  accept="image/*"
  style="display:none" />
<button id="fileSelect" type="button">画像を選択</button>
```

`style="display:none"`でinput要素を（**見た目上**）消し去っています。
そして最後にユーザーに見せるbutton要素を追加しています。


- JavaScript

```javascript
const fileSelect = document.getElementById("fileSelect");
const fileElem = document.getElementById("fileElem");

fileSelect.addEventListener("click", (e) => {
  if (fileElem) {
    fileElem.click();
  }
}, false);
```

button要素をクリックした時に、Input要素のclickイベントを発火させる関数になります。

## こんな感じ
見事にファイル名が消えていますね。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOKGzLz" data-user="umezakidaisuke" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/umezakidaisuke/pen/gOKGzLz">
  Untitled</a> by UmezakiDaisuke (<a href="https://codepen.io/umezakidaisuke">@umezakidaisuke</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

後はプレビュー機能を実装するなり、イケてないボタンの装飾なりをすればよいかと思います。

# 参考記事
- MDN（今回のメイン）

https://developer.mozilla.org/en-US/docs/Web/API/File_API/Using_files_from_web_applications#using_hidden_file_input_elements_using_the_click_method

- 偉大なる公式ドキュメント

https://html.spec.whatwg.org/multipage/input.html#file-upload-state-(type=file)

- label要素ではなくbutton要素でのラップを推奨する理由

https://zenn.dev/dqn/articles/7505cfa1bed278


## 【おまけ】 input type="file"をDisるMDN
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434874/483ad038-b8e8-836a-1aff-cac9314d5034.png" width="500">

そこまで言わんでも……笑
Google UXデザイン：ペーパー・プロトタイプ

# はじめに

わたしが[Google UX Design Crtificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1ed400d1-bbdf-302d-70be-3175620c3912.png" width="800">

<details><summary>これまでの振り返り</summary>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f5283f3c-b018-d798-9d01-df3b7904e6a0.jpeg" width="500">

</details>

#  ワイヤーフレームからプロトタイプへの移行

プロトタイプとは、実際に製品全体を構築することなく、その機能を実証する製品の初期モデルのことです。プロトタイプは、ステークホルダーや潜在的なユーザーに、あなたのアイデアの可能性を示すものです。あなたのチームが多大な時間とお金を投資する前に、ユーザーはプロトタイプと対話し、フィードバックを提供することができます。

ワイヤーフレームからプロトタイプに移行する際、最も大きな違いは

***<font color="MediumVioletRed">『インタラクティブ性、つまりある画面から別の画面へクリックする機能』</font>***

です。

ローファイ（低抽象度）・プロトタイプには、紙のものとデジタルのものがあります。

- 紙の場合、インタラクティブ性は、人間がコンピュータとして動作し、リアルタイムでデザインを手動で変更することができます。
- デジタルの場合、インタラクティブ性は、ワイヤーフレームがつながっていて、送信ボタンなどのワイヤーフレームの特定の部分をクリックすると、次のワイヤーフレームに移動することができます。

#  ペーパー・プロトタイプ

### メリット

- ペンと紙さえあれば、安価に作ることができます。
- 迅速なイテレーションを可能にします。紙とペンを使うだけなので、さまざまなアイデアのペーパープロトタイプを素早く作ることができます。
- 作成が低負担であることです。デジタルプロトタイプは作るのに時間がかかるので、それを完全に破棄する必要がある場合、苦痛になります。
- 正直なフィードバックを促します。ペーパープロトタイプはあまり洗練されていないので、チームメイトやユーザーがより快適に批判できるようになります。
- 共同作業で作成します。台所に料理人が多すぎるということはありえません。

### デメリット

- 紙のプロトタイプを解釈するのは難しいかもしれません。ペーパープロトタイプを試したユーザーが、実際の製品がどのようなものかを想像するのは、かなりの想像力が必要です。
- ペーパープロトタイプは、実際に会ってテストすることしかできません。ペーパープロトタイプをテスト場所に持っていき、人がコンピュータの代わりとなって、リアルタイムに手動でデザインを変更しなければならないのです。
- ペーパープロトタイプは、遠隔地にいるチームと一緒に作るのが難しいということです。

### どんなとき役立つ？

- ペーパープロトタイプは、ブレインストーミングの際に作成するのに適しています。複数のアイデアを素早く描き、それらのアイデアを比較することができます。
- 初期の製品アイデアをユーザーとテストするために、ペーパープロトタイプを作るのもよいでしょう。
- デザイナーがワイヤーフレームやプロトタイプを作るとき、さまざまな道を歩むことができることを指摘しておきます。例えば、紙のワイヤーフレームを完成させたら、そのままローファイなデジタルプロトタイプに移行するのが最適だと分かるかもしれませんし、アプリやウェブサイトがすでに確立されている場合など、紙をまったく使わず、すべてをデジタルで構築する場合もあります。すべては、あなたが取り組んでいるプロジェクトの種類と、あなたとあなたのチームにとって何がベストなのかによります。

# ペーパー・プロトタイプの作成

この例では、犬の散歩アプリのペーパープロトタイプを作成します。

では、このワイヤーフレームをインタラクティブな低忠実度のプロトタイプにするにはどうすればいいのでしょうか？それは、手際よくやるしかありません。プロトタイプをインタラクティブにするために、私はハサミを手に取り、すべての画面をこのように切り取ります。切り絵の出来上がりです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7389da9e-2e0e-eaf7-1cb8-38b3a2db512a.png" width="７00">

さて、スクリーンと携帯電話のアウトラインができたところで、それらをインタラクティブにするにはどうしたらよいでしょうか？

ここから紙芝居を行います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/6cbcf407-9c11-d681-6af2-bfa5bffd7417.png" width="７00">

これで完成です。
【Ruby on Rails】デプロイ手順




#### Gemを追加

```Ruby:Gemfile
group :production do
  gem 'pg'
end
```
```Terminal:ターミナル
bundle install
```

#### デプロイ用の設定ファイルを追加
① binフォルダに、render-build.shという名称でファイルを新規作成する。
② 作成したファイルに、以下の記述を追加する。
```Ruby:bin/render-build.sh
#!/usr/bin/env bash
# exit on error
set -o errexit

bundle install
bundle exec rake assets:precompile
bundle exec rake assets:clean
bundle exec rake db:migrate
```
#### database.ymlの設定を変更
このように変更することで、開発環境およびテスト環境ではMySQLが、本番環境ではPostgreSQLが使用されるようになる。
```Ruby:config/database.yml
default: &default
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  adapter: mysql2
  username: root
  password:
  host: localhost
  database: アプリケーション名_development

test:
  <<: *default
  adapter: mysql2
  username: root
  password:
  host: localhost
  database: アプリケーション名_test

production:
  <<: *default
  adapter: postgresql
  url: <%= ENV['DATABASE_URL'] %>
```

#### Gemfile.lockの設定を変更
```Terminal:ターミナル
bundle lock --add-platform x86_64-linux
```

#### 秘密情報管理用ファイルを作成
```Terminal:ターミナル
EDITOR="vi" bin/rails credentials:edit
```
「escキー」→「:」→「q」と入力し、「enterキー」を押下。


### Renderで「Web Service」作成時に入力する項目

| 入力欄       | 入力内容                           |
| ----------- | -------------------------------- |
|Build Command|./bin/render-build.sh             |
|Start Command|bundle exec puma -C config/puma.rb|

### Renderで「Add Environment Variable」に追記する項目

| 入力欄       　　　　　　| 入力内容                                      |
| -------------- | -------------------------------------------- |
|RAILS_MASTER_KEY|configフォルダにある「master.key」                  |
|DATABASE_URL　　　　　　　　|自身のRenderのDashboardの「Internal Database URL」|


#techcamp136期
larastan + gitlab Ci ではじめるCi入門

# 概要

Larabelで開発の際に静的解析をしたかったのでlarastanを導入することになりました。  
ただこの系統の資料がgitlabではあんまりなかったので調べながら進めた内容を少しでも対応する人の手助けになったらと思い今回の記事を書きました。

## larastan

### 導入

筆者の環境は以下のような感じ
```shell
Laravel Framework 8.83.19
PHP 8.0.23 (cli)
larastan 1.X
```

まずはlarastanの導入をします。
基本は、[公式](https://github.com/nunomaduro/larastan)を見てもらえば大丈夫なんですがざっくりと説明しておきます。

まずはLaravelとPHPのバージョンによって導入するlarastanのバージョンが違うので気をつけてください。
- PHP 8.0+
- Laravel 9.0+
ならばlarastanの2.X

ただし今回筆者はlaravelのバージョンが足りないためlarastanの1.Xをインストールします。
```shell
composer require nunomaduro/larastan:^1.0 --dev
```

インストール後は、アプリのルートディレクトリで`phpstan.neon`のファイルを作成します。
設定は、様々ありますがここでは最低限の内容のみ記載します。
```
includes:
    - ./vendor/nunomaduro/larastan/extension.neon

parameters:
    paths:
        - app

    level: 5
```
では各内容をします。
`includes`ではlarastanで使用する設定を他のファイルから取得できるようになっています。
今回記載しているのは、基本の設定っぽいので脳死で入れています。

`parameters`では各項目に対して設定します。
基本は、ここから下の内容をどんどん設定をいじる形ですね。

`paths`ではソースコードを解析する場所を指定します。
今回であればapp配下のソースコードを解析するように指示します。

`level`では解析するルールのレベルを変えることができます。
0~9まであるみたいですが9まで進めることは、筆者では難しかったです…。
また詳細は、長くなってしまうので割愛します。

その他の設定は、[こちら](https://phpstan.org/config-reference)からどうぞ

### 実行

ここまで設定ができればあとは、実行するだけです。
```shell
./vendor/bin/phpstan analyse -c phpstan.neon
```
これで解析OKですがよくここで起こるのは、メモリが足りないってエラーです。
なので筆者でも下記のようにオプションを追加して実行しています。
```shell
./vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=1G
```
これによりメモリが足りないエラーがなくなるのでつけることをおすすめします。

## gitlab

### 導入

CIの説明やgitlabでのCIのやり方は、ここでの説明ではないと思うので割愛します。
実際に記載したコードとしては以下の通りです。
```shell
test:
  stage: test
  script:
    - composer install
    - ./vendor/bin/phpstan analyse -c phpstan.neon --memory-limit 1G --error-format table
```
これで実際に実行されてテストの内容を把握することができます。

## まとめ
正直導入自体は、そこまで問題ないと思います。
ただし自分自身としては、reviewdogを導入してコメントできるまでは落とし込みたかったんですがよくわからなかったんですよね…。
実際gitlabでの導入が公式参考にしてましたが他の例が少なすぎて断念しました…。
ただし今度は、その参考例にもなりたいので再チャレンジします。
JSの書き方について

# Javascriptの書き方は人それぞれ
こんにちは！Zackeyです。
仕事をしているとよく人の書いたコードを読む機会があると思います。
JavaやC#などコンパイル型の言語は割としっかりと書いてありますよね。
誰のを読んでもそこまで困らない。

いつも思うのはJS（jQuery）なんです！
とにかく読みづらいものから、めちゃくちゃ読みやすい書き方まであるので、
ここでは私的読みやすいコーディングを書いていこうともいます。

## 関数型言語なんだよ・・・
JSは関数型の言語です！
つまり実行時には基本的に関数（function）が動作するということ。
それに基づいて書いていく！ってのが我流です。

## 悪い例
ここでは今まで見た中でもかなり悪い例を書いていきます。
```javascript
$(function () {
  $('.node').on('click', function () {
    console.log('click');
  });
});
$(function () {
  $('.node').on('change', function () {
    console.log('change');
  });
});
```
こんな感じ、、、
クッソきもいですね！
しかも発火タイミングが謎ですね！ぶっ〇しますよ！
これメンテしてって言われたら多分書き換えから視野に入ります。
実際に現場で結構目にする書き方なんで本当につらい。。。

## 私的な例
先ほどのコードをよりきれいにすっきり書いていきましょう。
まず`$(function () {})`ですがこれはdocument.onredyとほぼ同じなんで**複数書かないでください！**
```javascript
$(function () {
  $('.node').on('click', function () {
    console.log('click');
  });

  $('.node').on('change', function () {
    console.log('change');
  });
});
```
一つにまとめました。
次に関数型の言語なわけですから、引数に毎度毎度functionって書くんじゃあねえ！
thisの考え方もまばらになりがちなので、関数は事前に定義しときましょう！
```javascript
var action = function (event) {
    console.log(event.data.text);
}

$(function () {
  $('.node').on('click', { text: 'click' }, action);
  $('.node').on('change', { text: 'change' }, action);
});
```
だいぶましになってきました。
あとは渡すときにdataオブジェクトを前もって作っとくほうがきれいですね！
```javascript
var action = function (ev) {
    console.log(ev.data.text);
}

$(function () {
  var clickOptions = {};
  var changeOptions = {};

  click.text = 'click';
  change.text = 'change';

  $('.node').on('click', clickOptions, action);
  $('.node').on('change', changeOptions, action);
});
```
個人的にはこれですっきり

## フレームワークとTypescript
近年はWebAPPを作成する際はJSフレームワークとしてAngulerやVue、Reactなどを使ってコーディングするのが主流となっています。
どのFWもTypescriptを推奨しています。
厳格な型定義型であるTypescriptにさっと移行できるように、動けばいいJSを書くのは卒業しましょう！
paiza.ioでelixir その77

# 概要
paiza.ioでelixirやってみた。
e-statのsparqlを叩いてみた。

# サンプルコード

```
:inets.start
:ssl.start

query = URI.encode_query(%{query: """

SELECT ?subject ?predicate ?object
WHERE {
    ?subject ?predicate ?object
}
LIMIT 3

"""})
#|> IO.inspect
{:ok, {{_, _, _}, _, body}} = :httpc.request(:post, {
	'https://data.e-stat.go.jp/lod/sparql/alldata/query', 
	[{'Accept', 'application/sparql-results+json'}], 
	'application/x-www-form-urlencoded', 
	query
}, [], [])
#|> IO.inspect
body = IO.iodata_to_binary(body)
IO.puts(body)

```

# 実行結果

```
{
  "head": {
    "vars": [ "subject" , "predicate" , "object" ]
  } ,
  "results": {
    "bindings": [
      {
        "subject": { "type": "uri" , "value": "http://data.e-stat.go.jp/lod/dataset/gridCode/dm012015302/obsQ24DSKRZDMDOMMQ7TRTQI5FT4PMVNYLM" } ,
        "predicate": { "type": "uri" , "value": "http://purl.org/linked-data/cube#dataSet" } ,
        "object": { "type": "uri" , "value": "http://data.e-stat.go.jp/lod/dataset/g00200521/dm012015302" }
      } ,
      {
        "subject": { "type": "uri" , "value": "http://data.e-stat.go.jp/lod/dataset/gridCode/dm012015302/obsCEQ5NOWDXG5C747HEVQOVGER3CSFZ55J" } ,
        "predicate": { "type": "uri" , "value": "http://purl.org/linked-data/cube#dataSet" } ,
        "object": { "type": "uri" , "value": "http://data.e-stat.go.jp/lod/dataset/g00200521/dm012015302" }
      } ,
      {
        "subject": { "type": "uri" , "value": "http://data.e-stat.go.jp/lod/dataset/gridCode/dm012015302/obsSZGCBG3D4RSYDR5OQ22QZ7G62U2PJPXA" } ,
        "predicate": { "type": "uri" , "value": "http://purl.org/linked-data/cube#dataSet" } ,
        "object": { "type": "uri" , "value": "http://data.e-stat.go.jp/lod/dataset/g00200521/dm012015302" }
      }
    ]
  }
}

```

# 成果物

https://paiza.io/projects/CdFq4cAul-ocHHtaS9NNGw

以上。
Thunderbolt4 DockがSleep復帰時に認識されない

# はじめに
在宅ワークPC(Windos10)用にAnkerのThunderbot4 Dockを導入したが、Sleep復帰時にうまく再認識されない事象が発生し、一応の解決が見えたのそのメモ
利用したDock：Anker PowerExpand Elite 12-in-1 Thunderbolt 4 Dock (APEX)

## 結論 
急いでる人向けに結論
ノートPCの省電力設定が影響してました。
省電力設定をハイパフォーマンスなどのモードへ変更することで直ります。

### 補足
- OSおよびノートPCの省電力をHigh Perfomanceにする
	- とりあえずは通電時のみの設定でOK
	- それでもだめならバッテリ駆動時も
- Sleep復帰前にDock側のスイッチは必ずONにしてから起動
	- 上記の通電時のパフォーマンス設定で起動させるため

ここから下は細かい話です。


# おきたこと
起きたことと調べていった内容をメモします。
## 構成
構成していた環境の情報です。
### PC (Windows)
- Lenovo T14s メモリ32GBモデル
### Dock
- Anker PowerExpand Elite 12-in-1 Thunderbolt 4 Dock (APEX)
#### Dock接続機器
- Display
	-  Dell 27 Monitor - S2722QC
	- 接続方式：Thunderbolt DisplayPort Alt Mode対応ポート
- 会議用スピーカーマイク
	- Jabra 510 (有線)
- キーボード
	- HHKB Hybrid Type-S(有線)
- マウス
	- Logicool 無線ドングル (MXErgoが接続)
- Webカメラ
	- Logicool c922n
- ネットワーク(RJ45)
	- BUFFALO スイッチングハブ
		- LSW6-GT-8NS/BK
	- ケーブル
		- ELECOM CAT5e
## 症状
Dockを開封して初めて起動済みPCへ接続すると正常に認識され、USBやHDMI、ThunderboltでのDisplay接続も含めて動作を確認していた。
その日の仕事が終わり、一度Sleep(≠休止 ハイバネーション )を実行。

翌日朝、PCを立ち上げた際になぜか充電(USB PD)は実行されるが、
 Dockにつないだデバイスやディスプレイ外部出力がされない状況になった。Sleepからの復帰時に発生したものと推察

# 調査メモ
Sleep復帰がだめとか不具合でありそうだな。。。
というわけでいろいろ試した。

## 確認結果
| 起動状況 | 再起動 | 休止->復帰 | Sleep->復帰|
| ----- | ----- | ----- | ----- |
|Dockデバイスを接続したまま| NG | NG | NG |
|Dockデバイスを復帰後に接続| OK | OK | OK |

この二つからわかるのは、SleepでもなんでもHWデバイスが停止した状態から復帰する際に、Thunderbolt4のネゴシエーションが失敗しているような気がしてくる。

## 安直にドライバの問題？-> NO
と思いたくなったのだが、Thunderbolt関連ドライバ以外思いつかない。
なのでGoogleで似た症状について探してみたが、、、まぁ見当たらない。

## Thunderbolt コントローラーが動作していない？
ここで気になったのがHWデバイスが一度停止することがトリガになっているので、起動時にちゃんとコントローラーが動作しきれていない気がしてくる。

幸いLenovoにはthunderboltポートが2個あるので、1個にディスプレイを直接接続し、もう一個にDockを接続する。
この場合もディスプレイもDockも認識しなかった。

ここから調べるの結構レイヤ低そうだなと思いながら、ふとバッテリーのステータスで電源接続状態でBaterrySavingModeなのに気が付く。
先日、据え置き(クラムシェル)ファンの音がうるさいので省電力設定を電源接続時も有効にしていた。

・・・・これか？

というわけでHigh Performance Modeに設定を変更してみた結果。
無事Sleepや休止からの復帰でも認識しました笑

昔からThunderboltコントローラーは電力を使うとは聞いていたので、
省電力設定で何かコントローラーの機能が無効化されている気がします。

# まとめ
これ以上細かい深追いはしませんが、Dockのように広帯域でのThunderBolt接続をする場合には省電力設定が原因で意図した動作しないケースがあるということのようです。
intellij ideaで特定の拡張子のファイルだけ白黒になってしまう時の修正方法


環境設定の中のファイル・タイプの中から今開いているファイルを確認してください。

![スクリーンショット 2022-11-17 16.25.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832042/b36ca998-c3af-c676-e0fc-de6748e1c8bd.png)

私の場合は、Rubyの中に`*.rb`がなかったために`.rb`rubyファイルとして認識できていなかったです。

また.gitなど普段隠れてしまっているファイルをintelliJで表示させるには、無視するファイルとフォルダータブの中から.gitなどを外すようにしてください。
Nuxt.js2.13.3でnpm run buildするとError: Cannot find module '@babel/preset-env/lib/utils' Require stack:が出た時の対処法

# 前提条件
以下の環境でnpm run buildするとError: Cannot find module '@babel/preset-env/lib/utils' Require stack:が出た時の対処法です。

```
    "core-js": "^3.25.3",
    "fibers": "^5.0.3",
    "nuxt": "^2.13.3",
    "vue": "^2.7.10",
    "vue-server-renderer": "^2.7.10",
    "vue-template-compiler": "^2.7.10"
```

出たエラーメッセージがこちら

```
Module build failed (from ./node_modules/babel-loader/lib/index.js):                       friendly-errors 12:57:45
Error: /Users/Documents/nuxtjs_website/.nuxt/client.js: Cannot find module '@babel/preset-env/lib/utils'
Require stack:
(以下割愛)
```

# @babel/preset-envをインストール
@babel/preset-envをインストールするか、もし既に入っている場合は古いバージョン 7.12.17を使用しましょう。

```
$ npm install --save-dev @babel/preset-env
```

# nuxt.config.jsを編集
インストールしただけでは以下のエラーが出る場合があります。

```
 WARN  Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-property-in-object since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.
The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding
        ["@babel/plugin-proposal-private-property-in-object", { "loose": true }]
to the "plugins" section of your Babel config.
```

その場合は、以下の記述をnuxt.config.jsのbuildに追加しましょう。

```
  build: {
    babel: {
      presets({ isServer }) {
        const targets = isServer ? { node: 'current' } : { ie: 11 }
        return [
          [require.resolve("@babel/preset-env"), { targets }]
        ]
      },
      plugins: [
        "@babel/syntax-dynamic-import",
        "@babel/transform-runtime",
        "@babel/transform-async-to-generator"
      ]
    },
}
```

# バージョンアップすれば出ないエラー
どうやらこちらのエラーはNuxt2の古いバージョンで起こるエラーで、Nuxt3では修正されているようです。
可能であればバージョンアップをしてしまうのも手かもしれません。

参考：[https://github.com/nuxt/nuxt.js/issues/8882](https://github.com/nuxt/nuxt.js/issues/8882)
「ここまで」の代わりに「。。。」が使えるよ。。。

# 問題提起 - なでしこ3のブロック表現について

「なでしこ1」から「なでしこ3」になって、一番変わったのが、ブロック表現です。

「もし・・・ならば・・・ここまで」とか「N回・・・ここまで」のように、ブロックの末尾に「ここまで」を記述するようになりました。例えば、以下のように記述します。（なお「｜」は省略できます。）

```
3回
｜　　　　「ワン＞🐕」と表示。
ここまで。
```

これを実行すると、3回「ワン＞🐕」と表示されます。プログラムを読んだままに実行されますね。

![スクリーンショット 2022-11-17 16.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/da4957a0-cc74-a057-3190-beb5dd7a3427.png)

でも実際のところ「ここまで」って書くの面倒ですよね。

そこで、いろいろな策が練られてきました。

## 💧（しずく）

「💧(しずく)」「。。。」は「ここまで」と書くのと同じ意味です。

https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%F0%9F%92%A7

```
3回
｜　　「ワン＞🐕」と表示。
💧
```

## インデント構文

プログラムの先頭に「!インデント構文」や「💡インデント構文」と書くと、なでしこv1のようにインデントをブロックと認識します。

https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%E3%82%A4%E3%83%B3%E3%83%87%E3%83%B3%E3%83%88%E6%A7%8B%E6%96%87

```
💡インデント構文
3回
　　　　　　「ワン＞🐕」と表示。
```

## インラインインデント構文

しかし、「えー、プログラムの先頭に「!インデント構文」と書くなんて面倒くさーい」という人のために作ったのが、インラインインデント構文です。Pythonのように、行末に「：」を書くと次の行をブロックと認識します。

https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%E3%82%A4%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%B3%E3%83%87%E3%83%B3%E3%83%88%E6%A7%8B%E6%96%87

```
3回：
　　　　　　「ワン＞🐕」と表示。
```

## 個人的な好み

上記のように、なでしこ3に、いろいろなブロック表現を実装してきました。それでも、個人的には「ここまで」が好きです。やはり、これが日本語として一番読みやすいのではないでしょうか。

ただし、めちゃくちゃ焦ってプログラムを書き上げる場合や、使い捨てが必要な場合は「ここまで」の代わりに「。。。」を使っています。そして、インラインインデント構文の「：」も時々使います。

いろいろ選択肢があるって便利です。。。

## まとめ

プログラミング言語における「ブロック表現」について、これだけ自由に記述方法を変えられるのは、他のプログラミング言語ではあまりないことです。ブロック表現の自由度は「なでしこ3」の特徴の一つでしょう！！

しかし、仕様について悩み、試行錯誤して、また、悩み、みんなの意見を聞いて、試行錯誤して、また悩む・・・の結果、こうなったという感じです。いやはや、プログラミング言語の設計って終わりがありませんね！！楽しい限りです。

また、ブロック表現について、「もっと良い方法があるよ」という方、ぜひ、アイデアをお寄せください！！！
WordPressのACFを使ってよくあるご質問のコード

ここ数ヶ月で、WordPressのACFを使ってよくあるご質問のコードを３回くらい書いているような気がします。
だいたいのhtmlは変わらないので、使い回せるように貼っておきます。

```php
<?php if( have_rows('faq_list') ): ?>
    <ul class="faq_ul">
    <?php while ( have_rows('faq_list') ) : the_row(); ?>
        <li class="faq_li">
            <div class="q_area">
                <span class="q_icon">Q</span>
                <p class="q_text"><?php the_sub_field('question'); ?></p>
            </div>
            <div class="a_area">
                <span class="a_icon">A</span>
                <p class="a_text"><?php the_sub_field('answer'); ?></p>
            </div>
        </li>
    <?php endwhile; ?>
    </ul>
<?php endif; ?>
```

ACFの繰り返しフィールドを使っています。
有料プラグインです。

ページによっては、FAQの[Google構造化データ](https://developers.google.com/search/docs/advanced/structured-data/faqpage?hl=ja)を入れるといいかもです。
CloudkitとCoreDataの同期について

## 結論

PrivateDatabase以外は使わないことにした。


## 理由

更新のスピードと頻度とトリガーに問題あった。
ユーザー掲示板みたいなところで、PublicDatabaseを使えるかなと思ったが、更新がアプリのキャッシュを消して立ち上げた瞬間しか走らなかった。ネット情報では30分に1回は更新があると書いていたが、自分は何回か試してできなかった。

また、マスターデータとして使いたかったが、アプリをダウンロードして、立ち上げた瞬間にデータが見当たらなくて、同期のために数分間は待たないといけないので、マスターデータとしては使えなかった。(Rmote notificationsとPush Notificationsは設定済)

プライベートのデータベースに関しては、iPhone買い替えとかのタイミングに役立ちそうだったので使っている。

Disctoryのタイプだと変更を検知できなくて、違うViewで更新された場合に、Viewの更新がトリガーされないので、UserIDとかの保存程度ならDictionary程度でいいが、個人設定の内容とかだと少し使いづらかった。

英語のサイトを見る限り、同期のスピードはかなり前から指摘されているぽいので、たぶん簡単には治らないのだろう。将来良くなるかもしれないけど、2022/11時点では、使えないという判断になった。

iPhoneのメモアプリを使ってみたらわかるけど、同期されてない時多いし、メモを書いている最中に同期されたりしてて、かなり使い勝手は良くなかったりする。
たぶん技術的な問題以外に大人の事情とかで、色々上手くいっていないのかもしれない。
ソリューションビジネス

# ソリューションビジネスとサービス形態
## ASP(Application Service Provider)
情報システムの機能やアプリケーションソフトウェアなどを```ネットワークで利用できるサービスを提供する事業者（プロバイダ）```のこと。これらの```事業者が提供```するサービスを```ASPサービス```という。各社員のパソコンへ個別にアプリケーションをインストールしたりバージョンアップする従来の管理方法に比べ、ASPサービスを利用すると```運用が容易で管理の手間や費用を低減```することができる。

## クラウドサービス
クラウドコンピューティングとは、インターネットを介して```アプリケーションやハードウェア（ストレージまたは保存領域)の機能```を提供するサービス全般のことを指す。
クラウドコンピューティングを取り入れた```ASPの発展型```が登場しており、このサービスのことを```クラウドサービス```と呼ぶことがある。

### クラウドサービスの種類と提供されるサービス内容
#### SaaS(Softwawe as a Service)アプリケーションを提供
インターネット経由で、```複数の顧客が同じアプリケーションを共同利用```するマルチテント方式のサービス。
個別利用のASPサービスに比べ、```費用の低減が可能```。ただし、その顧客固有の機能を追加するなどの```カスタマイズ不可```。

#### PaaS(Platform as a Service)　開発環境（プラットフォーム)を提供
アプリケーションを稼働させるための```環境(プラットフォーム)をインターネット経由で提供```するサービス。アプリケーションの開発環境などとして使われている。プラットフォームやOSの更新はプロバイダが行う。
また、アプリケーションのカスタマイズや運用支援などを行うサービスもある。

#### IaaS(Infrastructure as a Service) ハードウェアやインフラを提供
```ソフトウェアだけでなく、仮想的なハードウェアごとインターネット経由```で提供するサービス。ストレージやサーバ機能なども含まれており、```OSの選択も可能```。ただし、```管理・運用は顧客が自ら行う```必要がある。

#### DaaS(Desktop as a Service) デスクトップ環境を提供
端末で使う```デスクトップ環境をインターネット経由で提供```するサービス。
```コンピュータ環境の構築費用を大幅に削減```できる。外出先でも同じデスクトップ環境が使える反面、```不正利用やライセンス管理の問題```がある。

#### FaaS(Function as a Service) サーバを提供
```システムの運用やソフトウェア開発に必要なサーバ機能を提供```するサービス（サーバの運用管理はプロバイダ)。PaaSとの違いは、稼働させるプログラムへのリクエスト管理もプロバイダが行い、```イベントの発生時のみ稼働```するので、```処理時間分（＋リクエスト数)のみの課金で済む```。利用料の加減によってプロバイダがサーバのスケーリングも行うため、ECサイトの運営などに適している。
##### スケーリングとは？
装置やソフトウェア、システムなどの性能や処理能力を、要求される処理量に合わせて増強したり縮減したりすることをスケーリング
出典 

https://e-words.jp/w/%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0.html#:~:text=%E8%A3%85%E7%BD%AE%E3%82%84%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%80%81%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AA%E3%81%A9%E3%81%AE%E6%80%A7%E8%83%BD%E3%82%84%E5%87%A6%E7%90%86%E8%83%BD%E5%8A%9B%E3%82%92%E3%80%81%E8%A6%81%E6%B1%82%E3%81%95%E3%82%8C%E3%82%8B%E5%87%A6%E7%90%86%E9%87%8F%E3%81%AB%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A6%E5%A2%97%E5%BC%B7%E3%81%97%E3%81%9F%E3%82%8A%E7%B8%AE%E6%B8%9B%E3%81%97%E3%81%9F%E3%82%8A%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%92%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0

### オンプレミス
クラウドサービスなどを用いず、情報システムを構成する```設備や機器を社内に設置・運用```すること。
```コストは高いがセキュリティ管理を自ら行える```メリットがある。


# ハウジングサービスとホスティングサービス
### ハウジングサービス
顧客企業が用意した```サーバをサービス事業者に預けて設置してもらう```サービス。
ネットワーク回線の敷設、電源設備や空調設備など、```サーバの設置に必要な設備を、プロバイダ側が一括して提供```する。また、プロバイダが```運用管理を請け負うケースも```ある。```OSやソフトウェアなどを自由に選択でき、拡張性や柔軟性が高い```。

### ホスティングサービス
サービス事業者が用意するサーバを貸し出すサービス。
```サーバを丸ごと一台借りる専用サーバ```や、```複数の顧客企業で共同利用する共有サーバ```がある。自社でサーバを購入・設置したり、運用を行う場合に比べ、```コストは安い```が、```使用できるOSやソフトウェア、データ容量などの制限```を受ける。

# ソリューションサービスを利用した構築や運用
### SOA(Service-Oriented Architecture: サービス指向アーキテクチャ)
業務遂行に必要な各種サービス(機能）を行う```ソフトウェアを部品化して用意```しておき、顧客からシステム構築の要請があれば、必要なサービスを組み合わせてシステム全体を構成することで、```素早く、費用を抑えて対応```する考え方。

### MSP(Management Serveces Provider)
顧客企業が所有するサーバやネットワーク回線などの、```導入から運用までを一括して請け負う事業者及びサービス```。顧客との間で取り交わしたSLA(サービスレベル合意書)に基づき、```ネットワークを監視し、運用や保守```を行う。

# 出典　
https://gihyo.jp/book/2022/978-4-297-12375-8
ただただ簡単なloop文

今回はただただ簡単でシンプルなテストデータ作成を行います。
環境は Oracle Database 19c です。
```
SQL> create table test(C1 number(36),C2 varchar2(36));

Table created.

SQL> BEGIN
  2   FOR i IN 1..10 LOOP
  3    insert into test(C1,C2)values(i,'aaa');
  4   END LOOP;
  5  END;
  6  /

PL/SQL procedure successfully completed.

SQL> select * from test;

        C1 C2
---------- ------------------------------------
         1 aaa
         2 aaa
         3 aaa
         4 aaa
         5 aaa
         6 aaa
         7 aaa
         8 aaa
         9 aaa
        10 aaa

10 rows selected.
```
SQL 部分(insert ～)を LOOP させたい SQL に変更してください。

以上です。
Bolt for Pythonを使ったSlackアプリでratelimitedエラーに対応するには

Slackアプリを作っています。
今回は、TimeLineというアプリで、過去のpostをすべて取得するような機能を追加していたところ、APIの叩きすぎでratelimitに達してしまい、エラーが出ました。

```{'ok': False, 'error': 'ratelimited'}```

ああ、なるほど、となる訳です。

https://api.slack.com/docs/rate-limits

このページにある通り、Slack APIにはTierが設定されており、そのTierによって回数制限が課されています。
一時的なバーストは問題ないのですが、定常的に超えてくると上記のようなエラーを返すようになります。

詳細はこちらに書いてあります

https://api.slack.com/lang/ja-jp/rate-limit

ここにコード例が書いてあるのですが、残念ながらjsです。Pythonで取得するにはどうすればよいのか…とヘルプミーしてみたところ、いつもお世話になっておりますSlackの @seratch さんからレスポンスを頂きました。

私----
bolt for Pythonで APIを叩いたときに ratelimited が返ってきてしまいました。
Retry-Afterを取りたいのですが、取得方法がいまいちわからず。
どんな形で取得すればよいのでしょうか。

@seratch ----
https://slack.dev/python-slack-sdk/web/index.html#rate-limits
で取れますが、デフォルトでは有効になっていない retry handler を有効にする方が楽かな。
https://slack.dev/python-slack-sdk/web/index.html#retryhandler
ratelimited error が発生しそうな処理の前に handler を append するのがいいと思います。

-----
色々検索してたのに全然出てこなかった情報が一瞬で解決。上述の2ページにはコード例も書かれているのでそれを使っていきます。

retry handlerは使わないパターン
```Python
while True:
    try:
        response = send_slack_message(channel, message)
    except SlackApiError as e:
        if e.response.status_code == 429:
            # The `Retry-After` header will tell you how long to wait before retrying
            delay = int(e.response.headers['Retry-After'])
            print(f"Rate limited. Retrying in {delay} seconds")
            time.sleep(delay)
            response = send_slack_message(channel, message)
        else:
            # other errors
            raise e
```

Retry-Afterの値を見たかったので、こっちで実装してしまいましたが、おすすめパターンはこちら

```Python
# This handler does retries when HTTP status 429 is returned
from slack_sdk.http_retry.builtin_handlers import RateLimitErrorRetryHandler
rate_limit_handler = RateLimitErrorRetryHandler(max_retry_count=1)

# Enable rate limited error retries as well
client.retry_handlers.append(rate_limit_handler)
```
こうやってclientにappendすることで処理してくれる模様。便利すぎるな。

加えて、rate_limit_handler をセットした client を App 初期化時に渡すという方法でもできるように @seratch さんが実装をスタートしてくれたようなので、それが実現すれば最初に使っておくことで全部気にしなくて良いという状態になりそうですね。
↑の件
1時間ほどでリリースされました。すごい

https://github.com/slackapi/bolt-python/releases/tag/v1.15.5
初期化時に```client=WebClient(retry_handlers = retry_handlers),``` とすれば良い模様。めちゃ便利。

```Python
from slack_bolt.app import App
from slack_sdk import WebClient
from slack_sdk.http_retry import all_builtin_retry_handlers

# Customized retry handlers
retry_handlers = all_builtin_retry_handlers()

app = App(
    # this client will be used when generating a client per request later
    client=WebClient(retry_handlers = retry_handlers),
    signing_secret="xxxxx",
)

@app.action("a")
def listener(ack, client):
    # This client arg should copy the list of retry handlers
    # but it does not work in the way as of v1.15.4
    assert len(client.retry_handlers) == len(retry_handlers)  # this fails
    ack()
```



ということで、初期にはぶつからなかったエラーにいよいよぶつかったので、その対応をしましたよという話でした。
ありがとうございました @seratch
[ROS1 Noetic] トピックがPubSubできないぞ！？

屋外でWi-Fi介して，複数台のPCとROS noetic版を使って通信すると，
あるタイミングから，トピックが配信できない・受信できないという問題に遭遇した．

本気で，わからなかったが，あるコマンドを使うことで解決した．

# 対象
OS: ubuntu 20.04
ROS noetic

# 対処方法
- roscoreをやめて，rosmasterを使うこと
- rosmasterで，処理スレッド数とソケットのタイムアウトの時間を設定すること

必要最低限のノード管理プロセスだけ立ち上げて，
処理スレッド数（10）とタイムアウトの時間（40）を設定する．

```sh:roscore代わりに，rosmaster
rosmaster --core -w 10 -t 40 --master-logger-level=fatal
```

rosmaster実行して，立ち上げたいノードをすべて立ち上げ切ったら，
ログを削除する．だんだんと重くなる原因．

- ~/.rosフォルダ内のログを消しちゃうこと
```sh:ログ全消し
rosclean purge -y
```
これで，強制的にログ・ファイルが削除される．
定期的に，このコマンドを実行した方がいい．

これで，トピックが飛ばなくなるといった現象は起こらなくなった．

めでたし，めでたし
OUPC2022 I「Huge Bingo」解説

# はじめに

「Huge Bingo」writer の Badlylucky です。OUPC2020 時代からの原案を放流しました。

yukicoder 既出[^1]であり一時は出題が危ぶまれましたが、OUPC2022 は非常に難しい問題が揃ってしまったため全体のバランスを取るために出題することとしました。また、レイドチーム導入の観点では問題数が多い方が望ましいため、その意味でも出題するべきとなりました。

# 問題

[I「Huge Bingo」](https://onlinejudge.u-aizu.ac.jp/beta/room.html#OUPC2022/problems/I)

$N \times N$ マスの一般的なビンゴのシートが与えられるので、$K$ 回ビンゴのくじを回したときにビンゴができる個数の期待値を求めてください。

# 解説
## Step1: 式を立てる

まず、最終状態の場合の数は $\dbinom{N^2}{K}$ です。

また、ビンゴが $1$ つできる場合の数は $K-N$ 回の試行中に特定の $5$ つ **ではない** 数字を当て、残りの $N$ 回でぴったりその $5$ つの数字を当てる場合の数と同じなので、$\dbinom{N^2 - N}{K-N}$ です。

それぞれの列にビンゴができる確率変数は独立ではありませんが、期待値の線形性が成り立つためこれにビンゴの数をかけることで問題の期待値を求めることができます。

よって、問題の答えは以下のようになります。

$$
\dfrac{(2N+2)\dbinom{N^2 -N}{K-N}}{\dbinom{N^2}{K}}
$$

## Step2: 数学的に考察して高速化する

しかし、これを素直に計算しようとすると $N^2 \leq 9\times10^8$ のため $(9\times10^8)!$ が必要になり、実行時間制限を超過してしまいます。なので、上の式を工夫して高速化します。

二項係数の定義より、上の式は以下のように分解できます。

$$
\dfrac{(2N+2)\dfrac{(N^2 - N)!}{(K-N)!(N^2 - K)!}}{\dfrac{N^{2}!}{K!(N^{2}-K)!}}
$$

これを約分すると、最終的に以下の式になります。

$$
(2N+2)\dfrac{{}\_{K}\mathrm{P}\_N}{{}\_{N^2}\mathrm{P}\_N}
$$

${}\_{K}\mathrm{P}\_N = K \times (K-1) \times \dots \times (K-N+1)$、${}\_{N^2}\mathrm{P}\_N = N^2 \times (N^2 - 1) \times \dots \times (N^2 - N + 1)$ なので、この式の計算は $\mathrm{O}(N)$ でできます。よって、時間内に解を求めることができるようになりました。

ただし $K<N$ のときがコーナーケースとなり、ビンゴができないので期待値は $0$ となります。

Step2 の Python での実装例を以下に示します。

```python
#!/usr/bin/env python3
MOD = int(1e9+7)
N, K = map(int, input().split())
if K < N:
    print(0)
    exit(0)
X = 1
Y = 2 * N + 2
for i in range(N):
    X = (X * (N * N - i)) % MOD
    Y = (Y * (K - i)) % MOD
Z = (Y * pow(X, MOD - 2, MOD)) % MOD
print(Z)
```

[^1]: [No.242 ビンゴゲーム](https://yukicoder.me/problems/638)。これ自体は解説にある高速化技法を使わなくても解けるが、sugarknri さんによる[解説](https://sugarknri.hatenablog.com/entry/2016/05/20/022800)によってこの高速化手法が指摘されている。
UbuntuでUSBデバイスのポート名・デバイス名を同じにする方法

ubuntuでは，USBをつなげるとデバイスファイル名がその都度決まる．
そのため，挿した順番などで，デバイス名が変わってしまう．

ArduinoやF9Pでシリアル通信をするとき，毎回変わることは避けたいので，固定する方法を紹介する．

# デバイスが異なるUSB場合

USBポートに接続すると、以下のIDを取得することができる。  
これはデバイスごとに異なるので、このIDを元にデバイス名を固定する。
- ID_VENDOR_ID
- ID_MODEL_ID
- ID_SERIAL_SHORT


## 1. 接続したいデバイスを接続
ここでは，ArduinoをUSBで挿す．
このとき，割り振られたデバイス名を調べておく
```sh
ls /dev/tty*
```
Arduinoは，ttyACM0とかに割り振られる．

## 2. デバイスの3つの情報を調べる．

3つの情報を調べる．

- ID_VENDOR_ID
- ID_MODEL_ID
- ID_SERIAL_SHORT

割り振られたデバイス名さえ知っていれば，以下のコマンドで調べられる．
```sh
udevadm info -q property -n {割り振られたデバイス名} |  grep -E "ID_SERIAL_SHORT=|ID_VENDOR_ID=|ID_MODEL_ID="
```

## 3. デバイスをudevルールに登録する

ルールファイルを新規・追加作成する
ここではファイル名を/etc/udev/rules.d/100-usb-serial-devices.rulesとする
*-usb-serial-devices.rules（*が大きいほどルールの優先度が高くなる）

```sh
sudo gedit /etc/udev/rules.d/100-usb-serial-devices.rules
```

以下のように追加する
```sh:/etc/udev/rules.d/100-usb-serial-devices.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="調べたID_VENDOR_ID", ATTRS{idProduct}=="調べたID_MODEL_ID", ATTRS{serial}=="調べたID_SERIAL_SHORT",SYMLINK+="表示させたい名前", MODE="0666"
```

認識後は，[/dev/表示させたい名前]でデバイスが認識されるようになるし，
権限も666で自動付与される．

## 4. 最後にリロードする
```sh
sudo service udev reload
sudo reboot
```

# デバイスが同じ場合

同じデバイスの場合、上記の方法は使えない。  
（RTK-GNSSモジュールのF9Pなどがそれ）

なので、接続したUSBのポート番号で識別する。

## 1. 接続したいデバイスを接続
ここでは，F9PをUSBで挿す．
このとき，割り振られたデバイス名を調べておく
```sh
ls /dev/tty*
```
F9Pは，ttyACM0とかに割り振られる．

# 2. デバイスの接続ポートを確認する。
```sh
udevadm info -q property -n /dev/ttyACM0
```
```sh:結果
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3.3/1-3.3:1.0/tty/ttyACM0
```
/tty/tty*の一つ前の「**1-3.3:1.0**」が必要な情報。
この部分は、USBハブを使っているかどうかにもよるので、とりあえず一つ前とおぼえておけば良し。

## 3. デバイスをudevルールに登録する

ルールファイルを新規・追加作成する
ここではファイル名を/etc/udev/rules.d/100-usb-serial-devices.rulesとする
*-usb-serial-devices.rules（*が大きいほどルールの優先度が高くなる）

```sh
sudo gedit /etc/udev/rules.d/100-usb-serial-devices.rules
```

以下のように追加する
```sh:/etc/udev/rules.d/100-usb-serial-devices.rules
KERNELS=="1-3.3:1.0", SYMLINK+="{表示させたい名前}", MODE="0666""
```

認識後は，[/dev/表示させたい名前]でデバイスが認識されるようになるし，
権限も666で自動付与される．

**ただし、この方法はUSBの接続ポートを変える事はできないので注意。同じポートにUSBを挿せば、どんなUSBデバイスも同じ名前で表示されることになる**

## 4. 最後にリロードする
```sh
sudo service udev reload
sudo reboot
```

おわり。
C# NLog.Configパッケージが非推奨になった！？

# はじめに
普段何気なく使用していたNLogだが、ある日5.0にアップデートしたところNuget ManagerでNlog.Configが非推奨になっていることに気づいた。
そこでなぜ非推奨になったのか調べてみた。

# NLog.Configの非推奨
NLog.Configが非推奨のパッケージとなった。（2021/08/25 NLog5.0）
理由としてはパッケージNLog.Configが正しく動作しなくなったからだと記載されていた。

以下原文
Reason: NLog.Config-nuget-package stopped working properly when Microsoft refactored the nuget-package-system to support <packagereference>. Microsoft disabled the ability for a nuget-package to inject a default NLog.config into the project directory when one didn’t exist. Instead it became overwrite always, so when deploying an application with dependency on NLog.config-nuget-package, then it would unexpectedly reset the NLog.config.

要約すると、NLog.Configパッケージに依存するアプリケーションをデプロイすると既存のNLog.configファイルがリセットされるそうだ。

詳細は以下URL参照
https://nlog-project.org/2021/08/25/nlog-5-0-preview1-ready.html

# 解決策
パッケージNLog.Configをインストールせず、NLog.configファイルを手動で作成し、アプリケーションプロジェクトに追加すればよい。
あとは今まで通り使用できる。
【WSL2】やっとwslgがWindows 10に降りてきました！

数日前にストア版WSL2導入出来たけど動かんと記事書いたが、直近のWindows Update で動くようになりました

対象のKBは以下
```
2022 年 11 月 15 日— KB5020030 (OS ビルド 19042.2311、19043.2311、19044.2311、19045.2311) 
```

さてお待ちかねの、今までできなかった--versionオプション！

```
==== Windows10 22H2
$ wsl.exe --version
WSL バージョン: 1.0.0.0
カーネル バージョン: 5.15.74.2
WSLg バージョン: 1.0.47
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.19045.2311

==== Windows10 21H2のリリースプレビューチャネル
wsl.exe --update したらwsl2起動不可に（汗、一度OSの再起動

$ wsl.exe --version
WSL バージョン: 1.0.0.0
カーネル バージョン: 5.15.74.2
WSLg バージョン: 1.0.47
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.19044.2311
```

これが何を意味するかというと`wslg`と`systemd`解禁ってことですな
まぁsystemのlinuxも動き出すのでいろいろリソースは奪われてそうだけど
```
C:\Users\alice>wsl --system
wslg [ /mnt/c/Users/alice ]$ cat /etc/os-release
NAME="Common Base Linux Mariner"
VERSION="2.0.20221010"
ID=mariner
VERSION_ID="2.0"
PRETTY_NAME="CBL-Mariner/Linux"
ANSI_COLOR="1;34"
HOME_URL="https://aka.ms/cbl-mariner"
BUG_REPORT_URL="https://aka.ms/cbl-mariner"
SUPPORT_URL="https://aka.ms/cbl-mariner"
wslg [ /mnt/c/Users/alice ]$ free -h
               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       321Mi       2.4Gi        10Mi       1.1Gi       3.2Gi
Swap:          1.0Gi          0B       1.0Gi
wslg [ /mnt/c/Users/alice ]$
```
321Mか、、
Unityで心理実験ーその０


## はじめに
どうも
某心理科学科４年のI.Kentoといいます

このたび研究費を使ってVive Pro eyeを買ってもらい、最近はうっきうきでUnityを使っています。
毎日がとても楽しい日々で幸せなのですが、ふと思いました。
「後輩たち…Unity使えるかな…」と

私は高専から心理科学科へ入るという稀有な経歴であったためプログラミングや電子機器といったことに抵抗がなく、楽しんでプログラミングに望めているのですが、周りを見るとやはり文系学科なだけあってそういったことに抵抗を感じる人や苦手だと感じてあきらめてしまう人が多々見られます。
さらに「Unityで心理実験やってみよう！」という情報は少なく、心理実験を目的とした人にとっては敷居がとても高いのが実情といえます。

 **「だったら私が書けばいいじゃん！」** と思い立ったのがこの記事です。
どうせ今年度で卒業して来年はエンジニアとして働く人間です。
こういったエンジニアが多くいる中に身を投じるという意味でも、
後輩たちのために轍を残すという意味でも、やってみて面白くなるんじゃないかなと思ってます。
ちまちま書いていくのでのんびり待っててもらえると嬉しいです

※私はプログラミングは下手の横好きですので見苦しいコードを披露することになるかもしれません。
ご了承いただけると幸いです。

---
twitter↓
https://twitter.com/dodocker1?t=8G_9dRCIIKqIow2_UmeZMw&s=09
エクセルでフィルターの絞込を一括解除

# 概要

下記のような複数カラムに対する絞り込みを一括解除して…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8733cfb7-62ff-a3b6-12dd-82597ddbc67c.png)

 ↓ こう一気にリセットしたい時。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e601acbf-8d52-7805-f367-6f839bc9123a.png)

カラム一つ一つ解除していくと面倒。
それに解除し忘れによる確認漏れの心配もある。

# やり方

データタブ ⇒ クリア 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9b610cf2-9700-b845-15e1-e7cb66889747.png)

# 参考サイトさん

https://did2memo.net/2016/10/11/excel-clear-all-filters/

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2311
Microsoft Excel for Microsoft 365 MSO (バージョン 2210 ビルド 16.0.15726.20188) 32 ビット
MySQL Workbenchで踏み台サーバ経由でデータベースに接続する

MySQLWorkbenchにおいてどのように踏み台サーバーを経由して接続するのかな〜と思い調べました

https://mashimashi.net/skill/db/mysql/621/

上の記事を参考に進めたところ、自分の環境では接続に失敗しました。

よく考えてみると、configの設定をProxyCommandにて設定しているので
普通にSSH接続すればいいのでは？と考えました。

ここからはただのSSHの接続設定をするだけ下に参考記事を載せておきます。
踏み台サーバのhostnameを書いていたところを接続したいサーバーのhostnameを
直接書くことで接続成功しました。

https://php-tips.com/2011/05/23/mysql-workbench-with-ssh-connection/

ただ踏み台サーバを経由するようにconfigで設定していたのを忘れていて難しく考えていただけでした。
多分これで踏み台サーバ経由でデータベースに接続することができたのではないかと思います。
PageSpeed Insights の パフォーマンス 改善の参考リンク集

# ざっくり
計測されるパフォーマンス値は主に以下の6つの項目と重要度で評価される。

項目|重要度（Weighting）| 改善が必要| 貧弱
--|--|--|--
TBT (Total Blocking Time)|30|x>1800|x>3000
LCP (Largest Contentful Paint)|25|x>3400|x>5800
CLS (Cumulative Layout Shift) |15|x>2500|x>4000
FCP (First Contentful Paint)|10|x>3800|x>7300
SI (Speed Index)|10|x>200|x>600
TTI(Time to Interactive)|10|x>0.1|x>0.25


# 計測系
https://pagespeed.web.dev/

https://yellowlab.tools/

https://googlechrome.github.io/lighthouse/scorecalc/

# 解説系

## LCP
https://web.dev/i18n/ja/lcp/

## TBT

https://web.dev/i18n/ja/lighthouse-total-blocking-time/

https://web.dev/i18n/ja/tbt/

## TTI
> First Contentful Paint (FCP) から開始します。
少なくとも 5 秒間の落ち着いている期間を時間の経過順に探していきます。この場合の落ち着いている期間とは、長く時間がかかっているタスクがなく、実行中のネットワーク GET リクエストが 2 件以下となる期間として定義されます。

https://web.dev/i18n/ja/tti/
https://web.dev/lighthouse-total-blocking-time/

## SI
https://web.dev/speed-index/

## その他

https://web.dev/i18n/ja/long-tasks-devtools/

https://web.dev/mainthread-work-breakdown/

https://blog.leap-in.com/use-web-worker/

https://blog.leap-in.com/lets-learn-how-to-browser-works/

https://qiita.com/kyntk/items/7ae8763961b62111889e

https://www.sprocket.bz/blog/20220419-pagespeedinsights.html

https://fastcoding.jp/blog/all/info/pagespeed/



# 実践系

https://tech.speee.jp/entry/page-score-improvement-for-engineers-part-1

https://coosy.co.jp/blog/pagespeedinsights-improvement/


# すぐやれそうなこと
- headでjsを読み込んでいる場合は、deferをつける。
- 開発者ツールでJSなどがLONG TASKとしてマークされた場合は、JSの分割や実装方法を見直す。
- JS、CSSから、無駄な記述、importなどを省く。
- 画像を軽量化する。
プログラミング言語のバージョンアップ運用を検討してみた

## 背景

担当プロジェクトで使用している「Ruby」のバージョンがサポート終了（EOL）となることを受けて、バージョンアップのやっていき方を検討してみたため、記録としてメモを残します。

当初は、「バージョンアップをしなかった場合に起こりえるセキュリティリスク」を全て洗い出して検討しようとしていたが、それはあまりにも壮大な話であったため、リスク対応と対応する工数のバランスについてを検討した。



## 今回の結論

EOLになるからと言ってバージョンアップをするのではなく、CVE（脆弱性情報）として公表されたものの中で対応が必要な場合に対応することとした。

（参考）[cve.mitre.org](https://cve.mitre.org/)

そのような脆弱性情報のほとんどは大きなニュースとして回ってくることが多く、かつ社内の担当部署から情報収集・展開がなされる運用も出来ているため、このような結論に至った。

## 理由

理想でいうと、マイナーバージョンの安定版が出るたびに小まめにバージョンアップをしていくのがセキュリティ面から言うと理想的ではあるが、工数がかかるため、開発速度は遅くなり、「本当に必要なこと」ではないことに工数を使うことにもなりかねない。

そこのバランスは非常に難しいが、「何か問題が起きてから」ではなく、「何か問題が起きる可能性があることが公表されてから」の対応が、今のプロジェクトとしてバランスが良いと判断した形となった。

（参考）[Apache Log4j の事例から学ぶ脆弱性対策](https://www.cybertrust.co.jp/blog/linux-oss/system-monitoring/log4j-vulnerability.html)


## こういうことが出来たら理想的

当該プロジェクトはDockerを使っており、Rubyのバージョンアップをしたい場合は、DockerImageの番号を書き替えてBuildし直すだけで出来る。

バージョンアップしたときに、自動的にテストを回すようにして、ワーニングの有無を確認して、本番にも適応する、というような運用が構築（できれば自動化）が出来ると、Dockerの便利さも活かしつつ、小まめなバージョンアップを工数を大きくかけずにやっていけるかもしれない。

ただ、自動テストの「カバレッジ100％」は難しいこともあると思うため、「どこまでは自動テストで見る、ここは自動テストでの対応は難しいので目視確認するようにする」などを、担当者間で合意しておくということでも対応はできそう。

## バージョンアップをするときの注意点

- 「安定版（Stable）」のみを使用する
- マイナーバージョンアップは「1個ずつ」行う
- メジャーバージョンアップは大きな仕様変更の可能性があるため慎重に対応する

（参考）[プログラム言語は常にバージョンアップしておいたほうが良い理由](https://blog.furu07yu.com/entry/upgrade-program-language)

---

以上です。
こんなテスト仕様書は書かないで

## はじめに
これまでのテスト実施やテスト仕様書作成の経験を踏まえてこんなテスト仕様書は書いてほしくないという思いを伝えたいと思います！

## その１　操作方法が分からない:sob:
システムの仕様が分かる人（自分など）向けにしか書かれておらず、詳細な操作方法が書かれていないというケースです。
テスト仕様書は必ずしも自分がやるとは限らないため、システムの仕様を把握していない人でも実施できるようなテストケースを記載すべきです。丁寧に書くと手間なのですが、結局この操作方法はどうやるのかという問い合わせが来る可能性が高くなり説明するのが手間ということにも繋がると思います。

**Point**:bulb:
入社したての新卒でも分かるかということを想像しながら丁寧に記載する

## その２ 期待値が曖昧:sob:
例として「〜が正しいこと」のように人によって判断がブレてしまうケースです。
人によって判断がブレてしまうと不具合が生じていても正しい期待値としてテストが進められてしまう可能性があります。そうなると、テスト時に発見できていた不具合の発見が遅れてしまい大きな不具合へと繋がるということもあり得ます。

**Point**:bulb:
抽象的な表現は避けて具体的な期待値を記載する

## その３　同じ操作を何回もやっている:sob:
１回の流れでまとめてテストができるのに分けて書かれていたり、不要なデータの作成が多いケースなどです。
一連の流れの中で確認できるものは効率性を考えてまとめて確認をしてしまいたいです。テスト仕様書を作成するということだけを考えるのではなく、後行程となるテスト実施時のことも考えながら記載してあげると良いでしょう。テストに掛かる時間が長くなると何事でもそうだと思うのですが、疲れて集中力が切れてきます。テストは不具合が無いかを確認する品質問題に関わる重要な過程なので、テスト実施者が快適にテストを進めることができるように意識することが大切です。

**Point**:bulb:
テスト実施者の気持ちを考える

## その４ 複数のテスト結果が１つの結果欄にまとめられている:sob:
例えば、複数ブラウザのテストをするケースなどです。
ブラウザ毎に結果を記載する箇所が分かれていなかったため、自分のエディタで結果を残して全部実施した後にテスト仕様書に結果を記載するというような経験をしたことがあります。テスト仕様書とは別の場所で結果を管理をしてしまうとテストの実施や不具合の発見が漏れてしまう可能性があります。全ての結果を記載できるようにテスト仕様書を書いてあげるとテスト実施者が楽になります。また、不具合の管理もしやすくなるかと思います。

**Point**:bulb:
テスト結果には１機能のみの結果を記載できる作りにする

## さいごに
個人的にはテスト仕様書の作成は一番辛い作業です:imp:ですが、それよりもリリース後に不具合が発生する方がもっと辛いため、テスト時に不具合を発見できるようにテスト仕様書の作成は丁寧に作成することを心掛けています。長いテストケースの作成は心が折れてしまいそうになりますが:sweat_smile:。。
テスト仕様書の作成は辛いですが、一緒に頑張りましょう:point_up_tone1:
TypeScriptの多重ループ読みにくいのでデカルト積でループしたいけどメモリ負荷高いのでデカルト積の要素を返却するジェネレータ（型定義有）

# TL;DR

https://www.npmjs.com/package/cartesian-generator

を異なる型の配列でも使えるように型定義しただけです（プルリクだしてみようかな）

```typescript
type CartesianProductElement<T extends unknown[][]> = T extends []
  ? []
  : T extends [Array<infer V>, ...infer W extends unknown[][]]
  ? [V, ...CartesianProductElement<W>]
  : [];

export function* cartesian<T extends unknown[][]>(
  ...args: T
): Generator<CartesianProductElement<T>, void, undefined> {
  if (args.length === 0) yield [] as any;
  else {
    const [head, ...rest] = args;
    for (const h of head) {
      const restIter = cartesian(...rest);
      for (const r of restIter) {
        yield [h, ...r] as any;
      }
    }
  }
}

cartesian([1, 2], ['a', 'b']) // => [[1,'a'], [1,'b'], [2,'a'], [2,'b']]
```
執筆文字数の推移を自動でグラフにする拡張機能「Writer Stock」を作りました。

# はじめに
サポーターズさんが行っているハッカソン[技育CAMP](https://talent.supporterz.jp/geekcamp/)に参加して、本成果物を作りました。
当時のプレゼン資料。

https://www.docswell.com/s/PenguinCabinet/K3D1MZ-Writer-Stock-giiku-camp

# 解決したいこと
小説や技術本の執筆文字数をグラフにしたいと思ったことはありませんか？
ですが、Excelで一々文字数と日付を記録するのも面倒ですよね。
そこで本拡張機能は、gitのコミットから自動的に文字数の推移のグラフを作成します！

# Writer Stockの紹介
このようなgitコミットから…
![img6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206651/236b94ff-3de9-defe-cd9f-395cbfad8870.png)
文字数の推移のグラフを自動生成します。
![img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206651/771bf077-9076-1710-e7b8-66aa7eafec4d.png)
VS Codeの拡張機能であるため、シームレスにグラフを確認できます。

![img7.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206651/39414ef5-3a47-49a4-a1b9-4434cd769b62.png)

「.wsignore」に記述すると、そのファイルを文字数のカウントから除外できます。
また、gitのステージエリアにファイルがある状態で、実行するとうまくいかないバグがあるので、コミットしてから実行してください。

# インストール

https://marketplace.visualstudio.com/items?itemName=PenguinCabinet.writer-stock

# 今後の開発について
リポジトリです。OSSですので、誰でも開発に参加できます！

https://github.com/PenguinCabinet/Writer-Stock

今後の実装予定
* アイコンがセンスないのでどうにかしたい
* オフライン環境での実行
* gitのステージエリアにファイルがある状態で、実行するとバグる問題を解決する

# 利用者の声(自分)
僕は趣味で小説の執筆をしているのですが、Writer-Stockを活用しました。
14万文字を執筆して、初めて公募に出せましたが、その時のモチベーションアップにとても良かったと思いました。
自分の成果物を自分で活用できるとうれしいですね。

# 技術的なお話
## 使用した技術スタック
* JavaScript
* HTML

## その他

VS CodeはElectronのため、拡張機能開発にWEBの技術をそのまま流用できる!!(ありがたい)

先ほどのグラフの表示部分も、WebViewでやっているので普通にchart.jsを使っています。

# 終わりに
ご活用いただけると嬉しいです。
MacでのSSH接続時のタイムアウト防止・・・?


# はじめに

ssh接続した際にしばらく放置すると自動的に切断される現象が発生しており、これを対処出来るか試行錯誤中。。。

# 結論

結局接続先のサーバ設定には逆らえない。。。
サーバ設定で切断時間が設定されていると、こちらでどんな設定をしても切断は免れなかった。


# 試行錯誤した内容

sshの設定ファイル"~/.ssh/config"(ここはデフォルト位置)に設定する事で一部のサーバでは無限接続を実現出来た。

```~/.ssh/config
Host *
  ServerAliveInterval 60
  TCPKeepAlive yes
  UseKeychain yes
```

configファイルに上記の設定を追加すると、ssh接続の全てに適用される。

"ServerAliveInterval" : 指定された間隔でサーバに接続確認を実施する為、切断されなくなる。

上記の設定では、サーバ次第では切断されないが、それはそれで問題がありそうなので"ServerAliveCountMax"などで確認回数を設定するなどの施策が必要になると思われる。
ただ調べ物をしている間だけ切断しないで欲しいといった要望には応えられない為、どうすればいいか模索中。。。

やっぱり理想は、一定期間操作されなければ切断して欲しい。。。操作をしたらカウントリセットしたりしてくれないかな。

# PR

エンジニアとして一緒に働きませんか！！
創業から3年が経ち、成長段階の弊社ですが、1人の裁量が大きいためスキルを身につけやすい環境です。
フレックス出勤やリモートワークも取り入れ、エンジニアにとって働きやすい制度も整っております。
このように、自分らしい働き方を見つけながら、さまざまなことに挑戦し、成長していきたいエンジニアを絶賛募集中です!!

募集要項 - 株式会社ブレイブスタジオ
https://bravestudio.co.jp/%E6%8E%A1%E7%94%A8/%E5%8B%9F%E9%9B%86%E8%A6%81%E9%A0%85/
OUPC2022 B「CD Collector」解説

# はじめに

「CD Collector」 writerのkotamanegiです。導入文はほぼ実話です。

for文で解くことができる、一番簡単な問題枠として出題しました。
OUPC2022で少なくとも2問は「解けた！」をお届けするために置いています。

# 問題の概要

[問題ページ](https://onlinejudge.u-aizu.ac.jp/beta/room.html#OUPC2022/problems/B)

$K$ 個の店舗をめぐって $N$ 種類すべてのCDを揃える問題です。 各店舗が取り扱っているCDの種類は異なるため、複数の店舗を巡る必要があります。 店舗は店舗 $1$ から $K$ まで順番に数直線上に配置されており、距離は等間隔で $D$ メートルです。 店舗 $1$ から出発するとき、全てのCDを揃えるために何メートル歩く必要があるかを求めてください。

# 解法

重要な性質として、店舗 $i$ を訪れるならば道中で店舗 $i-1$ にも訪れることができるという性質があります。 店舗は直線状に並んでいるため、店舗 $1$ から店舗 $i$ までの通り道の中に店舗 $i-1$ が必ず含まれています。 この性質を利用すると、以下のように問題を言い換えることができます。

> 店舗 $1$ から店舗 $k$ までの店舗を訪れることで $N$ 種類のCDが揃うような最小の $k$ を求め、$D \times (k-1)$ を出力せよ。

各CDは店舗 $1$ から一番近い店舗で買うとして良いです。そのため、この問題は $N$ 種類のCDのうちすでに購入したCDの種類をフラグで管理することによって $\mathrm{O}(NK)$ で解くことができます。疑似コードは以下の通りです。

```
# 入力: N,K,D:整数, shop_CD_list: 各店舗が取り扱っているCDのリスト 
# 出力: 答え

flag を長さ N の配列として 0 で初期化する

for k = 1 to N do
  for CD in shop_CD_list[k] do
    flag[CD] = 1 # 店舗 k が扱っているCDを購入したとしてflagを立てる
  end for
  if flag の各要素が全て 1:
    return D(k-1) # 店舗 k までで K 種類のCDが全て揃った
end for

raise Error # N個の店舗を巡れば必ずK種類のCDが手に入るはずなため、エラーを出す
```
Embedded Node-REDのカスタムノードについて

## 要約
Embedde Node-REDのユーザディレクトリは絶対パスで指定しましょう。

## Headless Node-REDが欲しい
Node-REDの実行時にはエディタ等のWeb UIは不要なのでいわゆるHeadlessなモードが欲しかった。軽く調べたところ、[httpAdminRootにnullを設定する](https://discourse.nodered.org/t/headless-node-red-instance/29053)というのが見つかったが、Webサーバ自体は起動してしまうようなので求めているものとは違った。

## Embedded Node-RED

[Node-REDのソース](https://github.com/node-red/node-red/blob/master/packages/node_modules/node-red/lib/red.js#L54)を眺めていると、initの第1引数にnullを指定してWebサーバを渡さないことを想定しているような書き方だった。なので以下のガイドを参考にHeadlessなEmbedded Node-REDを作ることにした。

https://nodered.jp/docs/user-guide/runtime/embedding

とは言え作るのは簡単である。通常のNode-REDでフローを開発し、そのユーザディレクトリ(./user)をそのまま指定して動かすことを想定している。なお、disableEditorをtrueにしないとエラーが発生して起動しない。

```JavaScript:headless.js
const RED = require('node-red');
const settings = {
    userDir: './user',
    flowFile: 'flows.json',
    disableEditor: true
}

RED.init(null, settings);
RED.start().then(
    () => {
        console.log('embedded Node-RED is started!');
    }
);
```

## カスタムノードモジュール
しかしながら、Node-REDのWebコンソールからインストールしたカスタムノードを使用したフローをheadless.jsで動かそうするとノードが見つからず、エラーになってしまう。

```
embedded Node-RED is started!
...
17 Nov 12:56:54 - [info] Waiting for missing types to be registered:
17 Nov 12:56:54 - [info]  - calculator
``` 

カスタムノードはユーザディレクトリのnode_modules配下に確かに存在しているはずなのに。

## ユーザディレクトリの指定方法
ググってみたところ、Embedded Node-REDのユーザディレクトリを相対パス指定すると、node_modules配下のカスタムモジュールがロードされないという情報を発見。
https://stackoverflow.com/questions/54494327/node-red-custom-node-modules-location

これをそのまま丸パクリすることで解決することができた。

```JavaScript: superheadless.js
const RED = require('node-red');
const path = require('path');
const current = path.dirname(__filename);

const settings = {
    userDir: current + '/user',
    flowFile: 'flows.json',
    disableEditor: true
}

RED.init(null, settings);
RED.start().then(
    () => {
        console.log('embedded Node-RED is started!');
    }
);
```
Discordで伝言をしてくれるbot

# 伝言botとは
### 概要
Discordで伝言をしてくれるbotです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2687626/bbbb9cd1-5f57-ba8f-8286-49d789f6d842.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2687626/932a8e1b-27b2-0b49-ee33-24d91e11c222.png)
* このbotと同じサーバーに参加しているユーザーのDM
* このbotと自分の両方が参加しているサーバー内のテキストチャンネル

に日時指定してメッセージを送信できます。
### 自動送信ではなく「伝言」
botからメッセージが届く形にすることで、匿名にして質問箱みたいに遊んだり、自分に伝言してリマインダーとして使ったりできます。

# 招待リンク
https://discord.com/api/oauth2/authorize?client_id=1042433118302392421&permissions=532576467008&scope=bot

# 使い方
### 1. 伝言を登録する
dengon addで伝言を登録します。
* **送信先**
-toで送信先を指定します。
    * タグ付きのユーザー名でユーザーのDMに送信
    このbotと同じサーバーに参加しているユーザーにのみ送信できます。

    * "$"+[ServerID]+":"+[ChannelID]でサーバーのテキストチャンネルに送信
    このbotと自分の両方が所属しているサーバーにのみ送信できます。
    ServerIDとChannelIDは dengon servers , dengon channel で取得します。
    ~~~
    -to test#0123
    ~~~
    ~~~
    -to $0:0
    ~~~
* **伝言主（表示名）**
-fromで送信先で表示される伝言主の名前を指定します。
    ~~~
    -from ぼいど
    ~~~
    省略時は「('ω')」になります。
* **メッセージ**
-mでメッセージ本文を入力します。
    ~~~
    -m hello
    ~~~
* **日時**
-tで送信日時を指定します。
    ~~~
    -t 2000-01-01-1200
    ~~~
* **例1：test#0123のDMに送信**
    ~~~
    dengon add -to test#0123 -from ぼいど -m hello -t 2000-01-01-1200
    ~~~
* **例2：ServerID:0 , ChannelID:0のテキストチャンネルに匿名で送信**
    ~~~
    dengon add -to $0:0 -m hello -t 2000-01-01-1200
    ~~~
### 2. 伝言を削除する
dengon deleteで未送信の伝言を削除できます。
* **伝言ID**
-idで削除する伝言IDを指定します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2687626/7637885c-c505-b881-cc2e-cf7d3889fbd1.png)
    ~~~
    dengon delete -id 036046
    ~~~
### 3. 伝言listを表示
dengon scheduleで自分が登録した未送信の伝言を表示します。
~~~
dengon schedule
~~~
### 4. サーバーリストを表示
dengon serversで送信可能なサーバーを表示します。左の数字がServerIDです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2687626/154dcd9a-c678-22d3-95e2-25ba0de6d27c.png)
~~~
dengon servers
~~~
### 5. チャンネルリストを表示
dengon channelでサーバー内のテキストチャンネルを表示します。左の数字がChannelIDです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2687626/55886bf5-099b-0f34-d459-84db88e91dc5.png)
* **ServerID**
-idで表示するサーバーのServerIDを指定します。
    ~~~
    dengon channel -id 0
    ~~~