OmniAICreator/Qiita-1.07M huggingface dataset:
2023/8/14主にITとかセキュリティの記事

ネット不正送金被害の最悪、上半期30億円　警察庁まとめ(8/12)
https://www.nikkei.com/article/DGXZQOUF111K30R10C23A8000000/

ChatGPTをスピード導入したスタディストに学ぶ生成AI業務利用のポイント(8/9)
https://kn.itmedia.co.jp/kn/articles/2308/02/news005.html

カナダの騎馬警察、仮想通貨やNFTの押収・保管ツールで入札(8/12)
https://coinpost.jp/?p=477015

インド太平洋でサイバー情報網　攻撃兆候を共有
政府、島しょ国の能力支援(8/12)
https://www.nikkei.com/article/DGXZQOUA208I50Q3A720C2000000/

中国軍のハッカーが日本を攻撃、システムに侵入されていた　対応遅れに米は再三警告、空疎なプライド捨てて連携強化を(8/12)
https://www.zakzak.co.jp/article/20230812-CPHHT7MAS5LMXCCKBHGW5KFLRQ/

AIが架空の女性やセクシーな写真、ストーリーや音声まで作成する「ハイパーポルノ」(8/12)
https://gigazine.net/news/20230812-mindy-hyperporn/

北がサイバー攻撃で暗号資産窃取、昨年２４５０億円…安保理パネル「技術がさらに洗練」(8/12)
https://www.yomiuri.co.jp/world/20230812-OYT1T50032/

中国が「日本の最高機密網」侵入の衝撃…3年前の事件が今報じられた裏に“米国の思惑”？(8/12)
https://news.yahoo.co.jp/articles/55e6f6f134f2f6a1ec3f119d7f21982108bae37a?source=rss

サイバー攻撃で調達　北朝鮮、過去最高の2400億円
国連報告案　昨年、核・ミサイル開発継続(8/12)
https://www.nikkei.com/article/DGKKZO73556170S3A810C2NNE000/

病院を狙うランサムウェアの脅威が増加、29施設につき1施設が被害(8/12)
https://news.mynavi.jp/techplus/article/20230812-2746096/

バイナンス（Binance）がウォレットプロトコルの脆弱性を認める(8/11)
https://nextmoney.jp/?p=60304

2018年にリリースされたmacOSのライト/ダークモードを簡単に切り替えるられる「NightOwl」アプリがボットネット化され、Appleが開発者署名を取り消し。(8/12)
https://applech2.com/archives/20230812-apple-revoke-nightowl.html
HTML Living Standardの魅力を探る！初心者から上級者まで必見


HTMLの世界は絶えず進化しています。この記事では、HTML Living Standardの成り立ちからその特徴、具体的な使用例までを解説します。新しい要素やタグの使い方を知りたい方は必見です！

