OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel11とInertia,Reactで多言語化

# はじめに

こんにちは、エンジニアのkeitaMaxです。

Laravel11とInertia,React,TypeScriptで多言語化対応したいと思います。

# PHP側の修正

まずPHPからReactに翻訳したいファイルを送れるように、
`HandleInertiaRequests`に以下を追加します。


```php:src/app/Http/Middleware/HandleInertiaRequests.php
    public function share(Request $request): array
    {
    // 追加　↓
        $fullLang = $request->getPreferredLanguage();
        $lang = strtok($fullLang, '_');
        $defaultLocale = config('app.locale');
        $json = lang_path("{$lang}/front.json");
        //NOTE: 用意していない言語ならデフォルトを使用
        if (!file_exists($json)) {
            $json = lang_path("{$defaultLocale}/front.json");
        }
        $content = file_get_contents($json);
        if ($content === false) {
            throw new Exception('ファイルの読み込みに失敗しました');
        }
        $translations = json_decode($content, true);
    // 追加　↑
    
        return [
            ...parent::share($request),
    // 追加　↓
            'translations' => $translations,
    // 追加　↑
            'auth' => [
                'user' => $request->user(),
            ],
            'flash' => [
                'message' => fn() => $request->session()->get('message'),
            ],
        ];
    }
```

実際にの翻訳ファイルは以下のファイルにおきます。
今回は日本語と英語の２つで設定をします。

`src/lang/en/front.json`
`src/lang/ja/front.json`

```json:src/lang/en/front.json
{
    "Good morning!": "Good morning"
}
```

```json:src/lang/ja/front.json
{
    "Good morning!": "こんにちは"
}
```
# React側の修正

PHPから送られてきた翻訳ファイルを受け取るために、
`src/resources/js/app.tsx`ファイルを以下のように修正します。

```ts:src/resources/js/app.tsx
const appName = import.meta.env.VITE_APP_NAME || 'Laravel'

    // 追加　↓
declare global {
    function __(key: string, replace?: Record<string, unknown>): string;
}
    // 追加　↑

createInertiaApp({
    title: (title) => `${title} ${appName}`,
    resolve: (name) => resolvePageComponent(`./Pages/${name}/index.tsx`, import.meta.glob('./Pages/**/*.tsx')),
    setup({ el, App, props }) {
        const root = createRoot(el)
    // 追加　↓
        const translations = Object(props.initialPage.props.translations)
        window.__ = (key: string, replace?: Record<string, unknown>): string => {
            let translatedText: string = translations[key] || key
            for (const key in replace) {
                const replacedText = String(replace[key as keyof typeof replace])
                translatedText = translatedText.replace(`:${key}`, replacedText)
            }
            return translatedText
        }
    // 追加　↑

        root.render(<App {...props} />)
    },
    
```

これで準備はOKです。

# 実際にやってみる

実際に多言語化対応をしたい時は、以下のようにReact側で書くとブラウザの言語によって変わります。

```index.tsx
<p>{__('Good morning!')}</p>
```

こうすると英語の時は`Good morning`,日本語の時は`こんにちは`と表示されるようになります。


# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

# 次の記事
phpMyAdminでテーブル作成時のエラーを直していく

## 前提環境
PHP：8.2.0（MAMP使用）
phpMyAdmin：5.2.0

※phpMyAdmin 5.2.1から解消されたエラーだと、コメントにて教えていただきました※

## phpMyAdminのテーブル作成時に以下のエラーが出ました

![phpMyAdminError.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3995314/a770363f-8bb0-4b7a-b382-48c440f9dce5.png)

「サーバー上でいくつかのエラーが検出されました！
このウィンドウの一番下を見てください。」
```
Deprecation Notice in ./libraries/classes/Table/ColumnsDefinition.php#424

Using ${var} in strings is deprecated, use {$var} instead
```

どうやらエラーを読むと「ColumnsDefinition.php」というファイルで、
${変数名}となっているものを、{$変数名}とする必要があるようです。

## ColumnsDefinition.phpを探す
私はMAMPを使ってPHPを使用しているので、以下のパスへ該当のファイルを探しに行きました。
```
/Applications/MAMP/bin/phpMyAdmin5/libraries/classes/Table/ColumnsDefinition.php
```

## 該当ファイルをエディタで開いて修正
※編集する前に変更を間違えるかもしれないので、ファイルを別場所でコピーして取っておきます。

「ColumnsDefinition.php」というファイルをVSCodeなどで開いて
エディタのコード検索で
```${```
と打ち込み、```${変数名}```になっているものを探します。

私の場合は```${columnNumber}```となっていたので、これを全て```{$columnNumber}```に書き換えました。

## 修正したファイルを保存して、MAMPを再起動
MAMPの「Stop」ボタンを押して、Apacheサーバーを停止。
ブラウザのキャッシュも消しておきます。
MAMPの「Start」ボタンを押して、再度立ち上げ。

:::note info
これでテーブル作成時に、エラーが出なくなりました。
:::
Docker構築してたけどよく分からなくなったのでコンテナ削除してみた

Docker Desktop上で削除しようとしたら「動いているので削除できません」みたいなこと言われたので、Dockerの停止からコンテナ指定削除、Docker Desktop上での削除までをまとめてみた。

流れ:
1. Dockerコンテナの停止
2. コンテナの指定削除
3. Docker Desktopでのコンテナ削除

# 1. Dockerコンテナの停止
コンテナ状況を把握します。以下のコマンドで停止中のコンテナを含めた全コンテナの稼働状況一覧を表示。
「Exited=停止」みたいです[1]。
```ruby:Terminal
$ docker ps -a 
```

> 動いている場合、以下のコマンドで停止[1]。
```ruby:Terminal
$ docker stop <CONTAINER IDまたはNAME>
```

# 2. コンテナの指定削除
以下のコマンドでコンテナを指定して削除。コンテナ名orコンテナIDは"$ docker ps -a"で確認[2]。なおrmの後に複数コンテナ名orコンテナID指定可能です。
```ruby:Terminal
$ docker rm コンテナ名orコンテナID
```

削除確認のため、再度以下コマンド実行して確認。コンテナがなければ削除完了。
```ruby:Terminal
$ docker ps -a 
```

# 3. Docker Desktopでのコンテナ削除
Docker Desktopを開き、削除したいコンテナを選択しながらDeleteボタンを押すと削除完了。

以上、誰かの役に立てたらとても嬉しいです。
応援しています。



# 参考資料:
[1] @hxrxchang.(2019).Dockerコンテナ一覧を表示し、任意のコンテナを起動する.https://qiita.com/hxrxchang/items/91759beb12336faf9518
[2] さんかく.(2024).Dockerコンテナ&イメージ削除方法.https://zenn.dev/joho0724/articles/sankaku0724-newcreate15
GitHubで親リポジトリはcloneできるのにサブモジュールをcloneできないとき

# 状況
- Windows11で発生
- 新規で開発メンバーに加わってもらうためOrganizationに招待し、memberのroleを与えた
- 親リポジトリ(private)とサブモジュール(private)どちらもweb上で開くことができている（アクセス権がある）
- gitをインストールしSSH認証キーの登録を済ませている
  - `ssh -T git@github.com`を実行すると`Hi username!`と出てくる
- `git clone <親リポジトリのSSHのURL>`で親リポジトリのcloneができている
- 親リポジトリのルートディレクトリで`git submodule update --init --recursive`を実行してサブモジュールをcloneしようとすると以下のようなエラーが出た
```
Cloning into 'C:/Users/<ユーザー名>/**/<親リポジトリ名>/<サブモジュール名>'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of 'git@github.com:<組織名>/<サブモジュール名>.git' into submodule path 'C:/Users/<ユーザー名>/**/<親リポジトリ名>/<サブモジュール名>' failed
Failed to clone '<サブモジュール名>'. Retry scheduled
Cloning into 'C:/Users/<ユーザー名>/**/<親リポジトリ名>/<サブモジュール名>'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of 'git@github.com:<組織名>/<サブモジュール名>.git' into submodule path 'C:/Users/<ユーザー名>/**/<親リポジトリ名>/<サブモジュール名>' failed
Failed to clone '<サブモジュール名>' a second time, aborting
```

# 解決方法

SSHではなくHTTPSでサブモジュールを取得した
```
git config --file .gitmodules submodule.<サブモジュール名>.url https://github.com/<組織名>/<サブモジュール名>.git
git submodule sync
git submodule update --init --recursive
```
もともと.gitmodulesの内容は
```
[submodule "<サブモジュール名>"]
	path = <サブモジュール名>
	url = git@github.com:<組織名>/<サブモジュール名>.git
```
とSSHのURLだったが、SSH認証がうまくいってないためこれをHTTPSのURLに変えることで成功した

# おわりに
SSH認証がうまくいってないのは間違いなさそうだが、親リポジトリをcloneできるのにサブモジュールだけできない理由がよくわかりません。
根本的な解決方法ではない気がするので誰か教えてください。
日本語プログラミング言語Mindの小技 「リカーシブコール」たらい回し関数

## Mindでもリカーシブコール
Mind でも他のプログラミング言語と同様に、リカーシブコール（再帰呼び出し）が使えます。
リカーシブコールとして有名（？）な、竹内 郁雄先生の「たらい回し関数」をMindでプログラミングし実行してみました。
## 実行時の注意
各プログラミング言語で実装・実行可能ですが、x,y,z の値によっては　呼び出し回数が膨大になります。
f(2,1,0)で9回、f(4,2,0)で53回、f(6,3,0)で673回、f(8,4,0)で12,605回、f(10,5,0) で343,073回、f(12,6,0)で12,604,861回、f(14,7,0)で588,802,013回
でした。
## たらい回し関数の停止性とその値
「たらい回し関数」は、
たらい回し関数f(x,y,z)：x,y,z は整数 の定義
f(x,y,z)
= y : x≦yのとき
= f(f(x-1,y,z),f(y-1,z,x),f(z-1,x,y)):x＞yのとき

たらい回し関数f(x,y,z)が　任意の整数x,y,zで停止し
ある簡単な関数g(x,y,z)があり。（g は再帰表現なしで記述できます）
f(x,y,z)＝g(x,y,z)である。
を証明するのは、結構たいへんです。
いくつか証明がありますが私の証明は、２重の数学的帰納法を使い、40行ぐらいです。
みなさんも　g(x,y,z)を見つけて（できれば証明の概略も）コメントに書き込んでください。