## 目次
- [はじめに](#はじめに)
- [HTML Living Standardとは？](#html-living-standardとは)
- [成り立ち](#成り立ち)
- [特徴的な要素](#特徴的な要素)
- [常に進化する仕様](#常に進化する仕様)
- [実例](#実例)
- [まとめ](#まとめ)

## はじめに
HTMLはウェブページの基盤となる言語ですが、その仕様は絶えず変わっています。HTML Living Standardとは、これらの最新の仕様をまとめたものです。

## HTML Living Standardとは？
HTML Living Standardは、HTMLの最新の仕様を表すものです。これは「生きている」ものとして、新しい技術やブラウザの実装に応じてアップデートされます。

## 成り立ち
2004年頃、ブラウザの大手ベンダーがHTMLの進化の停滞を感じ、新しいグループ、WHATWGを設立。これが後の「HTML5」へと発展し、さらに「HTML Living Standard」として継続的に更新されるようになりました。

## 特徴的な要素
HTML Living Standardには多くの新しい要素や属性が導入されています。

- **セマンティック要素**:
これらは、ウェブページの内容をより意味的に表現するためのものです。
```html
<article>
    <header>
        <h2>Title of the article</h2>
    </header>
    <p>Content of the article...</p>
    <footer>
        <p>Author: John Doe</p>
    </footer>
</article>
```

- **マルチメディアサポート**:
ネイティブなマルチメディアサポートが強化されました。
```html
<video controls>
  <source src="movie.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>
```

## 常に進化する仕様
HTML Living Standardは固定されたバージョンではなく、常に進化し続ける仕様です。これにより、新しい技術やブラウザの実装に迅速に対応することができます。

## 実例
HTML Living Standardには多くの新しい要素や属性があります。以下はその一例です。

```html
<!-- セマンティック要素の例 -->
<article>
    <header>
        <h2>Title of the article</h2>
    </header>
    <p>Content of the article...</p>
    <footer>
        <p>Author: John Doe</p>
    </footer>
</article>

<!-- ビデオ要素の例 -->
<video controls>
  <source src="movie.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>
```

## まとめ
HTML Living Standardは、ウェブの未来を形成する仕様です。新しい要素や属性を学ぶことで、より洗練されたウェブページの制作が可能になります。
FBXファイルに含まれた情報を見る

# 概要
FBXは、Autodeskが開発した3Dデータのファイル形式です。FBXファイルには、3Dモデル、アニメーション、テクスチャなど、3Dアセットに関連するデータが保存されます。FBXファイルをそのまま見ようとしてもASCiiでの情報しか見れません。
本項では、出力したファイルの情報をテキストのみで確認する方法を記述しています。GithubのプロジェクトF3Dというプログラムを利用しています。

# 手順
1. [F3DのGithubレポジトリ](https://github.com/f3d-app/f3d/tree/master)からリリースファイルもしくは、OSに合わせてコマンドでダウンロード
1. コマンドでファイル情報を返す
`F3D --no-render scene.fbx` 
1. ファイル情報をテキストファイルに保存
`F3D --no-render scene.fbx >> scene.txt`
ソフトバンク光のBBユニットとTPLinkのルータを使ってSynologyNASでVPN構築した

### 初めに
タイトル通りです。
ネットワーク無知な人間がvpn構築で詰まった部分を、
メモ書き程度ですが、備忘録として残したいと思います。
また。用語の意味を理解しきれていない箇所があるかもしれません。
コメント等で教えていただけると助かります。

### 現状
現在我が家では以下の構成のネットワークになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230793/e72ad66a-1e44-6a8e-ea40-a2ef3f8335c2.png)

このうち光BBユニットとTPLinkが両方ともルータ機能を持っており、二重ルータになってしまっています。
普通なら光BBユニットをAPモードで利用することで、二重ルータを解決できます。


### 光BBユニットについて
さっきの図を見たら「光BBユニット抜いたらいいんじゃね？」とか「光BBユニットをAPモードで利用したらいいんじゃない？」と考えると思います。実際自分もそう考えました。
しかし、光BBユニットが少々特殊らしく、こいつがipv6とipv4をいい感じに使うことで速度改善に貢献してくれているらしいです。
このBBユニット、ソフトバンク光契約後に「速度改善のためには...」と追加費用を取られました
~~まるでヤ〇ザですね~~

ということで、こいつを抜いてネットワークを構築するという選択肢をできるだけ回避する必要が出てきました。
また、APモードを利用するとPPPoEでTPLinkと通信することになります。PPPoEがipv4しか対応していないので、これではせっかくの追加費用が無駄になります。
ここで一日ぐらい詰まりました。

### DMZ設定について
いろいろ調べているとDMZ設定をして、光BBユニットに来た通信を全部送ればよいという記事を見つけました(すみません記事のURLがどっか行きました)
DMZは、サーバ等立てる際にローカルのネットワークに直接外部からアクセスできないような部分だと認識しています。この前受けた基本情報の試験対策で勉強しておいたので何となく理解できました。詳しくはググってください。
この方法だと、光BBユニットのipv6を生かしながら、TPLink側でネットワークを管理できます。
つまり、外部からの通信を、光BBユニットのDMZ設定で特定のアドレスに転送し、そのアドレスをTPLink側から受け取ります。完璧です。

### 設定手順
方法がわかれば後は設定していくだけです。
光BBユニットの設定画面から、ルーター機能の設定→DMZ設定画面を開きます。
初期ユーザ名と初期パスワードは両方とも　user　です。ログインしたら早めに変更しちゃいましょう。
DMZ設定を有効にし、適当なipアドレスを指定します。私はとりあえず192.168.3.200と設定しました。

設定出来たら、TPLinkの設定画面に移動し、インターネットの接続方法を静的ipに変更します。
その後、以下の情報を入力します。

| インターネット接続タイプ | 静的ip |
| :--- | :--- | 
| IPアドレス | 先ほど光BBユニット側でDMZ設定したipアドレスを入力 |
| サブネットマス | 初期値のまま |
|デフォルトゲートウェイ|	192.168.3.1　←光BBユニットの初期ipアドレス|
|プライマリ DNS|192.168.3.1　←光BBユニットの初期ipアドレス|
|セカンダリ DNS	|8.8.8.8に設定してた。設定しなくても多分大丈夫|
MTU サイズ|初期値のまま

上記の値を入力後、念のためルータを再起動します。
インターネットが利用できたら成功です。
インターネットが利用できない場合は先ほどの値がどこか間違えています。

### vpn設定
二重ルータ問題が解決できたのでvpnを設定していきます。
今回、TPLinkのルータにもvpnの機能がありますが、こちらだとなぜか、pcで利用できなかったため、synologyNASのvpnサーバ機能を利用していきます。
TPLink側で、vpnで利用するポートを開放します。
その後、NAS側で、DDNS設定とvpn設定をします。今回自分はopenvpnを設定しました。
また、DDNSが、二重ルータなので、うまく機能しないと思っていたのですが、
設定時の外部アドレスを”自動”にしたところ、あっさりグローバルipを認識してくれました。安心してください。vpnの設定時は以下のサイトを参考にしました。

https://nw.myds.me/synology/setup-vpn-server/

また、synologyのopenvpnだとなぜか、iosから接続した際、エラーとなってしまいます。
その場合はこちらのサイトを参考にしました。

https://qiita.com/nonamePM/items/90138b39f809b047d624

### おわりに
苦戦したけどvpn構築できたのでnasが外部からいじれるようになりました。めでたしめでたし
あとソフトバンク光の人が見てたら、光BBユニットで後から追い課金制度作るのやめてください。
[Spigot / Paper] アイテムの説明文を削除する

# ItemMeta が持っている Lore の情報をすべて捨てる
(ほぼ自分用メモ)

https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/inventory/meta/ItemMeta.html#setLore()

↑ に書いてある通り、`ItemMeta#setLore` に `null` を渡すと中身を全部削除してくれるらしい。
ICLR2023の枝刈り論文 (3)

# 概要

この記事では、[ICLR2023](https://iclr.cc/)の枝刈り論文を紹介します。[^1]
[その1](https://qiita.com/kyad/items/d7dd45af7f201c065ff3) [その2](https://qiita.com/kyad/items/247554d852f92a1c6ea0)

[^1]: 画像や数式は論文から引用しています。


# Learning to Jointly Share and Prune Weights for Grounding Based Vision and Language Models

https://openreview.net/forum?id=D7srTrGhAs

- 概要：Vision Language Modelの枝刈り。
- 研究機関：Samsung
- 新規性：VisionとLanguageが重み共有されるように刈りながら学習する。
- キモ：TransformerのBackboneの重み共有をする。さらに互いのBackboneの枝刈りもする。
- 評価：Vision Languageタスクで評価した。


# Over-parameterized Model Optimization with Polyak-Lojasiewicz Condition

https://openreview.net/forum?id=aBIpZvMdS56

- 概要：枝刈りのための正規化
- 新規性：Polyak-Lojasiewicz(PL)定数に正則化をかけることで刈りやすくなる
- キモ：目的関数にリプシッツ定数とLT定数の比の正則化項を追加して最適化する。
- 評価：BERT, VGG-16で実験した。


# A General Framework For Proving The Equivariant Strong Lottery Ticket Hypothesis

https://openreview.net/forum?id=vVJZtlZB9D

- 概要：[強い当たりくじ仮説](https://qiita.com/kyad/items/1f5520a7cc268e979893)の一般化
- 新規性：強い当たりくじ仮説を、群$G$の動きを保存する関数であるDNNへ拡張した。
- キモ：主定理 Theorem 1
- 評価：いくつかの具体的な関数で確認した。


# How I Learned to Stop Worrying and Love Retraining

https://openreview.net/forum?id=_nF5imFKQI

- 概要：枝刈りと学習を繰り返すときのLRの決め方
- 新規性：学習バジェット(EPOCH数)一定ではLRは線形に変化させるのが良いと主張した。
- キモ：Warmup後線形にLRを落とすLLRで、さらに初期LRを割合dで割り引くALLRが一番良い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/2c374241-2e4c-4a7b-608f-417ca513b798.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/0859aa18-f2b6-bb80-8e20-f26b70e12494.png)
- 評価：ResNet, CIFARで実験した。


# OTOv2: Automatic, Generic, User-Friendly

https://openreview.net/forum?id=7ynoX1ojPMt

- 概要：OTOv2. 一般のDNNで小さいモデルを作りながらone-shotで高精度・高速なDNNが得られる。
- 研究機関：Microsoft
- 新規性：[OTOv1](https://proceedings.neurips.cc/paper/2021/hash/a376033f78e144f494bfc743c0be3330-Abstract.html)のZIGを求めるのをOTOv2で自動化した。
- キモ：隠れ層で量子化してロス計算して最適化する。
- 評価：VGG16, ResNet50で実験した。
Macbook Airの内蔵SSDをESXiデータストアにする方法

# 背景
新しくM2のMacbook Airを購入したことで最後のintelモデルであった2019年版のMacbook Airが使わなくなったため，ESXi8.0をインストールしてVMを立てて遊ぶことにしました．その際にMacbook Airの内蔵SSDがデータストアとして登録できなかったので，解決した内容を残しておきます．

# ※注意
Mac OSを介さないでESXiを実行することは，公式ではサポートされていないので自己責任でお願いします．

# 本題
以下のようにUSBメモリしか認識していない
```
[root@localhost:~] esxcli storage core adapter list
HBA Name  Driver  Link State  UID          Capabilities  Description
--------  ------  ----------  -----------  ------------  -----------
vmhba32   vmkusb  link-n/a    usb.vmhba32                () USB
```

どうやら公式のESXiのisoだとMacbook AirのNVMeベースのSSDを使うのに必要なドライバが含まれていないらしい．
そのため以下のcommunityで開発されたvibファイルをダウンロードする必要がある．

https://flings.vmware.com/community-nvme-driver-for-esxi

上記は公式ではなくコミュニティが開発したESXiネイティブドライバです．上記をダウンロードし，ESXiにインストールすることでMacbook Airの内蔵SSDが認識されるようになる．
zipファイルがダウンロードされるので解凍してvibファイルをscpで送信する．
```
scp ./VMW_bootbank_nvme-community_1.0.1.0-3vmw.700.1.0.15843807.vib root@xxx:/vib_file/
(root@xxx) Password:
VMW_bootbank_nvme-community_1.0.1.0-3vmw.700.1.0.15843807.vib
```
上記をesxcliを使ってインストールする．
```
[root@localhost:~] cd vib_file/
[root@localhost:/vib_file] ls
[root@localhost:/vib_file] pwd
/vib_file
[root@localhost:/vib_file] esxcli software vib install -v VMW_bootbank_nvme-community_1.0.1.0-3vmw.700.1.0.15843807.vib
 [VibDownloadError]
 Not a valid absolute path: VMW_bootbank_nvme-community_1.0.1.0-3vmw.700.1.0.15843807.vib
        url = VMW_bootbank_nvme-community_1.0.1.0-3vmw.700.1.0.15843807.vib
 Please refer to the log file for more details.
[root@localhost:/vib_file] cd
[root@localhost:~] esxcli software vib install -v /vib_file/VMW_bootbank_nvme-community_1.0.1.0-3vmw.700.1.0.15843807.vib
Installation Result
   Message: The update completed successfully, but the system needs to be rebooted for the changes to be effective.
   VIBs Installed: VMW_bootbank_nvme-community_1.0.1.0-3vmw.700.1.0.15843807
   VIBs Removed:
   VIBs Skipped:
   Reboot Required: true
   DPU Results:
```
`-v`で指定したpathは絶対パスで指定する必要があるので注意．
`Reboot Required`が`true`なので一度rebootします．
reboot後にもう一度確認する．
```
[root@localhost:~] esxcli storage core adapter list
HBA Name  Driver          Link State  UID           Capabilities  Description
--------  --------------  ----------  ------------  ------------  -----------
vmhba0    nvme_community  link-n/a    pscsi.vmhba0                (0000:74:00.0) Apple Inc. ANS2 NVMe Controller
vmhba32   vmkusb          link-n/a    usb.vmhba32                 () USB
```
Macbook Airの内蔵SSDを認識している．
無事データストアとしても登録できた．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/61cbdee4-2408-d4c7-c012-637be856d2e2.png)

# 終わりに
今回調べる中で，ESXi communityという存在を初めて知ったので，この辺も深掘りをして記事にしてみようと思います．
php、composerコマンドが実行できない時の対処法

MACの場合

ターミナルを開いて以下コマンドを使用。

phpコマンドが使えない。
---
```
brew install php
```
```
brew --prefix php@7.4]
```

でphp@7.4が格納されている場所を確認
※/opt/homebrew/opt/php@7.4と表示されました。
その場合
zshrcファイルを開いて
```
vim ~/.zshrc
```
iで入力モードに
```
i
```
```
export PATH="/opt/homebrew/opt/php@7.4/bin:$PATH"
export PATH="/opt/homebrew/opt/php@7.4/sbin:$PATH"
```
と入力しescキーを押し、：wqを打ってEnter
```
source ~/.zshrc
```
で入力したPATHを反映

phpコマンドが使えるようになる。

composerコマンドが使えない。
---
composer.phar格納する場所を作成する。
```
sudo mkdir /usr/local/bin
```
パスワードを入力。
composer.pharをcomposerコマンドで使えるように作った格納場所に移動させる。
```
sudo mv composer.phar /usr/local/bin/composer
```
移動が完了したのでアクセス権を変更「a+x」
```
chmod a+x /usr/local/bin/composer
```
composerコマンドで移動できているか確認する。
オプショナルな配列に要素を追加する様々な方法(Swift)

## はじめに

`components.queryItems` は `[URLQueryItem]?` 型の配列です。

```swift
var queryItems: [URLQueryItem]? { get set }
```

https://developer.apple.com/documentation/foundation/urlcomponents/1779966-queryitems

配列の要素は非オプショナル型ですが、配列自体がオプショナル型です。
このような配列に要素を追加する方法を紹介します。

## 環境

- OS：macOS Ventura 13.4.1
- Swift：5.8

## オプショナルな配列に要素を追加する様々な方法

オプショナルな配列に要素を追加する様々な方法を紹介します。

前提として、配列が `nil` でない場合は先頭に元の要素を残すようにします。

### デフォルト値を使って先頭に元の要素を残す

自分が考え得る中で最も短いコードです。

```swift
components.queryItems = (components.queryItems ?? []) + [
    .init(name: "zipcode", value: zipCode),
]
```

もう少しスマートに書ける気がしますが、今のところ一番好みです。

### 配列を一時変数に格納する

配列を一時変数に格納してアンラップし、構築して変数ごと代入します。

```swift
var queryItems = components.queryItems ?? []
queryItems += [
    .init(name: "zipcode", value: zipCode),
]
components.queryItems = queryItems
```

最初の方法より少し長いですが、こちらのほうがわかりやすいという人も多いと思います。

Xcodeのように型推論された型がinlay hintで表示されない場合、配列の型を明記するとわかりやすいです。

```swift
var queryItems: [URLQueryItem] = components.queryItems ?? []
queryItems += [
    .init(name: "zipcode", value: zipCode),
]
components.queryItems = queryItems
```

### 関数を使う

配列を2次元にしてすべての要素を突っ込み、最後に `flatMap()` で1次元にします。

```swift
components.queryItems = [
    (components.queryItems ?? []),
    [
        .init(name: "zipcode", value: zipCode),
    ],
]
    .flatMap { $0 }
```

上記だと最初の方法の下位互換っぽいので、 オプショナルな配列を `compactMap()` で潰すとより関数型チックに書けます。

```swift
components.queryItems = [
    components.queryItems,
    [
        .init(name: "zipcode", value: zipCode),
    ],
]
    .compactMap { $0 }
    .flatMap { $0 }
```

関数型プログラミングが好きな人にはよさそうです。

## おわりに

オプショナルな配列に要素を追加する方法はたくさんあることがわかりました。
ほかにもありましたら、コメントなどで教えていただけると嬉しいです :relaxed:

## 参考リンク

- https://twitter.com/the_uhooi/status/1690534191983992832
Goの標準ライブラリだけでJWTをデコードしてみたら意外と簡単だったwww

# はじめに
jwtをデコードしユーザー情報を取得する処理を書く機会があったのですが、Goではサードパーティ製のライブラリを使わずとも意外と簡単に実装できたので、コピペするだけで簡単に使用できるサンプルをここで共有したいと思います。
# サンプル
```go
func decode(token string) ([]byte, error) {
	// jwtはピリオド区切りで3つのパーツに分かれている
	// [0]はヘッダー, [1]はペイロード, [2]はシグネチャー
	// 今回必要なユーザー情報などはペイロードに含まれているため[1]を取得している
	splitToken := strings.Split(token, ".")
	if len(splitToken) != 3 {
		panic(err)
	}
	payload := splitToken[1]

	// base64は文字数が4の倍数でないとデコードできないため末尾に"="を挿入することでパディングする
	paddingLength := ((4 - len(payload)%4) % 4)
	padding := strings.Repeat("=", paddingLength)
	paddedPayload := strings.Join([]string{payload, padding}, "")

	// デコード
	decodedPayload, err := base64.StdEncoding.DecodeString(paddedPayload)
	if err != nil {
		panic(err)
	}

	return decodedPayload, nil
}
```
# 使用例
以下の内容はginのミドルウェアとして使用する場合の例
```go
type sampleClaim struct {
	ID   string
	name string
	role string
}

func DecodeJwt() gin.HandlerFunc {
	return func(c *gin.Context) {
        // リクエストのヘッダーから認証に関する情報を取得
        // 内容が空白であればエラーを返す
		auth := strings.TrimSpace(c.Request.Header.Get("Authorization"))
		if len(auth) <= 0 {
			// 適当なエラーレスポンスをここに記述
			// 長くなりそうなので省略
		}

        // 先ほど取得した内容からjwtを抜き出し取得する
		token := auth[len("Bearer "):]
		decodedToken, err := decode(token)
		if err != nil {
			// 適当なエラーレスポンスをここに記述
			// 長くなりそうなので省略
		}

        // デコードしたtoken(json)を構造体として定義
		var claims sampleClaim
		if err := json.Unmarshal(decodedToken, &claims); err != nil {
			// 適当なエラーレスポンスをここに記述
			// 長くなりそうなので省略
		}

        // 構造体をcontextに保持させる
		c.Set("claims", claims)
		c.Next()
	}
}

func decode(token string) ([]byte, error) {
	// 省略
	return []byte{}, nil
}

```

# 終わりに
今回はjwtが適切かどうかを検証する処理は記述しませんでしたが、それも標準ライブラリのみで簡単に記述できそうでした。気が向いたらそちらも記事にしようかと思います。
お恥ずかしながらjwtの仕組みを知らずに今まで仕事してきたので、個人的にはとても学びのある経験ができました。

もしコードに誤りや非効率な部分がありましたら遠慮なくコメントしていただけると幸いです。
VisionProのエミュレーターのインストール方法

# VisionProのエミュレーターを起動する
## Xcodeベータ版のダウンロードと起動
Macがあれば誰でもVisionProのエミュレーターを触ることができます。
なお、快適な動作には、M2以上、32GB以上が求められる可能性が高いです。一応この検証はM1の16GBで行っていますが、ギリギリ動く感じです。（Intelチップは最適化がされていないのかハイスペックな機種でも動作は難しいです）

[シュミレーターはこちらから](https://developer.apple.com/download/all/?q=xcode%2015)
Xcode 15 beta をダウンロードしてください。
**MacのOSが最新じゃないとベータ版のXocdeは起動できないので注意してください。**

起動すると、どのOSでの開発をしますか？みたいな画面が表示されるので、VisionProを選択してください。

## エミュレーターの起動
Xcodeが起動したら「Create New Project」を選択
<img width="780" alt="image.png (80.1 kB)" src="https://img.esa.io/uploads/production/attachments/19973/2023/08/14/148413/9b98dbf7-0958-4b50-be6d-93ab8b441f9b.png">

1. 上のメニューから**VisionOS**を選択
1. **APP**を選択
1. Nextを選択
<img width="1496" alt="image.png (145.5 kB)" src="https://img.esa.io/uploads/production/attachments/19973/2023/08/14/148413/12d44986-ac4a-49d2-a5c1-85031635e39b.png">

適当なプロジェクト名を入力
Organaization Identiferについての説明は省きますが、一意になる必要があります。
"example.github.com"の場合、"com.github.example"のように、ドメインを逆さまに並べたものが推奨されています。
githubのアカウント名は一意なので、個人の使用でこだわりがなければ、githubでいいと思います。
<img width="1496" alt="image.png (153.7 kB)" src="https://img.esa.io/uploads/production/attachments/19973/2023/08/14/148413/5a42756c-b1f5-40fc-bac2-949e9d678d40.png">

適当なディレクトリを選択して、「creat」を押します。
<img width="1496" alt="image.png (170.2 kB)" src="https://img.esa.io/uploads/production/attachments/19973/2023/08/14/148413/327bfc82-f2c8-46b2-b12d-07ed473fb81a.png">

Xcodeが立ち上がったら、左上の三角ボタンからエミュレーターを起動します。
<img width="1496" alt="image.png (500.5 kB)" src="https://img.esa.io/uploads/production/attachments/19973/2023/08/14/148413/dcb4c187-c91e-4180-9684-9d85f247142e.png">

# 終わりに
VisionProのエミュレーターの起動方法について解説しました。基本的なVisionProの基本操作と、設定アプリの項目についての解説は、[こちらの記事（Apple Vision Pro の基本操作と基本設定まとめ）](https://qiita.com/kanakanho/items/bc2eb6c87c3644d630c0)にてまとめているので、興味のある方はどうぞ。
実機を買うのは値段的に厳しいものがありますが、エミュレーターを触るだけなら簡単にできていいですね。VisionProはswiftUIがそのまま使えるため、Swiftのエンジニアの多い日本では高い需要が生まれそうですね。
【TailwindCSS】スクロールバーを非表示にする方法

## カスタムクラスを作成する
以下の内容でカスタムクラスを作成します。

```css
.hidden-scrollbar{
  overflow: scroll;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.hidden-scrollbar::-webkit-scrollbar {
  display:none;
}

```

## 要素に適用する

適用したい要素に上記のクラスを記述します。
Prismaのマイグレーションコマンド実行時のM1 Mac x86アーキテクチャエラーとその対処法

## 事象

M1 Mac上で新しいPrismaプロジェクトをセットアップしようとした際、Prismaのマイグレーションコマンドを実行したところ、以下のエラーが発生しました。

```
$ npx prisma migrate dev
assertion failed [block != nullptr]: BasicBlock requested for unrecognized address
(BuilderBase.h:554 block_for_offset)
zsh: trace trap  npx prisma migrate dev
```

## 原因

このエラーの主な原因は、M1 Mac上でx86アーキテクチャのNode.jsが動作していることに関連しています。M1 MacはARM64アーキテクチャを採用しているため、x86アーキテクチャ用のソフトウェアはRosetta 2を通じて変換されて実行されます。Rosetta 2は、Apple Siliconでのx86アーキテクチャのソフトウェアの互換性を提供する変換レイヤーです。しかし、一部のソフトウェアやツールはRosetta 2を使用しても正常に動作しない場合があります。そのため、M1チップを搭載したMacで最適なパフォーマンスを得るためには、ARM64アーキテクチャに対応したソフトウェアをインストールすることが推奨されています。

## 対処法

1.  Node.jsの再インストール
    1. 現在のNode.jsのアンインストール

        ```
        which node # Node.jsのインストールパスを確認
        sudo rm -rf [上記のコマンドの出力パス]
    
        brew uninstall node # brewでインストールした場合
        ```
    
    2. nvmのインストール

        ```
        curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
        ```
        最新のインストールスクリプトはnvmの公式GitHubページで確認してください。
        https://github.com/nvm-sh/nvm

        インストール後、ターミナルを再起動または以下のコマンドを実行してnvmを有効にします。

        ```
        export NVM_DIR="$HOME/.nvm"
        [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
        ```

    3. ARM64アーキテクチャ用のNode.jsのインストール

        ```
        nvm install node # 最新バージョンのNode.jsをインストール
        nvm use node
        nvm alias default node
        ```

2. VSCodeの設定変更
    1. VSCodeを開く
    2. 左下の歯車アイコンをクリックして「設定」を開く
    3. 右上の{}アイコンをクリックして、JSONモードでの設定を開く 
    4. 以下の設定を追加または変更する

        ```settings.json
            "terminal.integrated.profiles.osx": {
                "bash": {
                    "path": "arch",
                    "args": ["-arm64", "bash", "-l"],
                    "overrideName": true
                }
            },
            "terminal.integrated.defaultProfile.osx": "bash"
        ```

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
Qiita vs Zenn vs はてなブログ vs note

Qiita vs Zenn vs はてなブログ vs note で比較してみました。

## 人気度比較

**比較表**

| 項目                     | Qiita       | Zenn        | はてなブログ | note                                       |
| ------------------------ | ----------- | ----------- | ------------ | ------------------------------------------ |
| ユーザ数                 | 100万人[1]  | 不明        | 不明         | >500万人[3]                                |
| 投稿数                   | 87万件[1]   | 不明        | 不明         | 不明                                       |
| 検索数(Google Trend)     | 2位[2]      | 3位[2]      | 1位[2]       | 計測不能(noteという単語が一般的過ぎるため) |
| 国内ランク(Similarweb)   | 345位[4]    | 602位[5]    | 73位[6]      | 33位                                       |
| 月間訪問数(Similarweb)   | 20.4M件[4]  | 10.2M件[5]  | 73.3M件[6]   | 130.2M件[7]                                |
| 平均滞在時間(Similarweb) | 00:04:24[4] | 00:03:45[5] | 00:01:50[6]  | 00:02:13[7]                                |
| 月間PV                   | 4000万件[1] | 不明        | 不明         | 不明                                       |

**参考文献**

1. <https://media-radar.jp/detail24638.html> 2023/08/07
2. <https://trends.google.co.jp/trends/explore?date=today%205-y&geo=JP&q=%2Fg%2F11f16fnx7b,%2Fg%2F11s9scs617,%2Fg%2F11btyfzm6z&hl=ja> 2023/08/13
3. <https://prtimes.jp/main/html/rd/p/000000102.000017890.html> 2022/04/21
4. <https://www.similarweb.com/website/qiita.com/#overview> 2023/08/13
5. <https://www.similarweb.com/website/zenn.dev/#overview> 2023/08/13
6. <https://www.similarweb.com/website/hatenablog.com/#overview> 2023/08/13
7. <https://www.similarweb.com/website/note.com/#overview> 2023/08/13

QiitaやZennは技術者コミュニティという特性上、ユーザ数や訪問数が少ないが、ページの平均滞在時間が長い傾向にあります。

一方で、飛ぶ鳥を落とす勢いで成長しているのがnoteです。

"老舗"のはてなブログを差し置いて、国内サイトランクは堂々の33位。

Google Trendの分析こそできませんでしたが、はてなブログを超えているのではないでしょうか。
月間訪問数は130.2M件と他のサイトと比べると文字どおり"桁違い"です。

しかしながら、平均滞在時間は2分13秒と短め。
装飾やアフィリエイトも少なく、ページがすっきりしているのでササッと読みやすい反面、さっさと出て行ってしまうユーザが多いのかもしれません。

## 機能比較

**比較表**

| 項目                      | Qiita | Zenn | はてなブログ | note |
| ------------------------- | ----- | ---- | ------------ | ---- |
| Markdown                  | 🆗     | 🆗    | 🆗            | ⛔    |
| リンクカード              | 🆗     | ❓    | ❓            | 🆗    |
| 表                        | 🆗     | 🆗    | 🆗            | ⛔    |
| 収益化:アフィリエイト連携 | ⛔     | ⛔    | 🆗            | ⛔    |
| 収益化:記事販売           | ⛔     | 🆗    | ⛔            | 🆗    |


機能面でみると、じつはnoteは表を描画する機能がなかったり、アフィリエイトが禁止されていたりと、いろいろと制約が多いことがわかります。

Zenn、QiitaはMarkdownをネイティブサポートしており、技術者にとっては書きやすいですね。
そして、はてなブログは非技術者系のブログにしては珍しくMarkdownでの記事作成機能をサポートしています。さすが老舗。。。
なるべくダウンタイムなくコンテナを差し替える

頻繁にコンテナを差し替える必要があったのですが、コンテナイメージのダウンロード時間もそれなりにかかりますし、処理の手順を間違えてもダウンタイムが長くなってしまうので良い方法を考えていました。

よって以下の shell script を作成しました。

```shell
echo -------- pre --------
docker pull ${あなたのコンテナを指定}:latest
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

echo -------- run --------
docker run -d -p 80:3000 ${あなたのコンテナを指定}:latest

echo -------- clean --------
docker image prune -a -f
```

事前にコンテナイメージをダウンロードしておき、そのまま落とした直後のコンテナイメージを指定して起動、使われなくなったイメージは prune で削除。これでとても楽にコンテナが差し替え出来るようになりました。

このスクリプトを活用してコンテナイメージに最新版が登場したら自動的に差し替えて、完了時に slack へ更新通知を送るスクリプトを用意してみましょう。

```shell
#!/bin/bash

# 注意事項
# - 本スクリプトは対象のコンテナが1つである時に利用すること
# - docker ps -a で一斉にコンテナ停止、削除を行なう為です
# - 対象のコンテナが複数ある場合は、コンテナ名等を指定して個別に処理するロジックに変更して下さい

# 変数
last_image_hash_file="last_image_hash.txt"
remote_image_url="${your-container-image}"
slack_webhook_url="https://hooks.slack.com/services/***********"

# 前回のイメージハッシュを読み込む
if [ -f "$last_image_hash_file" ]; then
    last_image_hash=$(cat "$last_image_hash_file")
else
    last_image_hash=""
fi

# リモートイメージのハッシュを取得
old_container_id=$(docker ps -q)
remote_image_hash=$(docker pull $remote_image_url | awk '/Digest:/ {print $2}')

# エラーハンドリング関数
handle_error() {
    echo "エラーが発生しました。"
    curl -X POST -H 'Content-type: application/json' -d "{\"text\": \"エラーが発生しています。古いコンテナイメージで起動します。\"}" $slack_webhook_url

    if [ -n "$old_container_id" ]; then
        echo "古いコンテナを再起動します。"
        docker start "$old_container_id"
    else
        echo "古いコンテナが存在しないため、スクリプトを終了します。"
        exit 1
    fi
}

# エラー時の処理を登録
trap 'handle_error' ERR

# 前回のハッシュと比較
if [ "$remote_image_hash" != "$last_image_hash" ]; then

    # コンテナ差し替え
    echo "更新を検知しました。コンテナを差し替えます。"
    docker stop $(docker ps -a -q)
    docker rm $(docker ps -a -q)

    # コンテナの起動を試みる
    if ! docker run -d -p 3000:3000 $remote_image_url; then
        # エラー発生時の処理をトリガー
        handle_error
    fi

    # 後処理
    docker image prune -a -f

    if [ -n "$slack_webhook_url" ]; then
        messages=("[ 更新通知 ]" "" "コンテナイメージ $remote_image_url を更新しました。" "最新の Hash は $remote_image_hash です")
        joined_messages=$(printf "%s\n" "${messages[@]}")
        curl -X POST -H 'Content-type: application/json' -d "{\"text\": \"$joined_messages\"}" $slack_webhook_url
    fi
    
    # 新しいハッシュをファイルに保存
    echo "リモートイメージが更新されました！"
    echo "$remote_image_hash" > "$last_image_hash_file"
else
    echo "リモートイメージは更新されていません。"
fi

```

上記の通り作成したら cron を設定しましょう。例えば以下の通りです。

```shell
chmod 700 /path/to/your/script.sh
crontab -e
```

```cron
*/5 * * * * /path/to/your/script.sh
```
【Unity】アセンブリ参照定義ファイルを削除した後のごみ取り

# 発生したエラー
アセンブリ参照定義ファイルを作成していろいろ名前空間を分けていたのですが、最終的にすべて同じ名前空間に配置することに。
不要になったアセンブリ参照定義ファイルを削除して、AssetBundleのビルドをすると以下のエラーが…
```
TypeDB: Assembly index for '[プロジェクトフォルダ]/Library/ScriptAssemblies/FireBaseAssembly.dll' was not found.
```

# 解決方法
何かの定義ファイルで参照先情報が残っていしまっていた様子。
以下フォルダのファイルで、エラーに出ているdill（FireBaseAssembly.dllのような部分）を丸ごと削除で対応しました

```
[プロジェクトフォルダ]\Library\BuildPlayerData\Editor\TypeDb-All.json
```
Ubuntuが入ったノートPCをSSHできるようにした

Linux触ってる人と会話してると「SSHすれば？」「SSHはいいぞ」とめっちゃ言われるのでUbuntuが入ったノートPCをメインノートPCでSSHできるようにした。

# SSHって？
SSHとは、Secure Shell(セキュアシェル)の略語でリモートコンピュータと通信するためのプロトコルである。認証部分も含めてインターネット上の通信も暗号化されるため、安全に通信することができる

つまり、他のコンピュータやサーバにネットワーク経由で安全に遠隔操作することができる仕組みということ

# 実際にやってみた
まず、**Ubuntuが入ってるノートPC**から作業を始めます。

前提条件として
* Vimがインストール済み
* ファイアウォールが設定済み
* メインノートPCにTera Termがインストール済み

があります

# １．SSHサーバーのインストール
使用するSSHサーバーのインストールを行います。この操作には、管理者権限が必要なため、rootアカウントか通常ユーザーをsudoグループに追加してください


~~~Linux:openssh-serverパッケージのインストール
$ sudo apt install openssh-server
~~~

~~~Linux:起動状態の確認
$ sudo systemctl status ssh
~~~
:::note info
sudo…？
→他のユーザ権限でコマンドを実行するときに使うコマンド(主にroot権限を使うときに使われるらしい)
:::

:::note info
apt…？
→Linuxのパッケージ管理システム(Debian系で標準的に使われているらしい)
:::
# ２．SSHの設定変更
インストールしたてのSSHは、セキュリティが甘いです。そこでSSHの設定ファイルの内容を変更することでセキュリティを強化します。

## 2.1 まずはバックアップ
~~~Linux:rootユーザーになる
$ sudo su
~~~
~~~Linux:バックアップを作成
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
~~~

## 2.2 設定ファイル(sshd_config)を編集
~~~Linux:設定ファイルに編集モードで入る
# vi /etc/ssh/sshd_config
~~~
~~~Linux:rootユーザーでログイン禁止
#PermitRootLogin prohibit-password
↓
PermitRootLogin no
~~~
~~~Linux:パスワード未設定のユーザーの接続を禁止
PermitEmptyPasswords no
~~~
~~~Linux:ポート番号の変更
Port ****(数字)
~~~
~~~Linux:公開鍵認証を有効
PubkeyAuthentication yes
~~~
~~~Linux:秘密鍵ファイルの設定
Hostkey /etc/ssh/ssh_host_rsa_key
Hostkey /etc/ssh/ssh_host_ecdsa_key
Hostkey /etc/ssh/ssh_host_ed25519_key
~~~
(↑使うやつだけ解除でよかったかも)
~~~Linux:パスワード認証の抑止
PasswordAuthentication no
~~~

設定が完了したらファイルを保存して再起動
~~~
# systemctl restart ssh
~~~

# ３．SSH接続用の鍵を作成

パスワード認証でも可能だが、パスワードを知られると他人も接続できるようになってしまう。なので、今回は公開鍵認証を採用した。

:::note info
公開鍵認証…？
公開鍵と秘密鍵で認証を行う手法。今回の場合だと、公開鍵をサーバー側、秘密鍵をメインノートPCに置き、サーバーにログインするときは、秘密鍵でメインノートPCにて署名を作成してサーバーに送る。送られた署名を公開鍵が検証し、大丈夫なら通すというような感じ
:::

~~~Linux:キーペアの作成
$ ssh-keygen -t ed25519 -m PEM
~~~
キーペアの保存先とパスフレーズの入力を求められるので入力

ed25519は暗号アルゴリズム

作成が終わると$ HOME/user/.sshに秘密鍵と公開鍵が作成される

公開鍵は、ファイル名と権限を変更しておく

~~~
$ cd /home/user/.ssh
$ mv id_ed25519.pub authorized_keys
$ chmod 600 authorized_keys
~~~

600は所有者のみ読み書きＯＫ

# ４．接続してみる

## 4.1 ファイアウォールを通す
ファイアウォールを設定している人は、事前に設定してたポート番号を許可してください

~~~
$ sudo ufw allow ***
~~~

## 4.2 接続

ここからは、メインノートPCの作業も入ります

秘密鍵のid_ed25519ファイルをメインノートPCに移動してください

ちなみに秘密鍵は**絶対に公開しないように**

接続には、Tera Termを使用します

Tera Termを起動すると以下の画面になります

![スクリーンショット 2023-08-12 171245.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445203/01c54262-64ca-c4de-3739-b9a4622a78d4.png)

1\. 接続するノートPCのホストアドレスを入力
2\. 接続するポート番号の入力
3\. 内容を確認してクリック

OKをクリックして正しく接続できるとこうなる

![mosaic_20230812172712.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445203/67ea4a56-3d90-3bfe-0e81-8dee8e64b7b8.png)

1\. Linuxで使ってるユーザ名を入力
2\. 入力したパスフレーズの入力
3\. 秘密鍵ファイルを選択
4\.内容を確認してクリック

これらを入力、選択して正しく接続されると

![mosaic_20230812174054.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445203/81960328-5641-7c2c-a5e1-c8dd9598f9a4.png)

こんな感じになれば接続完了

# 今後の展望
次の休みにこそ、Samba使いたい
RailsプロジェクトでJavaScriptが動作しない問題とその解決方法

## はじめに
今回の記事ではRailsプロジェクトにおいて、JavaScriptが動作しないというエラーが起きた原因と解決方法について書く。

## 実際に起こっている現象
ヘッダーのリンクをクリックしたときにログインしていなければトップページへ遷移するように設定している。遷移後のページではslickによってGIFがスライダー表示される。slickはスライダーを作成するためのJQueryのプラグイン。
slickは下記のようにapplication.jsで設定している。
```javascript
import "@hotwired/turbo-rails"
import $ from "jquery";
window.$ = $;
window.jQuery = $;
import "slick-carousel";

$(document).ready(function(){
  $('.slider-3').slick({
    // Slickのオプション設定
  });
});
```
リンクからトップページにアクセスした時に、slickがうまく作動せずスライだーを表示させることができなかった。しかし、root_pathへのURLを直接入力したり、ページをリロードするとslickが適用されるという現象が起きた。

## 解決方法
- Railsプロジェクトで利用しているTurboというJavaScriptのライブラリによってslickの初期化が行われていなかったことが原因だった。
- TurboはRails7ではデフォルトで有効化されており、ページの遷移を高速化するために、ページ全体の再読み込みを行わずにページの一部を変更できるよう。これによってページの読み込み時に一度だけ実行されるはずのSlickの初期化コードが実行されていなかったことが、問題の原因だった。

- そこで、Turboの`turbo:load`イベントを監視し、このイベントが発火したときにSlickなどのJavaScriptプラグインの初期化を行うことでこの問題を解決することができた。

先ほどのapplication.jsを以下のように修正した。

```javascript
import "@hotwired/turbo-rails"
import $ from "jquery";
window.$ = $;
window.jQuery = $;
import "slick-carousel";

document.addEventListener("turbo:load", function() {
  $('.slider-3').slick({
    // 処理内容
  });
});
```

これにより、"turbo:load"というイベントを監視し、Turboが新しいページのコンテンツを読み込んで表示が完了した時点でイベントが発火し、slickによってスライダーが作成される。

## まとめ
-  Rails7においてターボリンクはデフォルトで有効化されている。フォーム・リンクからのリクエストは全てFetch APIを利用した非同期リクエストになり、HTMLが直接レスポンスされる。その際にページの読み込みはせずbody要素の内容だけが差し替えられる。JavaScriptのコードなしでSPAのような感覚でWebアプリを操作できる。Turboは以下の4種類がある。

1. **Turbo Drive**
   - 通常のページ遷移と異なり、ページ全体の再読み込みを避け、代わりに`<body>`タグ内のコンテンツのみを置き換える。これにより、ページ遷移が高速になる。

2. **Turbo Frames**
   - `<turbo-frame>`タグを使用して、ページの特定の部分だけを更新することができる。JavaScriptを記述せず、ページの特定の部分だけを更新することが可能。

3. **Turbo Streams**
   - ページの複数の部分を同時に動的に更新することができる。

4. **Turbo Native**
   - iOSやAndroidのネイティブアプリケーションにおいて利用される。

- 現在作成しているWebアプリにおいてTurboを利用できそうな部分が多いため、学習しながら実装していきたい。
PowerShellの操作ログを自動取得する

## はじめに
この記事は、PowerShellの操作ログを残せたらなにかと便利だと思い、ログ出力方法を調べてやってみたので、その備忘録として書きました。
記事の内容に間違いや意見などありましたらコメントいただけると幸いです。

## ログ自動取得のためにやること
Powershellには「プロファイル」というログイン時に自動実行されるスクリプトがあります。
UNIX系OSでいうところの `.bash_profile` のようなものですね。
そのプロファイルにログ出力のコードを書くだけで、Powershellにログインすれば自動でログが記録されるようになります。

:::note info
「ローカルグループポリシーエディター」という Windows のツールからログ出力設定を行うというアプローチもあるようですが、
このツールは残念ながら Windows 10 Home や Windows 11 Home には標準搭載されていません[^1]。

私の環境 ( Windows 11 Home ) に無理やりインストールしてログ出力設定を有効化してみましたが、上手くいかず、ログが出力されませんでした。
標準で入ってないものを無理やり入れたからちゃんと動いてないのかもしれません。（私の設定の仕方が悪いのかもしれませんが...）

Home 以外の Windows OS をご利用の方は、この「ローカルグループポリシーエディター」を使う方法もあります。
結構簡単なのでやり方は調べてみてください。
:::
## 環境
OS：Windows 11 Home
PowerShell：5.1.22621.1778

## 詳細手順
まずはプロファイルの作成から。
プロファイル自体が存在しない場合もあるので、そのときは自分で作成します。
（以下、作成する前提で説明します）

どこに作ればいいのかはパワーシェルの変数 `$PROFILE` を見ると分かります。
```powershell
> $PROFILE
C:\Users\<ユーザ名>\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
```
これがプロファイルのフルパスなので、このパスの通りに `Microsoft.PowerShell_profile.ps1` という名前のプロファイルを作成します。
（ユーザ名は現在ログイン中のユーザ名に置き換えてください）
その上の `WindowsPowerShell` ディレクトリも無ければ作成します。

プロファイルが作成できたら、次のコードを記述します。
```powershell
# 現在の年月日時分秒を取得
$timestamp = Get-Date -Format "yyyy_MM_dd_HH-mm-ss"

# トランスクリプトファイル名を生成
$transcriptFileName = "Transcript_$timestamp.log"

# トランスクリプトを開始
Start-Transcript -Path "C:\foo\bar\$transcriptFileName"
```
`C:\foo\bar\` の部分は、ログの出力先にしたいディレクトリを指定してください。

保存したら作業は完了です！
PowerShellにログインすると、下のようなメッセージが出力され、ログが出力されていることが確認できます。
![fig_transcript.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530468/fce7d4f1-d44e-2ca9-88f0-60e0e769ca74.png)

フォルダを開くと、セッション単位（ログイン～ログアウトまでの間）でログファイルが生成されています。
![fig_transcript2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530468/07905d44-08af-dfc2-d20e-75a4373c0f5d.png)

以上です。
[^1]:参考：https://tanweb.net/2021/01/06/38190/
【Swift】TCAのActionでVoidを使用するとエラーがでる

# はじめに
最近、TCAを触ることが多くいろんな場面で躓くので記事にしていきます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">TaskResult&lt;Void&gt;するとEquatableのエラーが出るんだけどどう対応したらいいのかわからん <a href="https://t.co/nEjZE97Kt0">pic.twitter.com/nEjZE97Kt0</a></p>&mdash; たいしん (@SNQ2001) <a href="https://twitter.com/SNQ2001/status/1690623565950005248?ref_src=twsrc%5Etfw">August 13, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 問題点
VoidがEquatableに準拠してないのでエラーが出る
![スクリーンショット 2023-08-13 22.29.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/fa87fa84-3b80-07b7-e5eb-b4f6c283b50d.png)


```swift
public enum Action: Equatable {
    case buttonTapped
    case sample(TaskResult<Void>)
}
```

# 回避策
```swift
public enum Action: Equatable {
    case buttonTapped
    case sample(TaskResult<EquatableVoid>)
    
    public enum EquatableVoid { case finished }
}
```

# 使い方
```swift
public enum Action: Equatable {
    case buttonTapped
    case sample(TaskResult<EquatableVoid>)

    public enum EquatableVoid { case finished }
}

public func reduce(into state: inout State, action: Action) -> Effect<Action> {
    switch action {
    case .buttonTapped:
        return .run { send in
             await send(.sample(TaskResult {
                try await Task.sleep(nanoseconds: 3 * NSEC_PER_SEC)
                return .finished
            }))
        }
    case let .sample(result):
        switch result {
        case .success:
            print("finished")
        case let .failure(error):
            print(error)
        }
        return .none
    }
}
```

# おわり
まじむずいです
[Unity] ShaderGraphのAlphaがUIで使えるようになったよ！

# 経緯
今までShaderGraphをCanvasで使おうとすると、透明になっている部分が真っ黒に塗りつぶされてしまっていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/a3df43ec-2e68-a25a-9656-dcd087e3d130.png)

Canvasで透明が使えなかったので、泣く泣くShaderを手書きすることがあった。

# 使えるようになった
2023.2.0b3からUniversal -> Material にCanvasという項目が追加された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/cbc83d58-7b18-7e24-75e7-1c736856eaff.png)

Canvasに切り替えると透明度がちゃんと適用される！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/154c8995-22fe-e4ec-649f-f45027ffc245.png)
みんなうれしくてにっこり間違い無し。

どうやらこの機能は3年ほど前からロードマップに追加されていたらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/598f199e-0e02-2f66-29d3-72706fe31843.png)

# 何が変わった？
とりあえずViewGenerateShaderでShaderGraphから生成されたシェーダーコードの差分を見てみる。
なんとか差分が機能しそうな程度には内容が似ている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/5a5853df-07c6-57a3-6d3b-e7b9ccbcc3c7.png)

目についたのは、大幅に削除されている部分。
Shaderに詳しいわけではないので詳細な処理までは分からなかったが、ライティング、VFX、Varyings.hlslに関する処理(ForwardPass, NormalPass関連？)が消されているようだった。
このCanvas機能に関するドキュメントが見つからなかったので正確なことはいえないが、この辺りの機能についてはおそらく制限されるのだと思う。

まだβ版なので、これから詳しいドキュメントが作られたり、フォーラムで報告が上がってくると思うので動向に注目したい。
pytest-asyncio が入っているのに非同期関数のテストがスキップされる。

# 問題
pytest-asyncio が入っているのに pytest を実行すると以下のような警告が出て、非同期関数のテストがスキップされました。
```
============================= test session starts ==============================
platform linux -- Python 3.11.4, pytest-7.4.0, pluggy-1.2.0
rootdir: /src
plugins: anyio-3.7.1, asyncio-0.21.1
asyncio: mode=Mode.STRICT
collected 3 items / 2 deselected / 1 selected

tests/test_main.py s                                                     [100%]

=============================== warnings summary ===============================
~~ 略 ~~
PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped.

~~ 略 ~~

================= 1 skipped, 2 deselected, 6 warnings in 3.54s =================
```

# 原因と対処法
非同期関数のテスト用のデコレーターの付け忘れでした。
以下のように非同期関数の定義の前にデコレーターを付けました。
```
@pytest.mark.asyncio
async def <任意の関数名>():
    ~~ 略 ~~
```

# 結果
以下のようにうまくテストが実行されました。
```
============================= test session starts ==============================
platform linux -- Python 3.11.4, pytest-7.4.0, pluggy-1.2.0
rootdir: /src
plugins: anyio-3.7.1, asyncio-0.21.1
asyncio: mode=Mode.STRICT
collected 3 items / 2 deselected / 1 selected

tests/test_main.py .                                                     [100%]

~~ 略 ~~

================= 1 passed, 2 deselected, 7 warnings in 4.20s ==================
```
【React】自作コンポーネントで超軽量タブ

みなさん、こんにちは
まちゅです。

今回はReactで軽量のタブコンポーネント作成を行っていこうと思います。
外部ライブラリは使いません。

### 概要
このようなタブを作ります。
外部の不要なライブラリは一切使いません。
スタイルやアニメーションは皆さんのお好みで調整してください！![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611905/b251028e-8fd4-9627-9924-851b49557f53.gif)

### コード

まずはtsxからです。

```tsx
interface Props {
  onChange: (tab: number) => void | (() => void);
}

// ダミーデータ
const contents = [
  { text: "幼児", path: "/games" },
  { text: "1年生", path: "/gallery" },
];

export const Tabs: FC<Props> = ({ onChange }) => {
  const [tab, setTab] = useState<number>(0);

  return (
    <div className={style["contents-tab"]}>
      <div className={style["contents-tab-button-wrapper"]}>
        {contents.map((content, index) => (
          <div
            onClick={() => {
              setTab(index);
              onChange(tab);
            }}
            className={
              index === tab
                ? style["contents-tab-button-selected"]
                : style["contents-tab-button"]
            }
          >
            {content.text}
          </div>
        ))}
      </div>

      <div className={style["contents-tab-underline"]} />
    </div>
  );
};
```

軽い解説です。
```tsx
interface Props {
  onChange: (tab: number) => void | (() => void);
}
```
をFCの型引数に渡しておき、
タブが切り替わった際のコールバック関数を
`FC`の引数で受け取れるようにします。

```tsx
const [tab, setTab] = useState<number>(0);
```
では、`tab`に開いているコンポーネント番号を記憶させます。

```tsx
onClick={() => {
    setTab(index);
    onChange(tab);
}}
```
ここで
`setTab(index)`で現在のタブ番号を保存しながら、
コールバックの引数にタブ番号を渡してあげます。

`Array.map`で回しているタブの`index`と`tab`が一致した判定をとって、
`classNameを切り替えています。`

ポイントは、コールバック関数を受け取れるようにしているということです。
タブ番号を取得するために`Dispatch<SetStateAction<number>>`を
interfaceに定義する設計は**複雑度が増すのでナンセンス**です。

また、今回利用するscssは以下。

```scss
.contents-tab {
  width: 672px;
  padding-bottom: 2rem;
  &-button-wrapper {
    display: flex;
    gap: 0.5rem;
  }

  &-button,
  &-button-selected {
    width: 144px;
    height: 48px;
    border: $blue-1 solid;
    border-radius: 0.5rem 0.5rem 0 0;
    border-width: 2px 2px 0px 2px;
    display: grid;
    place-items: center;
    font-weight: bold;
    cursor: pointer;
    transition: 0.2s;
  }

  &-button {
    color: $blue-1;
  }

  &-button-selected {
    background-color: $blue-1;
    color: $white-1;
  }

  &-underline {
    height: 2px;
    background-color: $blue-1;
  }
}
```


利用する側では、このように使います。

```tsx
const [tabNum, setTabNum] = useState<number>(0);
    const tabHandler = (tab: number) => {
    setTabNum(tab);
};

~~(略)~~

<ContentsTab onChange={tabHandler} />
```

基本的に、`tabHandler`関数内でタブの内容変更処理を呼び出します。
コールバックを渡して処理してもらうという事を覚えましょう。

もう少し高度な設計の話で、`React Context`を用いる方法もあり。
そちらの方が自由度は高いですが、それはまたの機会に書きます。

### さいごに
こちらいかがだったでしょうか。
`react-tabs`などライブラリがありますが、
10分～20分もあれば書ける内容ですね。

よりよい手法があればコメントいただければ幸いです。

(追記)
cssのtransitionを追加したので、
gif画像に比べて微妙に挙動が滑らかになっています。
【DiscordChatExporter】Discordのチャットを保存する方法（更新予定あり）【MacOS】

現段階ではただの備忘録です。余力のある際に加筆修正します。

# 本記事の概要
Discordのチャットをローカルに保存したい！
そんな時に便利な無料アプリケーションがDiscordChatExporterです。

ただ、MacOSではコマンドラインでしか操作ができず、調べていてわかりにくかった点もあったので、備忘録がわりに残します。

## 本記事でできること：
- DiscordのチャットのログをHTML形式で保存できる
- 特定のサーバーやチャンネルのみのチャットのログを保存できるように指定できる

# DiscordChatExporterとは
Discordのチャットを保存することができる無料アプリ

# コマンドについて
## 自分の参加するすべてのサーバーのチャットログを出力する

```shell-session
$ dotnet DiscordChatExporter.Cli.dll exporall -t "tokenID"
```

## 自分の参加する特定のサーバーのサーバーIDを出力する

```shell-session
$ dotnet DiscordChatExporter.Cli.dll guilds -t "tokenID"
```

## 自分の参加する特定のサーバーのチャットログを出力する
先ほど出力したguildIDから、自分の保存したいサーバーのものを確認する。
それを利用して特定のサーバーのみのチャットログを出力する。

```shell-session
$ dotnet DiscordChatExporter.Cli.dll exportguild -t "tokenID" -g サーバーID
```

## 自分の参加する特定のチャンネルのチャットログを出力する

```shell-session
$ dotnet DiscordChatExporter.Cli.dll export -t "tokenID" -c チャンネルID
```

### その他コマンドについて
他にも使えるコマンドやオプションは以下のコマンドを用いてターミナルで確認できます。解読が難しかったので今回は自分の使ったものを中心に書き残しましたが、気になる方は見てみてください。

```shell-session
$ dotnet DiscordChatExporter.Cli.dll --help
```
# 参考サイト
- [DiscordChatExporterの公式サイト](https://github.com/Tyrrrz/DiscordChatExporter)
- [【Mac】Discordのチャットログを保存する方法【エクスポートにダウンロードに】](https://oneuro.net/mac-discord-chat-log-export)
Spring BootとMySQLでメモアプリを開発しました #2【駆け出し】

# Spring(Spring Boot)の開発
前回の記事
https://qiita.com/Takatsuna/items/31af8b007a44f2c3a900

では、CSSを当てずに簡易メモアプリを作成しました。

CSSを少し学んだので、アウトプットのためにアプリケーションにスタイルを追加していく形にしようと思います。

## 作ったもの
- メモアプリ
リポジトリ: https://github.com/takatsuna113/spring-memo-app

※ Home画面と詳細画面のみ


## 使用技術
- Spring Boot 2.7.12
- Java 11
- Maven(ビルドツール)
- MySQL(DB)
- Mybatis(O/Rマッパー)

## テーブル定義
前回の記事を参照ください。


## 成果物(画面)
#### Home画面
![スクリーンショット 2023-08-13 21.49.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523157/6cf77d4c-d8b2-7028-1760-7a02bf7faa90.png)

1画面に収まるようにした。
メモのタイトル右側にある「詳細」を押すと画面右側に詳細を表示する


#### 詳細画面
![スクリーンショット 2023-08-13 21.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523157/c859306e-ba3f-9d00-202a-6aee8d013858.png)

こちらも画面に収まるように以下の情報を表示

- タイトル
- 内容
- 作成日
- 更新日
- 詳細の非表示


## 機能
前回の記事を参照ください。

## こだわった箇所

- 自画面遷移
spring bootでの開発において、リンククリック時の自画面遷移の方法がいまいちわからなかったのでSPA"風"にすることで実装をした。
その際、2つのControllerの戻り値を同じhtmlに渡して表示をするのが少し苦労しましたが、なんとかそれっぽい感じになりました。

- css・javascriptを使った動的なスタイリング
メモの詳細をクリックしたときにクリックしたメモだけ背景色を当てるスタイルを実装しました。
しかし、思っていたより上手くいかず調べながら最終的に上手くいったのでとても嬉しかったです。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523157/0215a948-52f0-a56d-e48d-bb7df8a61e7e.gif)

html
```html
    <!-- サイドバー -->
    <div class="sidebar">
      <div class="sidebar-items" th:each="memo : ${memoList}" th:object="${memo}">
        <div class="memo-title">
          <p th:text="*{title}"></p>
        </div>
        <div class="memo-action">
          <a class="detail-memo" th:href="@{/memo/detail/{id}(id=${memo.id})}">詳細</a>
          <a class="edit-memo" th:href="@{/memo/edit/{id}(id=${memo.id})}">編集</a>
          <a class="delete-memo" th:href="@{/memo/delete/{id}(id=${memo.id})}">削除</a>
        </div>
      </div>
    </div>
```


javascript
```javascript
/** サイドバーのフォーカス切り替え */
window.onload = function () {
  const currentUrl = location.href;
  // activeクラスを追加するクラスを取得
  const sidebar = document.querySelectorAll('.sidebar-items');

  sidebar.forEach((link) => {
    // 各コンテンツの詳細リンクのhref属性を取得
    const activeUrl = link.children[1].children[0].href;
    // 開いているURLと詳細リンクを押したコンテンツが一致している場合、activeクラスを追加
    if (currentUrl === activeUrl) {
      link.classList.add('active');
    }
  });

}
```




## 現時点での反省点
- スタイリングの不十分さ
ページ全体のレイアウトを自身のPCに合わせて適用しているので、
レスポンシブ？なにそれ美味しいの？状態...
レスポンシブ対応も随時行っていきたい。
そもそもモバイルファーストでの開発をできていないので、今後意識していく。

## これから
Spring Boot自体あまり触れていなかったのにもかかわらず、フロントエンド周りしかほぼ触っていないのでバックエンドも触れるように既存のスタイリングだけでなく、簡単なアプリを0から作る機会を設けないといけないですね。
Vuetify3でv-date-picker復活！

# この記事の内容
Nuxt3でフォーム処理を作成した際に、
Vuetifyの`v-date-picker`の使い方につまずいたので備忘録として残しておく。

# v-date-picker
[公式](https://vuetifyjs.com/en/components/date-pickers/)にのっているようなコンポーネントです。
予約システムなどの入力に使えそうですね。

[Vuetify2](https://v2.vuetifyjs.com/ja/components/date-pickers/)において`v-date-picker`は通常コンポーネントとして使用できますが、
Vuetify3リリース当初`v-date-picker`は削除されました。
しかし、2023年6月14日リリース[v3.3.4](https://vuetifyjs.com/en/getting-started/release-notes/?version=v3.3.4) から`v-date-picker`が復活するとのことです。

# つみポイント
さっそく使ってみようと思いコーディング　・・・表示されない？
```sample.vue
<template>
	<div>
		<v-date-picker></v-date-picker>
    </div>
</template>
<script lang="ts" setup>

</script>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691844/791d30f7-1bfc-f53f-3d9e-35e6b88b3460.png)


# v-date-picker使い方
なんで使えないんだとissuesを調べた結果1つの[issue](https://github.com/vuetifyjs/vuetify/issues/16191)にたどり着いた。
Vuetifyの最新v3.3.12(2023年8月13日に確認)では常設のコンポーネントとして存在しないらしい。
代わりに現在ではVuetify Labs で利用できるようになったとのこと。
Vuetify Labsの機能は`<script>`で`import`すると使えるようになるらしい。
```sample.vue
<template>
  <div>
    <v-date-picker></v-date-picker>
  </div>
</template>

<script lavng="ts" setup>
  import { VDatePicker } from 'vuetify/labs/VDatePicker'
</script>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691844/0b835f5a-acd8-3500-6ef6-47fe5d98edc5.png)

# 追記 (2024/02/25)
3.4で標準使用できるようになったみたいです！
いずれにせよVuetify Labsがあることは忘れずにしていきたい。
https://vuetifyjs.com/en/components/date-pickers/

# まとめ
常設していない機能はLabsから使えるかもしれないのでRelease notesと共に要チェック！

# 参考文献
1. [公式-date-picker](https://vuetifyjs.com/en/components/date-pickers/)
1. [Vuetify2](https://v2.vuetifyjs.com/ja/components/date-pickers/)
1. [Vuetify v3.3.4](https://vuetifyjs.com/en/getting-started/release-notes/?version=v3.3.4)
1. [ [Bug Report][3.0.3] v-date-picker doesn't exist #16191 ](https://github.com/vuetifyjs/vuetify/issues/16191)
rex0220 一括更新プラグイン 計算式プラグイン連携

[一括更新プラグイン](https://qiita.com/rex0220/items/f90ca06fde6b6e362583)と[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)の連携について、解説します。
一括更新時に、計算式プラグインの処理を適用できます。

# 概要

kintoneアプリストアの問い合わせ管理アプリを利用します。
対応完了の一括処理時に、計算式プラグインの完了日設定処理を実行します。

![2023-08-13_21h35_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a988906a-e167-efb0-5240-ab0149235ea4.png)

更新結果：　完了日が計算式プラグインで更新される
![2023-08-13_21h42_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/10814545-6212-eaea-f5d3-650ad672ae04.png)


操作例
![2023-08-13_21h38_10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/eb7f15c7-b1e3-da60-a00d-4011332f00ef.gif)

# 一括更新プラグイン設定
ボタン名を「対応完了」で、処理を登録します。
![2023-08-13_21h47_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/4967b00e-a405-3e04-d87b-13e5caa8d450.png)

計算式プラグイン連携にチェックします。
これで一括更新の項目を反映後に、計算式プラグインが実行されます。
入力のチェックを行わず、計算式を指定すると自動計算になります。

- 計算式プラグイン連携：　チェック
- 項目別設定：　対応状況と完了日を設定
    - 対応状況
        - "完了"
    - 完了日
        - TODAY() ：　当日を設定

![2023-08-13_21h48_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/44f7e180-3897-3fcc-f3b9-86399e840028.png)

# 計算式プラグイン設定

完了日が未設定で、対応状況(Status)が"完了"の場合、当日を設定

```.js
// 完了日
IFS(完了日,完了日,
Status="完了",TODAY())
```

![2023-08-13_21h22_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/51041e79-5510-32b8-4e31-40736149d54f.png)
<firebase functions> custom errorを投げる

firebase functions でオリジナルのエラーを投げたい場面。

自前でerrorを返しても常にinternalエラーが返ってきてしまう

```js
[admin.FirebaseError: internal] {
   code: 'functions/internal',
   customData: undefined,
   name: 'FirebaseError',
   details: undefined
 }
```


```js
functions.https.onRequest(async (req, res): Promise<void> => {
  res.status(200).send({message: 'error'});
}
```

```js
functions.https.onRequest(async (req, res): Promise<void> => {
  res.status(500).send({message: 'error'});
}
```

# 解決法
今回は以下の2stepで行いました
1. 関数の定義をonCallにする
1. https.errorをthrowする

:::note
onCall は firebase sdkで呼び出す時のみ。
corsや認証の対応が楽にできる。
:::

```js
import { https } from 'firebase-functions';

functions.https.onCall(async (data, context): Promise<void> => {  
// do some
...

// error handling
throw new https.HttpsError('<定義されているcode>', '<custom message>')
}
```

# 参考
https://medium.com/geekculture/how-to-pass-errors-nicely-to-front-end-with-firebase-cloud-functions-6f224072eae4

https://azukiazusa.dev/blog/firebase-functions-https-oncall/
[Python / opencv-python] ImportError: libGL.so.1: cannot open shared object file の対策

# Env

|Item|Versionなど|
|:---|:----------|
|docker image|python:3.10-slim|
|opencv-python|4.8.0.76|


# 事象

dockerコンテナ上での出来事。

```bash
Traceback (most recent call last):
  File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 552, in _run_script
    exec(code, module.__dict__)
  File "/opt/src/st_app.py", line 9, in <module>
    import cv2
  File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.10/site-packages/cv2/__init__.py", line 181, in <module>
    bootstrap()
  File "/root/.local/share/virtualenvs/opt-zvmYt2-H/lib/python3.10/site-packages/cv2/__init__.py", line 153, in bootstrap
    native_module = importlib.import_module("cv2")
  File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: libGL.so.1: cannot open shared object file: No such file or directory
```

# 対策

```dockerfile:Dockerfile
RUN apt -y update
RUN apt -y install libopencv-dev
```

これで解決( ˙灬˙ ก)


# 公式ドキュメント

公式ドキュメントも貼っておく。
詳しくは見てないし、少なくとも今回は参考にすらしていないが、気にしている方もいると思うので。

https://docs.opencv.org/4.8.0/d2/de6/tutorial_py_setup_in_ubuntu.html

# 参考記事

よく発生する問題らしく、他にもいろいろな対策記事がある。

https://stackoverflow.com/questions/55313610/importerror-libgl-so-1-cannot-open-shared-object-file-no-such-file-or-directo

https://cocoinit23.com/docker-opencv-importerror-libgl-so-1-cannot-open-shared-object-file/

https://qiita.com/toshitanian/items/5da24c0c0bd473d514c8

どれかがうまくいかなくても、他で上手く行けばOK₍₍ (ง ˘ω˘ )ว ⁾⁾ｽﾔｯｽﾔｯ