大昔、数学セミナーの「エレガントな解答を求む」で出題されましたが、証明は掲載されませんでした。
次回は、g(x,y,z)と[停止性の証明](https://qiita.com/ITvision/items/44f27bbfe95b307513f8)を掲載したいと思います。
## Mind プログラム
``` 
たらい回しとは
      ｘは  変数
      ｙは  変数
      ｚは  変数
      ｘと  ｙと  ｚに  入れ
      ｘが  ｙ  以下  
            ならば  ｙを  返し
　　　　　 　さもなければ
                  ［ｘ － １］と  ｙと  ｚを  たらい回し
　　　　　　　　　　［ｙ － １］と  ｚと  ｘを  たらい回し
　　　　　　　　　　［ｚ － １］と  ｘと  ｙを  たらい回し
　　　　　　　　　　たらい回しし  返す 
　　　　　　つぎに。
メインは 
     ixは　変数
     iyは　変数
     izは　変数
	起動引数個数が　3と　等しい
　　　　ならば
  		    起動引数(1)を 数値変換し　捨て　ixに　入れる
	 	    起動引数(2)を 数値変換し　捨て　iyに　入れる
 		    起動引数(3)を 数値変換し　捨て　izに　入れる
　　　　    「たらい回し開始します。」と　表示し　改行し　
		    ixと　iyと　izとを　たらい回し  数値表示する
　　　　    「です。」と　表示し　改行する
       さもなければ
　　　　　  「起動引数個数は３個です。」と　表示し　改行する
　　　　つぎに。
 ```
 ## 実行結果
 ``` 
 c:\mind8\pmind\sample>taraimawashi 1 2 3
たらい回し開始します。
2です。
c:\mind8\pmind\sample>taraimawashi 15 10 6
たらい回し開始します。
15です。

 ```
Pythonのキュー比較：List・Deque・Queueの使い分け

キューを使うとき、「list でいいのか？ deque のほうが速いのか？ queue.Queue とは何が違うのか？」と迷ったことがあるかもしれません。それぞれのデータ構造には特徴があり、適材適所で使い分けることで処理の効率が大きく変わります！

---

## 1. それぞれの特徴
| データ構造 | 主な用途 | 特徴 |
|------------|----------|---------------------------------------------------|
| `list` | 一般的な配列操作 | 先頭の要素の追加・削除が遅い（O(n)） |
| `collections.deque` | 高速な両端キュー | 両端の追加・削除が高速（O(1)） |
| `queue.Queue` | マルチスレッドのタスク管理 | [スレッドセーフ](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89%E3%82%BB%E3%83%BC%E3%83%95)なFIFOキュー |

---

## 2. `list`（通常のリスト）
### ✅ 長所
- Python の組み込み型で、使いやすい
- 末尾の `append()` や `pop()` は O(1) で高速

### ❌ 短所
- 先頭の要素の `insert(0, x)` や `pop(0)` は O(n)（遅い）

```python
lst = [1, 2, 3]
lst.append(4)  # 末尾に追加（高速）
print(lst.pop())  # 4（末尾から削除、O(1)）

lst.insert(0, 0)  # 先頭に追加（O(n)）
print(lst.pop(0))  # 0（先頭から削除、O(n)）
```

> 🔹 先頭の追加・削除が多い場合は `deque` を使うべき！

---

## 3. `collections.deque`（両端キュー）
### ✅ 長所
- 両端の `append()` / `appendleft()` / `pop()` / `popleft()` が O(1) で高速
- `list` のような可変長のデータ構造
- スレッドセーフ（ロックは手動で必要）

### ❌ 短所
- `list` のようなランダムアクセス（`deque[i]`）は遅い（O(n)）

```python
from collections import deque

dq = deque([1, 2, 3])
dq.append(4)  # 右端に追加
dq.appendleft(0)  # 左端に追加

print(dq.pop())  # 4（右端から削除）
print(dq.popleft())  # 0（左端から削除）
```

> 🔹 両端の操作が頻繁に発生する場合は `deque` が最適！

---

## 4. `queue.Queue`（スレッドセーフなキュー）
### ✅ 長所
- `put()` / `get()` がスレッドセーフ（ロック管理不要）
- マルチスレッドのタスクキューに適している

### ❌ 短所
- `deque` よりもやや遅い（スレッドロックのオーバーヘッド）
- 直接インデックスアクセス不可（FIFO 方式）

```python
import queue

q = queue.Queue()
q.put(1)  # キューに追加
q.put(2)
q.put(3)

print(q.get())  # 1（FIFOで取得）
print(q.get())  # 2
```

> 🔹 マルチスレッド環境で安全にキューを使いたい場合に最適！

---

## 5.まとめ
| データ構造 | 先頭追加 | 末尾追加 | 先頭削除 | 末尾削除 | スレッドセーフ | 用途 |
|------------|---------|---------|---------|---------|--------------|-------------|
| `list` | O(n) | O(1) | O(n) | O(1) | ❌ | 一般的なリスト操作 |
| `deque` | O(1) | O(1) | O(1) | O(1) | △（ロックが必要） | キュー・スタック |
| `queue` | O(1) | O(1) | O(1) | O(1) | ✅ | マルチスレッドのタスク管理 |
- **`list`** → 配列のように扱いたいとき（検索や末尾操作が中心）
- **`deque`** → 先頭や末尾の要素の追加・削除が多いとき（スタック・キュー用途）
- **`queue`** → マルチスレッドで安全にキューを使いたいとき（タスク管理）
---

参考

- https://docs.python.org/3/tutorial/datastructures.html
- https://www.geeksforgeeks.org/deque-in-python/
- https://www.geeksforgeeks.org/queue-in-python/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/4d969b7b-759c-405c-a3c9-543c0846c844.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/6593e36c-f227-4d6c-b69f-fad3ba2fd53b.png)


弊社の求人,ご興味ある方是非応募してください。

- [急成長のHRTech企業でAIとデータ基盤を駆使しDXをリードするデータエンジニアを募集](https://hrmos.co/pages/techocean/jobs/1898172211721719822)
個人開発サーバーに Cloudflare を導入した話

# 概要
VPS（XServer）上に置いている API サーバーに Cloudflare を導入した。
Cloudflare でプロキシ化することで、トラフィック確認等のインフラ周りの分析がしやすくなることに加え、DDoS攻撃等のセキュリティ対策ができるようになる。
先日、DoS攻撃を受けたこともあり導入することにした。

本稿では XServer VPS にあるサーバーへの導入手順だが、作業内容自体は同じはず。

# 前提
- ドメインを取得していること
- Cloudflare アカウント作成済みであること

# 手順
1. DNSSEC を無効化
2. プロキシするDNSレコードを選択
3. ネームサーバーを更新

英語ドキュメントに抵抗がないのなら公式の丁寧な[セットアップ資料](https://developers.cloudflare.com/dns/zone-setups/full-setup/setup/)があるので、そちらを確認するのが一番わかりやすい。

## 1. DNSSEC を無効化
[ICANN Lookup](https://lookup.icann.org/en) で自身のドメインを入力し、現在使用 DNSSEC が有効かを確認する
もし、有効なら契約しているレジストラから無効にする
![スクリーンショット 2025-03-20 115129.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940829/b3faa825-96e5-41d0-b304-f7181b679171.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940829/e28a3d12-f8da-4ff8-9376-058e4fa7bc57.png)

## 2. プロキシするDNSレコードを選択
Cloudflare でプロキシ化したいドメインの入力欄があるので入力する（スクショ撮り忘れ）
すると、DNSレコードが表示される。プロキシ化したいレコードがあることを確認し、なければ「レコードの追加」から手動で追加し、プロキシを ON にする
レコード情報に問題がなければ「アクティベーションに進む」を押下
![スクリーンショット 2025-03-20 040933.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940829/e36de459-42a8-47cf-ba8a-3920290955af.png)

## 3. ネームサーバーを更新
現在使用しているネームサーバーを削除し、Cloudflare の提示したものに置き換える
![スクリーンショット 2025-03-20 041030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940829/255fa6c1-5b87-4072-aa2f-d0a833925e08.png)

その後、Cloudflare で変更の確認をして進めれば完了
普段ChatGPTやClaudeにぶん投げているトークン数がどのくらいなのか検証してみた

# 生成 AI のトークン数

よく、生成 AI の記事や新モデル発表のニュースなどで、料金体系が 3 ドル/100 万トークンのような表記がされています。

また、生成 AI のモデルによっては 1000 - 2000 トークンを目安にして、指示を渡すことで出力結果がより良くなり、逆にそれ以上の過量な情報を渡すと解答の精度が低下するということが分かっています。

しかし、この 1000 トークン、2000 トークン、100 万トークンというのは、一体どういう意味なのでしょうか？

そこで今回、生成 AI のトークン数を数える方法を調べ、普段生成 AI を使っているときにどのくらいのトークン数を消費しているかを肌感覚で理解するために検証を行なってみました。

## トークンとは

トークンとは、生成 AI のモデルが理解できる最小の単位のことです。

トークン化とは、文章をトークンに分解することであり、英単語は 1 トークン、日本語は 1 文字が 1 トークンに変換されることが多いとされています。(後述しますが、最新モデルではこのトークン化の効率がどんどん改善されており、多くの文字数をまとめて 1 トークンへ変換できるようになっています。)

つまり、上記のトークン化アルゴリズムだと、導入時に挙げた料金体系 3 ドル/100 万トークンとは、100 万英単語あたり 3 ドルの料金という意味です。

といっても、これだけではまだイメージが湧きにくいと思います。

そこで、トークン数を数える便利なサービスが提供されています。

## トークン数を数える方法

トークン数を数える方法は、様々なサービスで提供されていますが、中でも代表的な Open AI Tokenizer という OpenAI が提供しているサービスがあります。

[Open AI Tokenizer](https://platform.openai.com/tokenizer)

方法は簡単で、Open AI Tokenizer に文章を入力すると、そのトークン数が表示されます。

試しに、エンジニアによく使われるであろう、以下のような「 Ruby コード + 指示プロンプト」と言う形式の文章を入力して検証してみました。(モデルは GPT-4o & GPT-4o-mini)

```

# app/models/user.rb
class User < ApplicationRecord
  has_many :posts, dependent: :destroy
  has_many :comments, dependent: :destroy

  validates :email, presence: true, uniqueness: true
  validates :username, presence: true, length: { minimum: 3, maximum: 50 }

  before_save :downcase_email

  def full_name
    "#{first_name} #{last_name}"
  end

  private

  def downcase_email
    self.email = email.downcase if email.present?
  end

  # 以下、100 行まで汎用的なRubyコードを記述
  # ここから段階的に行数を増やしていく
end

---

あなたはRubyのエキスパートエンジニアです。
上記のコードをレビューし、改善点があれば指摘してください。

```

コード部分を段階的に増やして検証した結果が以下となります。

## トークン数の検証結果

### コード行数とトークン数の関係

| コード行数 | トークン数 |
| ---------: | ---------: |
|     100 行 |        757 |
|     150 行 |      1,851 |
|     200 行 |      2,300 |

ここから、だいたい汎用的なコード + 簡単な指示プロンプトで (行数 \* 10) ± 300 トークンくらいになるということが分かります。

この辺り、増減率が変化するのは、コードの複雑性に伴う文字数の増加でトークン数が変動するためです。

本来は、正確なトークン数を検証するには文字数と比較していく方が適切ですが、今回は「汎用的に使うようなコード+指示プロンプト」での検証を行って普段使っている指示がどのくらいのトークン数になるかを検証したかったため、このような普段使いでより把握しやすい行数での検証を行いました。

つまり、導入で挙げた例で言うと、今回の形式だと生成 AI モデルによっては 150 行前後がもっともよい解答が出力されるということです。

なお、注意事項として、トークン化アルゴリズムは ChatGPT各種 や Claude各種 などのモデルごとに異なっており必ずしも今回の結果が全てに共通するわけではありません。(ちなみに Open AI Tokenizerでは ChatGPT の各モデルのアルゴリズムでトークン数を検証できます)

また、今回検証したのはユーザーが入力する入力トークン数です。

生成 AI の回答は出力トークン数でカウントされ、例えば API キーで利用する場合は別々の料金体系となっています。(Claude 3.7 Sonnet は出力トークンを制限することができ、解答の量とコストのトレードオフが行えるようになっています。)

## まとめ

今回は、生成 AI のトークン数を数える方法を調べ、普段生成 AI を使っているときにどのくらいのトークン数を消費しているかを肌感覚で理解するために検証を行なってみました。

2025 年 3 月時点では、最新モデルではトークン化の効率がどんどん改善されており、多くの文字数をまとめて 1 トークンへ変換できるようになっています。

Claude 3.7 Sonnet では、渡すトークンが多ければ多いほど解答の精度が上昇するとも言われています。

ですが、コスト的な面から、旧モデルを利用してシステムに組み込む場合は、トークン数を意識して指示を渡すことで、よりコストパフォーマンスの高いシステムを構築することができると考えられます。

また、普段使いでもトークン数を意識することで、例えば無料プランで利用可能なモデルの回答の精度を上げることも可能だと思います。

ぜひ、普段自身が使用している言語やプロンプトでもトークン数を数えてみてください。
develop ブランチに push すべきところを誤って master ブランチに push してしまった話

# git でやらかした

状況としては下記のとおり。

(1) ```master``` ブランチから ```develop``` ブランチを切って作業をした
(2) ```develop``` ブランチで何度か commit した
(3) 本来は ```git push origin develop``` とすべきところを、間違えて ```git push origin master``` としてしまった
(4) その結果、```develop``` ブランチの変更が、リモートの ```master``` ブランチに反映されてしまった

この状態からリモートレポジトリを元に戻し、あらためて ```git push origin develop``` としたい。なお、コミット履歴は下記のとおり。

```
33e0459 * develop origin/master いろいろと機能を追加
41925cc * 関数を追加
2e1fcea * 諸々修正
2bdc6cb * いったんすっきりさせた
6b0eac3 * master 誤記を修正
```

回復方法をいろいろ検索してもこれといった方法が見当たらず、[思い切って質問したところ](https://qiita.com/hajime-f/questions/cc629bdea2335393c2aa)、神が降臨して丁寧に手順を教えてくださったので（ありがとうございました）、備忘を兼ねて記録に残します。

# 回復手順

状況に応じて下記3つの方針がある。

## 方針A

リモートの ```master``` の履歴を ```6b0eac3``` まで巻き戻し、```develop``` の内容を反映させた事実を無かったことにする。

```
$ git checkout master
$ git push --force origin master
$ git checkout develop
$ git push origin develop
```

リモートからコミットを取り除くことになるので、複数人で作業していてリモートの ```master``` を他の誰かが参照しているならやるべきではない。自分一人で作業しているなら手軽。

## 方針B

ローカルの ```master``` を ```33e0459``` まで進めた上で、```6b0eac3``` 以降のコミットを新しいものから順にすべて revert する。

```
$ git checkout master
$ git merge --ff develop
$ git revert 6b0eac3..HEAD
$ git push origin master
$ git checkout develop
$ git push origin develop
```

複数人で作業しているならこれが安全。1コミットずつ revert した履歴を残したいならこれ。

## 方針C

ローカルの ```master``` を ```33e0459``` まで進めた上で、```6b0eac3``` 時点のファイルを取り出し、それをコミットする。これも安全。1コミットで元に戻したいならこれ。

```
$ git checkout master
$ git merge --ff develop
$ git checkout 6b0eac3 -- .
$ git commit -a
$ git push origin master
$ git checkout develop
$ git push origin develop
```

# git むづかしい

私は気楽な個人開発で１人作業していたので、方針Aでサクッと解決できたんですが、これがチーム開発だとそうはいかないですよね。現場で顔を青くする様子が目に浮かびます。

それにしても、git むづかしすぎない…？🫠
人類（特に私）には早すぎるツールなのかもしれない…。
Salesforceでの通知のまとめ



+ [カスタム通知を設定する](https://qiita.com/Keiji_otsubo/items/9dc53cc93f6c22c8dc19)
+ [ケースコメント通知にコメントがありません](https://qiita.com/Keiji_otsubo/items/b26dd19deb16bba471a1)
+ [2024/10/20からTrailblazer Communityやプレイグランド、DE環境のメール通知が届かない](https://qiita.com/Keiji_otsubo/items/bd1af4268e5610f00f57)


# フロー

+ [フロー：商談で最終活動日から一定数の日付が過ぎたら通知する](https://qiita.com/Keiji_otsubo/items/c50823adcc48659300e8)
+ [フローメールアラートの受信者エラー 0の回避策](https://qiita.com/Keiji_otsubo/items/bfc48b68d9f3e2273e68)
+ [フローコアアクションの設定](https://qiita.com/Keiji_otsubo/items/0ebaa1a2a3c4c40f60e9)

# トレイルヘッド

+ [インスタント通知アプリケーションの作成](https://qiita.com/Keiji_otsubo/items/c28736e5a20eecbc5b07)


# 未解決

+ [承認プロセスのベールマク通知](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000V0Fc)
Node.js 22 + TypeORM (ESM) でハマった

## はじめに

Node.js 22 で TypeORM を使ってバックエンドを構築しようとした際に、ESM (ECMAScript Modules) の扱いで様々なエラーに遭遇しました。本記事では、発生したエラーとその解決策をまとめます。

## 環境

- Node.js: 22.13.1
- TypeORM: 0.3.21
- TypeScript: 5.8.2

## 発生したエラー

1. `exports is not defined in ES module scope`
2. `Cannot find module '/app/dist/data-source' imported from /app/dist/server.js`
3. `ERR_UNKNOWN_FILE_EXTENSION: Unknown file extension ".ts" for /app/src/entities/Drug.ts`

## 解決策

### 1. `package.json` の設定

Node.js 22 では ESM を使用する場合、`package.json` に `"type": "module"` を明示する必要があります。

```json
{
  "name": "medilog-backend",
  "version": "1.0.0",
  "description": "MediLog backend using Express and TypeORM",
  "main": "dist/server.js",
  "type": "module",
  "scripts": {
    "dev": "ts-node-dev --respawn --transpile-only src/server.ts",
    "build": "tsc",
    "start": "node dist/server.js"
  },
  "dependencies": {
    "body-parser": "^1.20.3",
    "cors": "^2.8.5",
    "dotenv": "^16.4.7",
    "express": "^4.21.2",
    "mssql": "^11.0.1",
    "reflect-metadata": "^0.2.2",
    "tsconfig-paths": "^4.2.0",
    "typeorm": "^0.3.21"
  },
  "devDependencies": {
    "@types/cors": "^2.8.17",
    "@types/express": "^5.0.0",
    "ts-node": "^10.9.2",
    "ts-node-dev": "^2.0.0",
    "typescript": "^5.8.2"
  },
}
```

### 2. `tsconfig.json` の設定

TypeScript のコンパイル設定で `module` を `NodeNext` に変更し、`moduleResolution` も `NodeNext` にする。

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true,
    "strictPropertyInitialization": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "resolveJsonModule": true,
    "forceConsistentCasingInFileNames": true,
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}
```

### 3. `import` 文の修正

CommonJS (`require`) は使えないため、すべて `import` に統一する必要があります。

**修正前 (CommonJS):**
```js
const express = require("express");
```

**修正後 (ESM):**
```js
import express from "express";
```

### 4. TypeORM の `entities` 設定

TypeORM の `data-source.ts` で `entities` のパスを `.js` に変える必要があります。

**修正前:**
```ts
entities: ["src/entities/*.ts"],
```

**修正後:**
```ts
entities: ["dist/entities/*.js"],
```

## まとめ

Node.js 22 で TypeORM を ESM として動かす場合、

- `package.json` に `"type": "module"` を追加
- `tsconfig.json` で `module` と `moduleResolution` を `NodeNext` に変更
- `import` 文を ESM 準拠に修正
- TypeORM の `entities` パスを `.js` に変更

といった対応が必要になります。
docker localstack, terraformを利用して sqsのlocal環境を作成する

[docker localstack, terraformを利用して s3のlocal環境を作成する](https://qiita.com/ziima/items/31e0c09f944592623351)の続きでどうしても、AWSでPush型Eventの環境を作りたくなり始めているだけ。

# docker localstack, terraformを利用して sqsのlocal環境を作成する

## table of contents

1. sqsのresouceを作成する
1. localstackにserviceを登録する
1. apply

## 1. sqsのresouceを作成する

sqs用のterraformファイルとmain.tfを編集する。


`main.tf` には、endpointsを定義。

```terraform
terraform {
  backend "local" {}
}

provider "aws" {
  region     = "ap-northeast-1"
  access_key = "access_key"
  secret_key = "secret_key"

  s3_use_path_style           = true
  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true

  endpoints {
    s3 = "http://localstack-main:4566"
    sqs = "http://localstack-main:4566"
  }
}
```

`sqs.tf`には、SQSの定義を記載する。
[terraform](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue)にほぼどおり。

```terraform
resource "aws_sqs_queue" "example_queue" {
    name = "example_queue"
    delay_seconds = 0
    max_message_size = 262144
    message_retention_seconds = 1209600
    receive_wait_time_seconds = 5
    redrive_policy =  jsonencode({
        maxReceiveCount = 4,
        deadLetterTargeArn = aws_sqs_queue.example_queue_deadletter.arn
    })
}

resource "aws_sqs_queue" "example_queue_deadletter" {
    name = "example_queue_deadletter"
}

resource "aws_sqs_queue_redrive_allow_policy" "example_queue_deadletter_policy" {
    queue_url = aws_sqs_queue.example_queue_deadletter.id

    redrive_allow_policy = jsonencode({
        redrivePermission = "byQueue",
        sourceQueueArns = [aws_sqs_queue.example_queue.arn]
    })
}
```


## 2. localstackにserviceを登録する

servicesに追加する

```compose.yaml
localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
    build:
      context: ./localstack
      dockerfile: dockerfile
    ports:
      - "127.0.0.1:4566:4566"            # LocalStack Gateway
      - "127.0.0.1:4510-4559:4510-4559"  # external services port range
    environment:
      # LocalStack configuration: https://docs.localstack.cloud/references/configuration/
      - DEBUG=${DEBUG:-0}
      - SERVICES=s3,sqs
    volumes:
      - "localstack_volume:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
```

## 3. apply

あとは、terraformでapplyを実施する

```terminal
% terraform apply
```
Power BI workout - 行ラベル

Power BI セマンティック モデルのテーブル プロパティ **行ラベル** について、どんな機能？と考えるより実際の動作を把握するだけで充分である。

テーブルを用意し、Power BI ビジュアルに列を使用する。
```text:TMDL
createOrReplace

	table Table1
		column PK
			isKey
			sourceColumn: [PK]

		column Name
			sourceColumn: [Name]

		column 'Name (Row label)'
			isDefaultLabel
			sourceColumn: [Name (Row label)]

        column Value
			summarizeBy: sum
			sourceColumn: [Value]

		partition Table1 = calculated
			mode: import
			source = ```
					
					DATATABLE(
					    "PK", INTEGER,
					    "Name", STRING, "Name (Row label)", STRING,
					    "Value", INTEGER, 
					    {
					          { 1, "NameA", "NameA", 10 }
					        , { 2, "NameA", "NameA", 20 }
					        , { 3, "NameB", "NameB", 20 }
					    }
					)
					```
```
行ラベルに定義した列は個別の値として扱われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/adb78ced-3683-4cfc-89b2-9751f0945472.png)
ビジュアルにより発行される DAX クエリを読めば動作は明白である。
```text:DAX query
DEFINE
	VAR __DS0Core = 
		SUMMARIZECOLUMNS(
			ROLLUPADDISSUBTOTAL('Table1'[Name], "IsGrandTotalRowTotal"),
			"SumValue", CALCULATE(SUM('Table1'[Value]))
		)

	VAR __DS0PrimaryWindowed = 
		TOPN(502, __DS0Core, [IsGrandTotalRowTotal], 0, 'Table1'[Name], 1)

EVALUATE
	__DS0PrimaryWindowed

ORDER BY
	[IsGrandTotalRowTotal] DESC, 'Table1'[Name]
```
行ラベルに定義された列を使用するとき、自動的にキー列を含めるという動作。
```text:DAX query
// DAX Query
DEFINE
	VAR __DS0Core = 
		SUMMARIZECOLUMNS(
			ROLLUPADDISSUBTOTAL(
                ROLLUPGROUP('Table1'[PK], 'Table1'[Name (Row label)]),
                "IsGrandTotalRowTotal"
            ),
			"SumValue", CALCULATE(SUM('Table1'[Value]))
		)

	VAR __DS0PrimaryWindowed = 
		TOPN(
            502,
            __DS0Core,
            [IsGrandTotalRowTotal], 0,
            'Table1'[Name (Row label)], 1,
            'Table1'[PK], 1
        )

EVALUATE
	__DS0PrimaryWindowed

ORDER BY
	[IsGrandTotalRowTotal] DESC, 'Table1'[Name (Row label)], 'Table1'[PK]
```

# 思ったこと🙄
- Sort by column も似たような仕組みである

# その他
https://powerbi.connpass.com/

https://www.microsoft.com/en-us/power-platform/products/power-bi

https://www.microsoft.com/en-us/microsoft-fabric
spring boot x PostgreSQL IDカラム AUTO INCREMENT


# IdカラムのAUTO INCREMENTが働かない
```@GeneratedValue(strategy = GenerationType.IDENTITY)```  追記してるのになぜ？
```java
@Entity
@Table(name="todos")
public class Todo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "content", nullable = false)
    private String content;

    @Column(name = "done")
    private Boolean done = false;
}
```
Not Null指定してるのに新しいTodoを追加する時、
自動でIdカラムにIdが追加されず、Nullなんやがと言われる...
```Error updating database. Cause: org.postgresql.util.PSQLException: ERROR: null value in column "id" of relation "todos" violates not-null constraint Detail: Failing row contains (null, shopping, 2025-03-20 02:04:51.057386, null, null). ```


# カラムのデータ型が原因
#### Idカラムのデータ型が *bigint* 
```
 Column   |              Type              | Collation | Nullable | Default
------------+--------------------------------+-----------+----------+---------
 id         | bigint                         |           | not null |
 content    | character varying(255)         |           | not null |
 created_at | timestamp(6) without time zone |           |          |
 delete     | timestamp(6) without time zone |           |          |
 done       | boolean                        |           |          |
 ```

 # データ型をSERIALに変更
 ```
 # 既存の主キー制約の削除
ALTER TABLE todos DROP CONSTRAINT todos_pkey;
  ```

  ```
  # SERIALと主キーを持つ新しいidカラムを追加
 ALTER TABLE todos ADD COLUMN id SERIAL PRIMARY KEY;
  ```

  ```
   Column   |              Type              | Collation | Nullable |              Default
------------+--------------------------------+-----------+----------+-----------------------------------
 content    | character varying(255)         |           | not null |
 created_at | timestamp(6) without time zone |           |          |
 delete     | timestamp(6) without time zone |           |          |
 done       | boolean                        |           |          |
 id         | integer                        |           | not null | nextval('todos_id_seq'::regclass)
 ```

 #### nextval('todos_id_seq'::regclass) とは??
 > PostgreSQLでは、nextval('sequence_name')はシーケンスから次の値を取得するため

```nextval('todos_id_seq')``` :  todos_id_seqシーケンスから次の数値を取得
```'todos_id_seq'::regclass ```: todos_id_seqをシーケンスオブジェクトとして扱うようPostgreSQLに指示
 
 
### Thank you AI:writing_hand_tone1:
【備忘録】jmeterを使ってみる

jmeterを使ってみます。
今回はapi実行のみを対象に使ってみます。

###  インストール
ググったら出てくる記事を参考にインストールできました。
参考：https://baremetal.jp/blog/2022/12/27/1241/
</br>

### サンプルプロジェクトの用意
適当にREST APIのプロジェクトを用意します。
今回はタスクテーブルからタスクIDを指定して取ってくるAPIを使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920773/f70770a1-d6fb-4818-b959-ef9faa3f24f6.png)

### コンポーネントの追加
今回は以下のコンポーネントを使いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920773/c6e24c4a-b7a2-4050-b0f5-7317211fdb78.png)


### スレッドグループのプロパティに値を入れる
適当に入れてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920773/c77b622b-6057-4067-b325-36546f343abb.png)

### http requestの設定
適当に入れてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920773/514b7d34-d067-4c52-960a-ccbbddc6013f.png)


### 結果の確認
なんかいろいろ書いてあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920773/e864476b-f783-4ac8-98cf-5f69b47dfbbb.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920773/fc5e7935-397b-4d3d-b0e7-be51b1307919.png)


### 実際は
データ量、データ分布、同時接続数など色々なパラメータを考慮して、シナリオを組むことになるでしょう。
テストの計画、実施は勉強して出直します。
SimBAのインストール手順とトラブルシューティング

## SimBAのインストール手順とトラブルシューティング

自宅のハムスターたちの行動を解析して見るために、SimBAという解析ツールを使ってみます。
は動物行動解析ツールであり、Python環境を使用して動作します。
自分用インストール記録のメモです。


### **1. Conda環境の準備**

SimBAはPython 3.6環境で動作します。まず、Condaを使用して専用の環境を作成します。

```bash
conda create -n simba_env python=3.6 -y
conda activate simba_env
```


### **2. 必要なライブラリのインストール**

SimBAが依存するライブラリを`pip`でインストールします。

```bash
pip install simba-uw-tf-dev opencv-python==3.4.5.20 shapely pyparsing==2.4.7
```


### **3. Condaチャンネルの設定**

Condaのチャンネル優先度を設定します。

```bash
conda config --add channels defaults
conda config --add channels conda-forge
conda config --set channel_priority flexible
```


### **4. FFMPEGのインストール**

SimBAはFFMPEGが必要です。Linuxの場合、以下のコマンドでインストールしてください。

```bash
sudo apt install ffmpeg
```


### **5. SimBA GUIの起動**

インストールが完了したら、以下のコマンドでSimBAのGUIを起動します。

```bash
simba
```

---

## インストール時に発生した問題とその解決法

### **問題1: Conda環境で"PackagesNotFoundError"が発生**

**原因:** `anaconda`パッケージが現在のチャンネルから利用できないため。
**解決法:** `anaconda`を指定せずに環境を作成することで解決しました。

```bash
conda create -n simba_env python=3.6 -y
```

---

### **問題2: Shapely関連エラー**

**原因:** Shapelyが正しくインストールされていない場合、SimBAが起動しないことがあります。
**解決法:** 以下のコマンドでShapelyを再インストールしました。

```bash
pip uninstall shapely
conda install -c conda-forge shapely
```

---

### **問題3: FFMPEGが見つからないエラー**

**原因:** FFMPEGがシステムにインストールされていない場合、このエラーが発生します。
**解決法:** Linuxの場合、以下のコマンドでFFMPEGをインストールしました。

```bash
sudo apt install ffmpeg
```

---

### **問題4: 入力ディレクトリと出力ディレクトリが同じ場合のエラー**

**原因:** SimBAでは入力ディレクトリと出力ディレクトリを同じフォルダに設定するとエラーになります。
**解決法:** 入力ディレクトリと出力ディレクトリを別々に設定することで解決しました。

---

以上でSimBAのインストールとトラブルシューティングは完了です。問題が発生した場合は、エラーメッセージに従って適切に対処してください。
iexでモジュールを含んだファイル内の関数の実行方法

# はじめに
elixirを扱う際にphoenixを用いたアプリケーション開発はよく用いられる。
またlivebookを利用し、iexでコードの実行することもよくある。
しかしファイルを作成し、そのファイルに必要なモジュールをインポートして実行する方法については意外にも知見が少なくわかりずらい。
そこで当記事ではモジュールを作成したファイルとそのモジュールを活用したコードを作成し、それを動作することを目指す

# 大まかな流れ
.exファイルと.exsファイルを作成しそれぞれをコンパイルしてからiexで実行をする
今回はjsonを利用する
また.exファイル内は検証のためにライブラリを使用しない関数と使用する関数を作成する

# 実際の流れ
sample.exsの作成
```elixir
Mix.install([
  {:jason, "~> 1.2"}
])
```

sample.exの作成
```elixir
defmodule Test do
  def sum(x, y) do
    x + y
  end

  def decode() do
    Jason.decode("{}")
  end
end
```

これらを作成した段階で
```elixirc sample.ex```
```elixir sample.exs```
のコマンドを実行する
iex実行時には```iex test.exs```と実行する。
これを実行することでコンパイルが行われ、iex上で利用が可能となる。

検証
Test.sum()で
```elixir
Test.sum(5, 2)
```
7が

Test.decode()で
```elixir
Test.decode("{}")
```
{:ok, %{}}が結果として返ってくるのがわかる

decodeの結果についてはドキュメントを参考に
https://hexdocs.pm/jason/Jason.html#decode/2

# 終わりに
シンプルな内容ではあるがとっさに作り方がわからず調べる羽目になったため今回の記事を執筆するに至った。
この記事がelixirを勉強されている方のお役に立てば幸いです。
M2 MacBook AirでGemma3 1bを動かしてみる

オープンソースでものすごい大規模言語モデルキターーと噂のGoogle謹製 Gemma3を試してみました。
参考：https://huggingface.co/blog/gemma3

# まずはLLM実行ツール：Ollamaインストール
ローカル環境で大規模言語モデル(LLM)を実行するためのツールだと以下が有名です
- Ollama
- LM Studio
- ​Llama.cpp

どれを使っても良いですが、セットアップが簡単で、軽量、CUIに抵抗がないので今回は**Ollama**を使います。

GUIで使いたい場合はLM Studioがいいと思います。M2 MacBook Airでも動きます。

[Ollamaの公式サイト](https://ollama.com/download)からダウンロードして、インストールしてください。ダウンロードしたファイルをクリックするだけで簡単にインストールできるはずです。
インストールの画面を進めていくと、なぜかDeep Sheekを入れるようにお薦めしてくれますが今回は遠慮してそっと閉じます。
インストールができたら、ラマの可愛いアプリアイコンをクリックして起動しておいてください。

# Gemma3をダウンロード
早速、Gemma3をダウンロードします。
[OllamaのGemma3のページ](https://ollama.com/library/gemma3:1b)に、ダウンロードのコマンドが載っています。
コピペしてターミナルに貼り付けてダウンロードしましょう。
私は一番軽量なモデルで試したかったので1bを選びました。

```terminal
ollama pull gemma3:1b
```
Gemma3は、1B、4B、12B、27Bの4つのモデルサイズがあります。
​1Bモデルはテキストのみの処理に対応していますが、4B、12B、27Bはテキストと画像の両方を扱う機能を備えています。

他の方が4bを入れて画像の認識MacBook Airで使って画像認識を試されているので、4bでも良かったかも。

参考：
https://qiita.com/7shi/items/c0255409aa28c1b2e1a0
https://qiita.com/momoooo/items/2a324983dae83bf68bcb

# Gemma3を起動

```terminal
ollama run gemma3:1b
```

起動したら入力プロンプトが起動するのでいつも通りChatGPTにプロンプトを打ち込むようにしてお使いください。

![スクリーンショット 2025-03-20 12.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262827/7f479e2b-ce6c-400a-b649-54fa4457887a.png)

パーソナル設定もできるみたいですごいですね。1bなのに回答速度も早かったです。


# 補足：LM Studioで4bを入れてみた。
LM Studioも使ってみようと思い、インストールしてみました。
https://lmstudio.ai/

インストールの手順はOllamaと変わらないです。
なぜかLM StudioもDeep Sheekを最初のモデルとしてお勧めされます。閉じても開き直すと復活するのですが右上にわかりにくい感じでSkipがあったのでそれで華麗にスルーしました。

4bを入れようと思ったのですが、真面目に色々よくみると4bにも色々なモデルがあり、Instruction-Tuned（命令チューニング済み）で、少しで絵も軽量な量子化しているものが良かったので[unsloth/gemma-3-4b-it-GGUF](https://huggingface.co/unsloth/gemma-3-4b-it-GGUF)を選択しました。

- LM StudioやOllamaは、llama.cppベースのツールなので、GGUF形式のモデルをそのままロード＆実行できるので-GGUFがついているモデル
- Instruction-Tunedの印である-itがついているモデル

モデルの切り替えがしやすいし、モデルの検索や、管理もしやすくてLM Studioも最高ですね。特に動作が不安定になるということもありませんでした。
まだそこまで使っていないので断定はできませんが、1bとの違いはよくわからないです。4bだと画像の判定ができるというところが違うだけでしょうか。

HuggingfaceのサイトでGemma3にレシートを読み込ませていたので、やってみました。
![スクリーンショット 2025-03-20 11.48.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262827/98c18d79-fc04-41f4-bef8-fd8c379cab43.png)

画像の認識で、これぐらい鮮明だと文字の読み取りはパーフェクトでした。すごい。
この後、ナイキのスニーカーの画像を読み取らせていた人がいたので、オニツカタイガーの画像を読み込ませてみましたがアシックスと回答していました。アシックス知ってるんだ。すごい。

回答生成まで5秒程度で、MacBook Airが暑くなる等の問題もなく、Chromeと20個ぐらいタブを開いていても、VS Codeを開いていても挙動に問題はなかったです。

ただ画像の読み取りは鮮明ではない書類だと20秒ぐらいかかるのに間違っていました。

Ollamaは画像の指定をパスで行うのですが、LM Studioだと、画像の指定もぽちぽちするだけなので、楽ですね。
PHPで「foreach文でキーと値を取り出す」の動作を確認してみた。

# 概要

PHPで「foreach文でキーと値を取り出す」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/php/for/index9.html

# 実装

以下のファイルを作成しました。

```sample.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
<?php
$preflist = array('Tokyo' => '東京', 'Osaka' => '大阪');

foreach ($preflist as $key => $value){
  print $key.'=>'.$value.'<br />';
}
?>
</p>

</body>
</html>
```

以下のコマンドを実行しました。

```
$ php sample.php 
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
Tokyo=>東京<br />Osaka=>大阪<br /></p>

</body>
</html>
```

# まとめ

何かの役に立てばと。
Uncaught TypeError: self.crypto.randomUUID is not a functionの原因と対処法

## エラーの内容
JavaScriptで`crypto.randomUUID()`を使用してuuidを生成しようとした際、以下のエラーが発生しました。ここではその原因と対策を記録しておきます。
```javascript
Uncaught TypeError: self.crypto.randomUUID is not a function
```

## エラーの発生状況
このエラーがテストページでのみ発生していたため、不思議に思って検証したところ、HTTPS環境で実行した場合は発生しないが、HTTP環境では発生するという特徴がありました。

## そもそもcryptoとは

>Crypto インターフェイスは、現在のコンテキストで利用できる基本的な暗号機能を表します。 これは、暗号強度の強い乱数生成器と暗号プリミティブへのアクセスを許可します。

[MDN: Crypto](https://developer.mozilla.org/ja/docs/Web/API/Crypto)

`crypto`はJavaScriptの組み込みオブジェクトで、暗号関連の機能を提供してくれます。その中の`randomUUID()`メソッドは、HTTPS環境またはlocalhostのようなセキュアコンテキストでのみ利用可能な仕様になっているそうです。

## 対処法
### HTTPS通信を使用する
特別な理由がない限り、HTTPS通信を使用するのが適切です。ローカル環境では、`http://localhost`を使用していればエラーは発生しません。

一応、乱数を組み合わせるなどして無理やりuuidを自作することも可能ですが、そもそもHTTP通信しかできない環境でuuidを扱うべきではないと思われます。
TypeORM マイグレーション自動生成しようとしたら `No changes in database schema were found` というエラーが出る

## 前提

- **Node.js**: v22.13.1
- **TypeScript**: Version 5.8.2
- **TypeORM**: 0.3.21
- **ts-node**: 10.9.2

## 事象

以下のコマンドを実行して、エラーが発生した：

```sh
npx typeorm-ts-node-commonjs migration:generate src/migration/CreateDrugTable -d src/data-source.ts
```

エラーメッセージ：

```plaintext
No changes in database schema were found - cannot generate a migration.
To create a new empty migration use "typeorm migration:create" command
```

## 原因

このエラーの主な原因は、`synchronize: true` が設定されていたことです。`synchronize: true` にすると、TypeORM はアプリケーション起動時にデータベーススキーマを自動で更新します。この設定により、エンティティの変更が自動的にデータベースに反映され、不要な変更がログとして残ります。そのため、マイグレーションの自動生成時に変更が見つからず、エラーが発生することがあります。

## 解決策

エラーを解決するためには、`synchronize: false` に設定を変更した上で、データベーススキーマをリセットすることが必要です。以下の手順で問題を解決できます。

### 手順

1. **`data-source.ts` の設定確認**

   `data-source.ts` で `synchronize: true` が設定されていた場合、まずこれを `false` に変更します。これにより、データベーススキーマの自動更新を無効にします。

   ```ts
   const AppDataSource = new DataSource({
     type: "mysql",
     host: "localhost",
     port: 3306,
     username: "root",
     password: "password",
     database: "mydb",
     synchronize: false,  // この設定が重要
     entities: [Drug, User],
     migrations: ["src/migration/**/*.ts"],
   });
   ```

2. **データベーススキーマをリセット**

   次に、データベーススキーマをリセットします。`synchronize: false` の設定により、データベースの変更が自動的に反映されなくなりますが、既存のスキーマをリセットするためには手動でスキーマを削除します。

   ```sh
   npx typeorm schema:drop -d src/data-source.ts
   ```

3. **マイグレーションの再生成**

   データベーススキーマをリセットした後、再度マイグレーションを生成します。

   ```sh
   npx typeorm-ts-node-commonjs migration:generate src/migration/CreateDrugTable -d src/data-source.ts
   ```

これで、マイグレーションが正常に生成されるはずです。

## まとめ

`No changes in database schema were found` エラーが発生する場合、`synchronize: true` 設定が影響している可能性があります。この場合、以下の手順で問題を解決できます。

1. `synchronize: false` に設定を変更。
2. `npx typeorm schema:drop -d src/data-source.ts` でデータベーススキーマをリセット。
3. 再度、マイグレーションを生成。

これで、マイグレーションの自動生成が正常に動作するようになります！🚀
Power Appsで位置報告アプリ

## 緒言
以前投稿した[こちら](https://qiita.com/meccha__eeyan/items/6425fcc6786da011e56d)の記事の応用で出勤時等の位置報告アプリを作成しました。フリーアドレスの自席共有や会議室等のリソース予約などに使えそうかなと思います。

動作イメージはこんな感じ。

https://x.com/meccha__eeyan/status/1898673537260683612

## 中身
https://github.com/minoru365/WorkAttendanceInfo

データソースのSharePointリストは下図の2つで極力シンプルに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/3eabfb51-398d-4b40-962b-99427233b28a.png)


## 工夫したポイント
### 過去のレコードクリア
Power Automateなどで過去分クリアするのではなく更新日時でフィルタして非表示。
```
Filter(WorkAttendanceInfo,更新日時>Today(),Floor.Value=DropdownSelectImage.Selected.タイトル)
```

### 入力ボックスのポップアップ
枠からはみ出さないようにX、Yの数式を工夫
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/4a11ce4d-41bb-4842-b2e7-e3a401c0212d.png)
家計簿アプリを作る＃１９

![スクリーンショット 2025-03-20 092531.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/1780acff-dbee-4b4c-81d4-838c2baa01ff.png)
＜List＞の中では、配列の中身をmap関数で、一つ、一つ展開して、ListItem（Liタグのようなもの）の中で表示してます。

![スクリーンショット 2025-03-20 092818.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/337349c7-f82d-4eb8-8ec3-94e35e7fed76.png)
＜Divider /＞は↓の斜線になります。
![スクリーンショット 2025-03-20 092921.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/bb4c0029-78f7-40ad-a829-5f743a9c20fd.png)
AWSでドメイン取得と証明書発行とALBへのルーティング設定

忘れそうなので忘備録として

## 目標
Route53で独自ドメイン`sample.com`を取得し`https://test.sample.com/`へのインターネットアクセスがALBに到達すること

## 手順

### 1. Route53でドメインを取得
1. `ドメインを登録`から`sample.com`ドメインを検索、選択しチェックアウトへ
    1. 最低1年から期間を選択できます
    1. 自動更新をオンにすると期間が自動で更新されます
        1. コンソールからいつでもオフに変更可能
        1. 有効期限が切れる前に、自動更新がオンであることを知らせるメールが届きます
1. 連絡先情報を入力して送信
1. 数分から数十分程度で登録したメールアドレスへドメイン取得完了のメールが届き完了

### 2. Certificate Managerで証明書の発行
1. Certificate Managerコンソールの`リクエスト`から証明書のリクエストを行う
    1. 証明書タイプ : `パブリック証明書をリクエスト`
    1. 完全修飾ドメイン名 : `test.sample.com`
    1. 検証方法 : `DNS検証`
    1. キーアルゴリズム : `RSA 2048`
2. 全て入力しリクエスト
    2. この状態ではまだ証明書のステータスが`保留中の検証`のままです

### 3. Route53でDNS検証を行う
1. 作成した証明書の詳細画面で`ドメイン` > `Route53でレコードを作成`
    1. これによりRoute53でDNS検証を行うためのCNAMEレコードがホストゾーン`sample.com`に追加されます
2. 数分程度で証明書のステータスが`発行済み`になります

### 4. ALBの設定
1. 未作成の場合はコンソールから`ロードバランサーの作成` > `Application Load Balancer を作成`で作成
1. `リスナーとルーティング`から`HTTPS:443`で転送先のターゲットグループを選択
1. `セキュアリスナーの設定`
    1. セキュリティポリシー : 特に指定なければデフォルト値のまま
    1. デフォルト SSL/TLS サーバー証明書 : 
        1. 証明書の取得先 : `ACMから`
        1. 証明書(ACMから) : `test.sample.com`
1. その他ALBの必要な設定を行いロードバランサーの作成または更新
![スクリーンショット 2025-03-16 20.17.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1640807/a07af141-32f9-4623-823c-936fa0febdff.png)
![スクリーンショット 2025-03-16 20.18.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1640807/9e16491b-b3bc-44f2-b89f-21f5c57350c9.png)

### 5. Route53 -> ALBのルーティング設定
1. Route53のコンソールから`ホストゾーン` > `sample.com` > `レコードを作成`でルーティング用のAレコードを作成
    1. レコード名 : `test.sample.com`
    1. レコードタイプ : `A - IPv4アドレスと一部のAWSリソースにトラフィックをルーティングします。`
    1. エイリアス : `オン`
    1. トラフィックのルーティング先 : `Application Load BalancerとClassic Load Balancerへのエイリアス`
    1. ルーティングポリシー : `シンプルルーティング`

以上の設定により、インターネット経由での`https://test.sample.com/`へのトラフィックをALBに紐付けターゲットグループへ転送することができるようになりました。
【試験対策】内部不正による情報漏えいとは？手口・影響・対策をわかりやすく解説！

✅ はじめに
内部不正による情報漏えいは、企業内部の従業員や関係者が意図的・または過失によって情報を外部に流出させる行為です。
外部からのサイバー攻撃だけでなく、内部のリスク管理 も重要視されており、応用情報技術者試験でも頻出のテーマです。

本記事では、
✅ 内部不正の主な手口
✅ 被害の影響
✅ 具体的な対策方法
✅ 応用情報技術者試験での出題ポイント
を整理しました。

試験対策だけでなく、実務でも役立つ内容なので、ぜひ最後まで読んでください！

⸻

📌 内部不正による情報漏えいとは？
🔹 攻撃の概要
内部不正とは、企業の従業員や元従業員、取引先などの関係者が、意図的・または過失によって情報を漏えいさせる行為です。
攻撃者は 「企業のシステムやデータにアクセスできる権限を持っている」ため、外部攻撃よりも検知が難しいのが特徴です。

🔹 代表的な手口
| 手口の種類 |攻撃の内容 |
|:-:|:-:|
| 持ち出し（USB・メール・紙）  | 機密情報をUSBやメールで持ち出し、外部に流出させる  |
|不正アクセス   | 権限を悪用して、機密情報や顧客データを盗み出す  |
| 退職時のデータ持ち出し  | 退職者が顧客情報や営業機密を持ち出し、競合企業に提供する |
|権限の悪用   | 管理者権限を使い、不正にデータを操作・削除する  |
| ソーシャルエンジニアリング  |従業員を騙してパスワードを聞き出し、不正アクセスを行う  |

📌 被害の影響
内部不正が発生すると、企業は以下のような深刻な被害を受けます。
	•	顧客情報や機密情報の流出（信用低下・法的責任）
	•	競合企業への情報漏えい（事業戦略・技術の流出）
	•	業務停止・金銭的損失（システム破壊・取引先からの信頼喪失）
	•	企業のブランドイメージの損傷（炎上・メディア報道）

⸻

📌 具体的な対策方法
🔹 1. アクセス権限の適正化
✅ 最小権限の原則（Least Privilege）を徹底
	•	必要最低限の権限のみ付与し、全員に管理者権限を与えない
	•	定期的に権限を見直し、不要な権限は削除

🔹 2. ログ監視と異常検知
✅ SIEM（Security Information and Event Management）を活用
	•	ユーザーのアクセスログを監視し、**異常な行動（大量データ持ち出し・深夜アクセスなど）**を検知
	•	**機械学習による異常行動分析（UEBA：User and Entity Behavior Analytics）**を導入

🔹 3. データ持ち出し対策
✅ 持ち出しを制限し、データ流出を防ぐ
	•	USBメモリや外部ストレージの使用を禁止
	•	メール送信時の添付ファイル制限（暗号化・承認制）
	•	印刷制限（機密情報の紙媒体化を防ぐ）

🔹 4. 退職者・異動者のアカウント管理
✅ 退職・異動時には速やかにアカウント削除
	•	退職前に重要データのアクセス履歴を確認
	•	退職後もアカウントが残らないよう、定期的に削除確認

🔹 5. 社員教育の徹底
✅ 内部不正を防ぐために従業員の意識向上
	•	セキュリティ研修を実施（情報漏えいの事例・対策）
	•	内部告発制度を整備（匿名で不正を通報できる仕組み）

⸻

📌 試験での出題ポイント

✅ 記述問題の対策
午後試験では、「内部不正の手口・影響・対策」を論理的に説明できるかが問われます。
以下のような問題が出る可能性が高いため、事前に練習しておきましょう。

Q1. 内部不正による情報漏えいの特徴を説明せよ。
解答例:
内部不正は、企業内部の従業員や元従業員、取引先が、意図的または過失により情報を外部へ漏えいさせる行為である。
攻撃者は正規のアクセス権限を持つため、不正を検知しにくいという特徴がある。

Q2. 内部不正による情報漏えいの影響とその原因を説明せよ。
解答例:
例えば、従業員が退職時に顧客リストを持ち出し、競合企業に提供するケースがある。
このような問題は、アクセス権限管理の不備や、データ持ち出し制限の欠如が原因で発生する。

Q3. 内部不正を防ぐための効果的な対策を2つ挙げ、それぞれの理由を説明せよ。
解答例:
	1.	最小権限の原則を徹底する
	•	不要な権限を持たせないことで、従業員が意図的・過失的に情報を漏えいするリスクを減らせる。
	2.	SIEMを活用したログ監視を行う
	•	ユーザーの異常行動をリアルタイムで検知し、内部不正の兆候を早期に発見できる。

⸻

✅ まとめ
	•	内部不正とは、企業の従業員や関係者が意図的・過失により情報を漏えいさせる行為
	•	持ち出し・不正アクセス・退職時のデータ流出・権限悪用が主な手口
	•	対策として「アクセス権限管理・ログ監視・データ持ち出し制限・退職者管理・社員教育」を徹底
	•	試験では「手口・影響・対策」をセットで理解し、記述問題に対応できるようにする！
Linux入門：/etc/sudoers.d/ ディレクトリと sudoers ファイルの優先度について

## はじめに
Linux システムでは、`sudo` コマンドを利用して特定のユーザーに管理者権限を付与することができます。

:::note info
**その権限管理を行う主要なファイルが `/etc/sudoers` であり、追加の設定を格納するディレクトリとして `/etc/sudoers.d/` も存在します。**
:::

本記事では、これらの設定の優先度について詳しく解説します。

## 書こうと思ったきっかけ
`/etc/sudoers.d/` と `/etc/sudoers` のどちらの設定が優先されるのか疑問に思ったため、整理しておくことにしました。

システム管理を行う上で、誤った設定によって `sudo` コマンドが正しく動作しなくなるリスクを避けるためにも、適切な管理方法を理解することが重要です。

## 優先順位のルール
`/etc/sudoers` ファイルと `/etc/sudoers.d/` ディレクトリの読み込み順序は以下の通りです。

1. **`/etc/sudoers` ファイルが最初に読み込まれる。**
2. **`/etc/sudoers` 内の `#includedir /etc/sudoers.d` ディレクティブによって、 `/etc/sudoers.d/` 内のファイルが追加で読み込まれる。**
3. **`/etc/sudoers.d/` にあるファイルは、辞書順（アルファベット順）で読み込まれる。**  
   - 例: `00-custom` → `10-admin` → `99-user` の順で適用。
4. **後から読み込まれた設定が優先されるため、 `/etc/sudoers.d/` にあるファイルの内容が `/etc/sudoers` の設定を上書きすることが可能。**

## 備忘録メモ
`/etc/sudoers.d/` のファイルは `/etc/sudoers` の後に読み込まれるため、**原則として `/etc/sudoers.d/` に書かれた設定が優先されます。

** ただし、`/etc/sudoers.d/` にあるファイルの内容が適切でない場合（文法ミスなど）、`sudo` の動作が正しく機能しなくなる可能性があるので注意が必要です。

## **確認方法**
現在の `sudo` 設定が正しく機能するかを確認するために、以下のコマンドを実行してください。

```bash
sudo visudo
```

このコマンドを実行すると、`sudo` 設定の構文チェックが行われ、エラーがある場合は警告が表示されます。

## **注意点**
- `sudoers` ファイルや `/etc/sudoers.d/` 内のファイルを編集する際には、必ず `visudo` コマンドを使用してください。
- `/etc/sudoers.d/` 内のファイルを管理する際には、ファイル名の命名規則に注意し、適切な順序で適用されるように設計しましょう。
- 重大なミスを防ぐために、新しいルールを適用する際には `sudo visudo -c` を実行して事前にチェックすることを推奨します。

## まとめ
`/etc/sudoers` は最初に読み込まれ、次に `/etc/sudoers.d/` ディレクトリ内のファイルが辞書順で適用されます。

:::note info
**そのため、`/etc/sudoers.d/` 内のファイルに後から書かれたルールが `/etc/sudoers` の設定を上書きすることができます。**
:::

しかし、誤った設定があると `sudo` の動作に影響を与える可能性があるため、`visudo` コマンドを活用して設定を適切に管理することが重要です。

適切な `sudo` 設定を行い、安全なシステム運用を心がけてください！
Proxy

Proxyは代理人となってインスタンスの処理を肩代わりすることができる。subjectインターフェースを作ってProxyクラスとRealsubjectクラスが継承する。ProxyクラスがRealsubjectクラスの処理を一部肩代わりして、できないときはRealsubjectに委譲する。こうすることで重い処理で処理時間がかかる時に時短することができる。
最近チェックしたAIコーディング系の記事メモ

まずはメモ。自分にメリットがあるかも合わせて書いている。

## 全体

ここら辺を見ながらCLINEを触っていけば自分の手の内化ができそう。[AIコーディングのプラクティス](https://zenn.dev/devneko/scraps/f79aaba14f8868)でまとめられている記事を中心に見ていく。

- [わざわざ言語化されないClineのコツ](https://zenn.dev/watany/articles/85af6cfb8dccb2)
    - Claude 3.7がおすすめ、メモリバンクを使え、という記事。
- [CLINEに全部賭けろ](https://zenn.dev/mizchi/articles/all-in-on-cline)
    - 文章メイン。メモリバンクについて著者は懐疑的。
- [Cline+Claudeでの開発を試してみた感想](https://zenn.dev/razokulover/articles/768337f838a110)
    - .clinerulesの例と作成方法、CLINEへの依頼方法あり。★お役立ち
- [$100燃やして分かったClineのTips](https://zenn.dev/watany/articles/50665ee40f4948)
    - Plan/Actの使い方など、実際に進めていく中でのナレッジあり。★お役立ち
- [AIをシステム開発に活かすコツ、全部書く｜kmagai](https://note.com/kmagai/n/n9c78650645f9)
    - 仕様書をしっかり書く、AIに理解してもらいやすいようmarkdownで書き、ダイヤグラムはmermeidで書く。仕様書の置き場所をAIに伝える(.clinerulesで参照させる)
- [AIコーディング時代の開発環境構築：VS Code × Cline（Roo Code）で爆速開発！](https://zenn.dev/mkj/articles/cf8536923d9cd7)
    - .clinerulesの作成方法あり。vscodeの設定から説明しているので、記事が長い割に見るべきところは少ない。★お役立ち
- [Clineに全部賭ける前に　〜Clineの動作原理を深掘り〜](https://zenn.dev/codeciao/articles/6d0a83e234a34a)
    - 動作原理を知りたい時


## メモ

- メモ
    - [ノンプログラマーズ・プログラミング - WIP](https://zenn.dev/mizchi/books/non-programmars)
        - 書きかけで止まっているが、更新されたら読みたいのでメモ
    - [AIエージェント時代のエンジニアになろう #jawsug #jawsdays2025 / 20250301 Agentic AI Engineering Speaker Deck](https://speakerdeck.com/yoshidashingo/20250301-agentic-ai-engineering)
        - AWSイベントの講演資料。資料を読むと「こんなことを話したのだな」という事は分かるが、詳細は分からない。資料だけだと、ありきたりな話＋宣伝に見える
- 文章(いわゆるポエム)
    - [エンジニアに許された特別な時間の終わり - Speaker Deck](https://speakerdeck.com/watany/the-end-of-the-special-time-granted-to-engineers)
        - ロジックで解決できる部分はAIがやり、エンジニアは運と結果責任だけが残る、のか?

## その他

- [【Vercel】v0とは？主要機能や使い方、料金体系を徹底解説！活用事例も紹介 | AI総合研究所](https://www.ai-souken.com/article/what-is-v0-vercel#lp%E4%BD%9C%E6%88%90)
Create and Submit Contracts



https://trailhead.salesforce.com/content/learn/modules/deep-dive-into-salesforce-contracts/create-update-and-manage-contracts-hoc

+ [【ヘルプ】契約の作成と更新のためのコンテキストユースケースマッピング](https://help.salesforce.com/s/articleView?id=ind.sf_contracts_context_use_case_mapping_to_create_and_update_contracts.htm&type=5)

+ [Create and Submit Contracts challenge issue](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000WqNw0AK)


We couldn't fetch the context definision name and its associated mapping name from the Context Use Case Mapping Object.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ffefc910-be29-4de2-8f3b-e191ef559d8d.png)
Visual Studio Code のアクティビティバーを非表示にしたい

# 1. はじめに
* Visual Studio Codeの左にあるアクティビティバーを非表示にしたい
* ステータスバーにアイコンを追加して、必要な時に使えるようにしたい

# 2. 開発環境
* Visual Studio Code
* Windows 11

# 3. アクティビティバーの非表示
## 3.1. ```Ctrl + Shift + P``` をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/4b64ba52-7ac7-4565-ac27-1ab0eb56fd3b.png)

## 3.2. ```表示: アクティビティバーを非表示にする```を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/3506f35c-fd3f-446a-81d3-970db01b9950.png)

# 4. ステータスバーにアイコンを追加
## 4.1. 拡張機能から ```Activitus Bar``` をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/00af7779-2bce-4806-9bf5-f67f2b650c6e.png)

## 4.2. ステータスバーに追加される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/54ecb02a-0bee-4609-ac79-96a44028a512.png)

# 5. （補足）ステータスバーのアイコン追加
## 5.1. ```Activitus Bar``` の設定画面から ```settings.jsonを編集``` をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/4f95441a-dbf9-47fb-b430-c22f3fb719e6.png)

## 5.2. JSONを編集して追加する
* Project Managerのアイコンを追加してみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/8c3fc74a-6ce8-466b-86af-efc5acd7bec4.png)

# 6. 参考文献

https://www.kamo-it.org/blog/vscode-activitybar-setting/