OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScript（ES6〜）演算子と分割代入

## 演算子とは
演算処理を記号やキーワードで表したもの

## 被演算子(オペランド)
演算子によって処理される値
例）`5 + 3`の`5`、`3`の部分
`+`は演算子

## 二項演算子
2つの被演算子を持つ演算子
例）`5 + 3`

二項演算子には下記のようなものがあります
- プラス演算子 ( `+` )
  - `1 + 1` =>`2`
- 文字列結合演算子 ( `+` )
  - `"文字列" + "結合"` =>`"文字列結合"`
- マイナス演算子 ( `-` )
  - `2 - 1` =>`1`
- 乗算演算子 ( `*` )
  - `1 * 1` =>`1`
- 除算演算子 ( `/` )
  - `2 / 2` =>`1`
- 剰余演算子 ( `%` )
  - `8 % 2` =>`0`
- べき乗演算子 ( `**` ) 
  - `2 ** 3` =>`8`

## 単項演算子
1つの被演算子だけを持つ演算子
例）`x = -x;`
被演算子(オペランド)を数値に変換します。ただし、真偽値などを数値のデータ型に変換することはわかりにくいコードになるので、現場では使われないです

単項演算子には下記のようなものがあります
- 単項プラス演算子（ `+` ）
- 単項マイナス演算子 ( `-` )

## 比較演算子
値を比較し、`true`または`false`を返す演算子
現場では厳密等価演算子や厳密不等価演算子がよく使われます
一方、等価演算子や不等価演算子は意図しない挙動をすることがあり、不具合の温床なので、基本的に使われないです
例）`5 == "5"` => `true`
- 厳密等価演算子 ( `===` )
- 厳密不等価演算子 ( `!==` )
- 等価演算子 ( `==` )
- 不等価演算子 ( `!=` )
- 大なり演算子 ( `>` )
- 大なりイコール演算子 ( `>=` )
- 小なり演算子 ( `<` )
- 小なりイコール演算子 ( `<=` )

### 厳密等価演算子 ( === )
同じ型かつ同じ値である場合に`true`を返す演算子
```javascript
console.log(5 === 5);    // true
console.log(5 === "5");  // false
```

### 厳密不等価演算子 ( !== )
同じ型かつ同じ値である場合に`false`を返す演算子
```
console.log(5 !== 5);    // false
console.log(5 !== "5");  // true
```

## ビット演算子
値を2進数で処理する演算子
- ビット論理積（ `&` ）
  - 「両方が`1`のとき`1`になる」AND演算
  - マスク処理やフラグ判定 でよく使われます
- ビット論理和（ `|` ）
  - 「どちらかが`1`なら`1`になる」OR演算
  - ビットをセットする（ONにする）処理で使われます
- ビット排他的論理和（ `^` ）
  - 「異なるビットなら`1`になる」XOR演算
  - 特定のビットを反転させることに使えます
- ビット否定（ `~` ）
  - すべてのビットを反転（NOT演算）
- 左シフト演算子（ `<<` ）
  - ビットを左に`n`ビット移動する演算子
- 右シフト演算子（ `>>` ）
  - ビットを右に n ビット移動する演算子（符号あり）
- ゼロ埋め右シフト演算子（ `>>>` ）
  - 符号なしの右シフト演算子（0 で埋める）

## 代入演算子
変数に値を代入する演算子

## 論理演算子
真偽値（`true`/`false`）を扱う演算子
### AND演算子 ( && )
- 左辺が`false`の場合：右辺を評価せず、左辺の値を返します
- 左辺が`true`で、右辺が`false`の場合：右辺の値を返します
- 左辺と右辺が両方`true`の場合：右辺の値を返します

左辺を評価する際に、真偽値へと暗黙的な変換をしてから判定しています
- falsyな値は`false`
- falsyでない値は`true`
- falsyな値の一覧
    - null
    - undefined
    - false
    - NaN
    - 0
    - 0n
    - “” (空文字列)

```javascript
// 左辺がfalsyな値の時
console.log(0 && "Hello");    // 0
console.log(false && "Bye");  // false

// 右辺がfalsyな値の時
console.log(true && 0);          // 0
console.log(true && null);       // null

// 左辺、右辺両方がtrueの時
console.log(true && 1);         // 1
console.log(true && "Hello");   // "Hello"
```

#### 短絡評価
左辺が`false`の場合、右辺を評価をしないのような値が決まった時点でそれ以上評価しないこと
- 処理効率が向上します

### OR演算子 ( || )
- 左辺の評価結果が`true`の場合：左辺の値を返します
- 左辺の評価結果が`false`の場合：右辺の値を返します

### NOT演算子 ( ! )
真偽値を反転して返す演算子

## 三項演算子
`条件 ? 真の場合 : 偽の場合`のように書ける、簡潔な条件分岐
`const`を使った変数宣言時によく使われます

## グループ演算子
`()`で式をグループ化し、優先順位を変更する演算子
```javascript
const a = 4;
const b = 5;
const c = 6;

console.log(a + b * c); // 34
console.log((a + b) * c); // 54
```

## カンマ演算子
複数の式を評価し、最後の式の値を返す演算子
```javascript
const a = 1;
const b = 2;
const c = (a = a + 1, b = b + 2, a + b); // 複数の式を評価して、最後の式 `a + b` の結果が返される
console.log(c); // 5
```

## 分割代入
配列やオブジェクトの要素を個別の変数に同時に代入する構文
```javascript
const arr = [1, 2, 3];

// 通常の代入
const a = arr[0];
const b = arr[1];
const c = arr[2];

// 分割代入
const [x, y, z] = arr;

console.log(x); // 1
console.log(y); // 2
console.log(z); // 3
```


## まとめ
上記の中からよく使われるものは分割代入、三項演算子、厳密比較、論理演算子です。分割代入や三項演算子は、コードを簡潔にし可読性を高めるため、特に短いコードを書く際に便利です。
JavaScriptで「Numberオブジェクト」の動作を確認してみた。

# 概要

JavaScriptで「Numberオブジェクト」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/javascript/number/index4.html

# 実装

以下の通り実行しました。

![Screenshot from 2025-03-23 11-45-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/a89df28f-1166-4d01-889f-5533371ea438.png)

# まとめ

何かの役に立てばと。
[GitHub]組織内プロジェクトよりブランチをリスト化する

# はじめに
誰がいつ作ったブランチなのかをリスト化したくて調べました。
私と同じ悩みを抱えている方に届けばと思います。

# 環境
GitHubのapiをPythonで実行します。
※Pythonが実行できる環境であれば問題ないです

私は以下の環境で実行しました。

OS：Windows
エディタ：VSCode


# 事前準備

### GitHubのトークンを取得
以下の手順で取得できます。

1. GitHubの[Personal Access Token](https://github.com/settings/tokens)の設定ページにアクセス
1. 「Generate new token」 または 「Fine-grained tokens」 を選択
1. 必要なスコープ (repo または public_repo) にチェックを入れる
1. トークンを生成する

# Pythonコード
以下のPythonのコード「設定」部分を編集することで実行できます。

```python
import requests
from urllib.parse import quote

# 設定（ここだけ編集すれば動く）
GITHUB_TOKEN = "{取得したトークン}"
ORG_NAME = "{組織の名前}"

# ヘッダー
headers = {
    "Authorization": f"token {GITHUB_TOKEN}"
}

# 組織のリポジトリ一覧を取得
repo_url = f"https://api.github.com/orgs/{ORG_NAME}/repos"
repos = requests.get(repo_url, headers=headers).json()

# ユーザーが生成したブランチを収集
user_branches = []

for repo in repos:
    repo_name = repo["name"]
    # 念のためリポジトリ名をURLエンコードしておく
    encoded_repo_name = quote(repo_name, safe="")
    branches_url = f"https://api.github.com/repos/{ORG_NAME}/{encoded_repo_name}/branches"
    branches = requests.get(branches_url, headers=headers).json()

    for branch in branches:
        branch_name = branch["name"]
        # 念のためブランチ名をURLエンコードしておく
        encoded_branch_name = quote(branch_name, safe="")
        commits_url = f"https://api.github.com/repos/{ORG_NAME}/{repo_name}/commits?sha={encoded_branch_name}"
        commits = requests.get(commits_url, headers=headers).json()

        if commits:
            user_branches.append({
                "repo": repo_name,
                "branch": branch_name,
                "author": commits[0]["commit"]["author"]["name"],
                "date": commits[0]["commit"]["author"]["date"]
                })

# 結果を表示
for branch in user_branches:
    print(f"Repo: {branch['repo']}, Branch: {branch['branch']}, Author: {branch['author']}, Date: {branch['date']}")
```
Mattermost セルフホスティング方法 (最短)

# Mattermost

- slack クローン
- OSS

## Discord と比較して

### メリット

- (Discord と同様に) Markdown 記法で書ける

### デメリット

あくまでデフォルト設定, 現時点 (2025/3/23) での話

- webp アニメーションのプレビュー機能はなし (ダウンロードしないと再生できない)
- 画像を複数アップロードしたとき, いい感じに並べてプレビューしてくれない (↓のように並べて表示される)
  ![{7D1FC93F-8C12-45ED-82C6-57C3904255AC}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191898/03e24ccc-36fa-41ee-8530-4ec4158ef93a.png)

## インストール

- 今回は apt でインストール
  - **mattermost 本体に加えて postgres のセットアップも必要**
- docker 版も動作確認したが, WebUI の上部にちょくちょくよくわからないエラーが出るという現象が発生したため, こちらは使用しない.
  ![{27DD6725-A6E4-4D49-89B3-0892DA9881F1}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191898/ef73170b-4650-4f56-bb48-79cfa44e7a91.png)
- 今回は postgres と mattermost は同じサーバーにインストール

### 実行環境

- OS: Ubuntu Server 24.04 LTS
- CPU: 4 vCPU, Skylake 世代
- RAM: DDR4, 8GB
- SSD: 32GB (SATA)
- hostname: mattermost

### インストール手順

#### DB インストール

公式ドキュメント:
- https://www.postgresql.org/download/linux/ubuntu/
- https://docs.mattermost.com/install/prepare-mattermost-database.html

① postgres インストール

```bash
sudo apt install postgresql
```

バージョン 16 がインストールされる.

② データベースとユーザーの作成

```bash
sudo -u postgres psql
```

```sql
CREATE DATABASE mattermost;
\connect mattermost
CREATE USER mmuser WITH PASSWORD 'mmuser-password';
GRANT ALL PRIVILEGES ON DATABASE mattermost to mmuser;
ALTER DATABASE mattermost OWNER TO mmuser;
GRANT USAGE, CREATE ON SCHEMA PUBLIC TO mmuser;
\q
```

`pg_hba.conf` をドキュメントに従って修正する

![{236E9FA0-87E7-4565-9563-B14549EEE667}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191898/2cd747aa-7638-4557-a3cb-a52dcc3096cb.png)

```bash
sudo systemctl reload postgresql.service
```

③ 疎通確認

```bash
psql --dbname=mattermost --username=mmuser --password
```

#### Mattermost インストール

公式ドキュメント:
- https://docs.mattermost.com/install/install-ubuntu.html

① import the new public key

```bash
curl -sL -o- https://deb.packages.mattermost.com/pubkey.gpg |  gpg --dearmor | sudo tee /usr/share/keyrings/mattermost-archive-keyring.gpg > /dev/null
```

② add the Mattermost Server repositories

```bash
curl -o- https://deb.packages.mattermost.com/repo-setup.sh | sudo bash -s mattermost
```

③ mattermost インストール

```bash
sudo apt install mattermost -y
```

10.6.1 がインストールされた.

### セットアップ

① デフォルト設定ファイルをコピペして, 必要箇所を修正する.

```bash
sudo install -C -m 600 -o mattermost -g mattermost /opt/mattermost/config/config.defaults.json /opt/mattermost/config/config.json
```

postgres 接続設定の修正が必須.

```json
"SqlSettings": {
  ...
  "DataSource": "postgres://mmuser:mmuser-password@localhost:5432/mattermost?...",
  ...
}
```

② mattermost 起動

```bash
sudo systemctl start mattermost.service
```

## 動作確認

http://mattermost.local:8065/

にアクセスして, サインイン画面が出れば完了.

![{BF340DE3-75BA-4F3C-B07A-496D9FB5B8DC}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191898/20cdd3f5-d0c5-4b08-8da2-f99d0b4fe263.png)
データベース学習記録

# CRUDとは
**CRUD**とはDB操作の基本的な4つの機能を表す頭字語
1\.Create(作成)
2\.Read(読み取り)
3\.Update(更新)
4\.Delete(削除)

# SQLとは
DBMSに命令を出すための言語。SQLには大きくDDL(データを定義する言語)とDML(データを操作する言語)の2つの言語で構成されている。

```sql
CREATE TABLE テーブル文(
    列名1 列名1に型 (列名1の制約),
    列名2 列名2に型 (列名2の制約),
    列名3 列名3に型 (列名3の制約),
    列名4 列名4に型 (列名4の制約),
```

# DBとは
構造化した情報またはデータの組織的な集合

# RDBMS(リレーショナルデータベース)とは
RDBMSとは最もよく使われているデータベースの一種。
**テーブル**と呼ばれる表の形式でデータを管理している。
**テーブル**をいくつかまとめたものを、**データベース**と呼んでいる。
行は**ロウ(row)**または**レコード(recode)**、列は**カラム(column)**と呼ばれている。
カラムは名前と型から成る。

## MySQLでのSQL文書き方
#### select文
```SQL
select カラム1, カラム2 from テーブル名;
```
:::note
・select文の結果は**テーブル**←(重要)
・selectやfromは大文字でも小文字でも問題ない
・*(アスタリスク)を指定することですべてのカラムを取得することができる
・カラム名は`カラム名`のようにバッククォートで囲むことができる
:::

#### where句
```SQL
select カラム1, カラム2 from テーブル名 where 条件式;
(例1) select ID, Name from city where Name = 'Tokyo';
(例2) select ID, Name from city where Name > 'Y';
(例3) select ID, Name from city where Name <> 'Tokyo';
(例4) select ID, Name from city where Name = 'Tokyo' and ID > 10;
(例5) select ID, Name from city where ID between 10 and 20;
(例6) select ID, Name from city where Name in ('Tokyo', 'osaka');
```
:::note
・where 条件式 ではTrueなら1、Falseなら0となり、条件式が1となるものだけが抽出される。
・文字列に対して大小関係の比較をすると辞書順で比較される。
・照合順序で辞書順を決めることができる。
　→ci(case insensitive)、cs(case sensitive)がある。
・!=と<>はどちらも否定を意味する。
・between A and BはA以上B以下を取得する。
:::

#### like句(あいまいな検索)
```SQL
select * from city where Name like 'to%';
select * from city where Name like '%oky%';
select * from city where Name like 'toky_';
select * from city where CountryCode = 'JPN' order by Population;
select * from city where CountryCode = 'JPN' order by Population limit 5;
```
:::note
・%はワイルドカード文字と呼ばれるもので、0文字以上のどんな文字の代わりにもなる。
・_はワイルドカードの一種で1文字のどんな文字の代わりにもなる。
・order by (カラム名)でカラム名順に並び変えて結果を出力することができる。デフォルトはasc=ascending(昇順)になっているがorder by (カラム名) descと書くことによりdesc=descending(降順)で並び替えて結果を出すことができる。
・limit 件数;と書くと件数分だけ取得することができる。
:::


# SQlite
**SQlite**は、軽量で**ファイルベース**のDB管理システムです。
設定不要で外部のDBサーバに依存せずに動作するため、組み込みアプリケーションや**小規模プロジェクト**に適しています。
ソフトデリート(論理削除)とハードデリート(物理削除)の違いと使い分け

# はじめに

Laravelでデータを削除するとき、`delete()` を呼ぶだけで簡単に削除できますが、  
実は「**ソフトデリート(論理削除)**」と「**ハードデリート(物理削除)**」の2種類があることをご存知でしょうか？

この2つの違いや使い分けを、自分の学習メモとして整理しておきます。

---

# ①ソフトデリート(論理削除)とは？

データベースからレコードを**物理的には削除せず、「削除済み」としてマークする方式**です。

Laravelでは、`SoftDeletes` トレイトをモデルに追加するだけで使えます。

## モデルでの設定

```php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use SoftDeletes;
}
```

## 必要なカラム
マイグレーションでdeleted_adカラムを追加します。

```php
$table->softDeletes(); // datetime型の deleted_at カラムを追加
```

# ②ソフトデリートの操作方法
**1.データの削除（論理削除）**

```php
$post = Post::find($id);
$post->delete();
```
→  実際には削除されず、deleted_at に日時が記録されるだけ。

**2.削除済みデータを取得する**
```php
Post::withTrashed()->get();      // 削除済みも含む
Post::onlyTrashed()->get();      // 削除済みのみ
```

**3.削除を取り消す（復元）**
```php
$post->restore();
```

# ③ハードデリート(物理削除)とは?
データベースからレコードを**完全に削除する方式**です。

**方法1: ソフトデリートを使わずにdelete()**
```php
$post = Post::find($id);
$post->delete(); // 完全削除される
```

**方法2: ソフトデリートモデルでforceDelete()**
```php
$post = Post::find($id);
$post->forceDelete(); // 完全に削除（復元できない）
```

# ④ソフトデリートとハードデリートの比較

![IMG_3733.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/ce573a81-f536-4078-b608-1c324cdb80d9.jpeg)

# ⑤実務での使い分けの目安
- ユーザーや投稿など、将来的に復元の可能性があるデータ
→ **ソフトデリートを使用する**

- ログや一時データなど、完全に消して問題ないデータ
→ **ハードデリートでOK**

# ⑥まとめ
- Laravelでは簡単に「削除の種類」を使い分けられる
- ソフトデリートは SoftDeletes トレイト＋ deleted_at のカラムが必要
- ハードデリートは forceDelete() またはソフトデリート未使用モデルの delete()
- **安全第一の設計をしたいなら、まずはソフトデリートで運用してみるのがベター**
[JavaScript] vanilla JSで Iterator Helpers が試せるラッパーを作ってみた

[Iterator Helpers](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Iterator#イテレーターヘルパーメソッド)がそのうち使えるようになるらしいけど、現時点(2025.3)でvanilla JSでは使えない場合の方が多いので自前で薄ーいラッパーaddHelpers()を作ってみました。
中味がどうなってるか興味があったし、今は使えてない場所でもお手軽に使えるやつが欲しかったのです。
たぶんIterator.from()の車輪の再発明ってことです。

```js:
const addHelpers = iter => ({
  next: () => iter.next(),
  
  [Symbol.iterator]: () => iter,
  
  map: f =>
    addHelpers(
      function* () {
        let index = 0
        for (const value of iter) {
          yield f(value, index)
          index++
        }
      }()
    ),
    
  flatMap: f =>
    addHelpers(
      function* () {
        let index = 0
        for (const value of iter) {
          yield* f(value, index)
          index++
        }
      }()
    ),
    
  filter: f =>
    addHelpers(
      function* () {
        let index = 0
        for (const value of iter) {
          if (f(value, index)) yield value
          index++
        }
      }()
    ),
    
  drop: n =>
    addHelpers(
      function* () {
        let index = 0
        for (const value of iter) {
          if (index >= n) yield value
          index++
        }
      }()
    ),
    
  take: n =>
    addHelpers(
      function* () {
        let index = 0
        for (const value of iter) {
          if (index >= n) return
          yield value
          index++
        }
      }()
    ),
    
  forEach: f => {
    let index = 0
    for (const value of iter) {
      f(value, index)
      index++
    }
  },
  
  reduce: (f, init) => {
    let acc = init
    let index = 0
    for (const value of iter) {
      if (index === 0 && init === undefined) acc = value
      else acc = f(acc, value, index)
      index++
    }
    return acc
  },
  
  toArray: () => [...iter],
  
  every: f => {
    let index = 0
    for (const value of iter) {
      if (!f(value, index)) return false
      index++
    }
    return true
  },
  
  some: f => {
    let index = 0
    for (const value of iter) {
      if (f(value, index)) return true
      index++
    }
    return false
  },
  
  find: f => {
    let index = 0
    for (const value of iter) {
      if (f(value, index)) return value
      index++
    }
    return undefined
  },
})
```
使い方：
イテレーターオブジェクトに addHelpers を適用すると、ヘルパーメソッドが使えるイテレーターオブジェクトが帰ってきます。あとはお好みでメソッドチェーンすればよい。

以下は無限イテレーターをヘルパーメソッド使用可能にし、ある範囲を切り出してmapする例です。

```js:
const countG = n => function*(){
  while(true) yield n++  
}()

console.log(
    addHelpers( countG(1) )  
    .drop(3)          
    .take(7)          
    .map( e => e * 2) 
    .toArray()        
    )  // [ 8, 10, 12, 14, 16, 18, 20 ]
 ```
 これで来たるべきその日のために色々試すことができます。
 
 何か問題があればコメントよろしくお願いします。
S3にリソースをアップロードし、ACMで証明書を取得してCloudFrontで配信する手順

## 概要
備忘録として、Vue.jsで作成した静的サイトをS3にアップロードし、CloudFrontを利用してHTTPSで配信する手順を記載する。ACM（AWS Certificate Manager）でSSL/TLS証明書を取得し、独自ドメインを適用する方法についても残す。

## 前提条件
- Vue.jsのプロジェクトがすでにビルド済みであること（`dist/` ディレクトリが存在する）

---

## 1. Route 53で独自ドメインを取得
### 1.1 ドメインの取得
1. AWSマネジメントコンソールで **Route 53** を開く
2. 「ドメインを登録」をクリックし、希望の独自ドメイン（例: `example.com`）を検索
3. 取得可能であれば購入し、登録を完了する

### 1.2 ホストゾーンの作成
1. Route 53の「ホストゾーン」を開き、「ホストゾーンの作成」をクリック
2. 取得したドメイン（`example.com`）を入力し、作成
3. 作成されたホストゾーンのNSレコードを確認し、ドメインレジストラの設定と一致させる

---

## 2. S3にVueのリソースをアップロード
### 2.1 S3バケットの作成
1. AWSマネジメントコンソールで **S3** を開く
2. 「バケットを作成」をクリックし、以下の設定でバケットを作成する
   - **バケット名**: `example-bucket`（任意の名前）
   - **リージョン**: `us-east-1`（ACMの証明書と合わせるため推奨。東京でもOK）
   - **パブリックアクセスをすべてブロック**: オフ（後でCloudFrontを経由するため）
   - **静的ウェブサイトホスティング**: 有効（CloudFrontを使用するため、インデックスドキュメントを `index.html` に設定）

### 2.2 Vueリソースのアップロード
ローカルでVueプロジェクトの `dist/` ディレクトリをS3にアップロードする。

```sh
aws s3 sync ./dist s3://example-bucket --acl public-read
```

---

## 3. ACMでSSL/TLS証明書を取得
### 3.1 ACMの証明書をリクエスト
1. AWSマネジメントコンソールで **ACM（AWS Certificate Manager）** を開く
2. 「証明書のリクエスト」をクリック
3. **パブリック証明書** を選択し、独自ドメイン（例: `www.example.com`）を入力
4. 検証方法は **DNS検証** を選択
5. Route 53でDNSレコードを作成し、検証を完了させる

---

## 4. CloudFrontの設定
### 4.1 ディストリビューションの作成
1. AWSマネジメントコンソールで **CloudFront** を開く
2. 「ディストリビューションを作成」をクリック
3. **オリジンドメイン** に作成したS3バケットを指定
4. **プロトコル**: `Redirect HTTP to HTTPS`
5. **代替ドメイン名（CNAME）** に `www.example.com` を追加
6. **ACMで取得した証明書** を選択
7. 設定を保存し、CloudFrontディストリビューションを作成

**⚠️ 注意: 代替ドメイン名（CNAME）を設定しないと、CloudFrontで独自ドメインを利用できず、HTTPS証明書エラーが発生する。**

---

## 5. Route 53でDNS設定
### 5.1 Aレコードの追加（エイリアス有効）
1. AWSマネジメントコンソールで **Route 53** を開く
2. 該当するホストゾーンを選択
3. **新しいレコードを作成** し、以下の設定を追加
   - **名前**: `www.example.com`
   - **タイプ**: A
   - **エイリアス**: 有効
   - **ターゲット**: CloudFrontのディストリビューション（例:abcdefg.cloudfront.net.）

### 5.2 ホストゾーンのNSレコードを確認
取得したドメインのNS（ネームサーバー）と、Route 53のホストゾーンのNSが一致しているかを確認する。

**⚠️ 注意: NSレコードが一致しないと、DNSが正しく機能せずCloudFrontにアクセスできない。**

---

## 6. 動作確認
1. ブラウザで `https://www.example.com` にアクセス
2. Vueのサイトが正しく表示されることを確認

---

## まとめ
本記事では、S3にVueのリソースをアップロードし、CloudFrontを利用してHTTPSで配信する手順を説明した。特に以下の2点が重要である。

1. **CloudFrontの代替ドメイン名（CNAME）を正しく設定すること**
   - 設定しないとHTTPS証明書の適用ができず、独自ドメインでアクセスできない
2. **Route 53のホストゾーンのNS設定を確認すること**
   - 取得したドメインのNSと一致していないと、DNSが機能せずCloudFrontにアクセスできない
AdGuard HomeをOpenWrtにインストールするまで

# 筆者について

```
name → Koki Teramoto
age → 18
language → ja_JP, en_US
```

# 本編

題名の通りです。AdGuard HomeをOpenWrtにインストールしていきます。今回は公式Wikiを参考にしました。

https://openwrt.org/docs/guide-user/services/dns/adguard-home

## インストール

コマンドで一発ですね！ここがOpenWrtのいいところ。

```zsh
opkg update
opkg install adguardhome
```

インストールが終わったらそのままサービスだけ起動しときます。

```zsh
service adguardhome enable
service adguardhome start
```

## 設定

もう本当に公式Wikiのままでした。とりあえず変数だけ設定しておきましょう。

```zsh
NET_ADDR=$(/sbin/ip -o -4 addr list br-lan | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1]; exit }')
NET_ADDR6=$(/sbin/ip -o -6 addr list br-lan scope global | awk '$4 ~ /^fd|^fc/ { split($4, ip_addr, "/"); print ip_addr[1]; exit }')
echo "Router IPv4 : ""${NET_ADDR}"
echo "Router IPv6 : ""${NET_ADDR6}"
```

次にOpenWrtに内蔵されているDNSをのポートを変更し、不必要な設定を削除します。

```zsh
# 1. Move dnsmasq to port 54.
# 2. Set local domain to "lan".
# 3. Add local '/lan/' to make sure all queries *.lan are resolved in dnsmasq;
# 4. Add expandhosts '1' to make sure non-expanded hosts are expanded to ".lan";
# 5. Disable dnsmasq cache size as it will only provide PTR/rDNS info, making sure queries are always up to date (even if a device internal IP change after a DHCP lease renew).
# 6. Disable reading /tmp/resolv.conf.d/resolv.conf.auto file (which are your ISP nameservers by default), you don't want to leak any queries to your ISP.
# 7. Delete all forwarding servers from dnsmasq config.
uci set dhcp.@dnsmasq[0].port="54"
uci set dhcp.@dnsmasq[0].domain="lan"
uci set dhcp.@dnsmasq[0].local="/lan/"
uci set dhcp.@dnsmasq[0].expandhosts="1"
uci set dhcp.@dnsmasq[0].cachesize="0"
uci set dhcp.@dnsmasq[0].noresolv="1"
uci -q del dhcp.@dnsmasq[0].server
uci -q del dhcp.lan.dhcp_option
uci -q del dhcp.lan.dns
```

DNS設定を指定しておく。

```zsh
uci add_list dhcp.lan.dhcp_option='3,'"${NET_ADDR}"
uci add_list dhcp.lan.dhcp_option='6,'"${NET_ADDR}"

# ここはオプション。正味どっちでもいい。
uci add_list dhcp.lan.dhcp_option='15,'"lan"
uci add_list dhcp.lan.dns="$NET_ADDR6"

uci commit dhcp
```

最後にリスタートします。

```zsh
service dnsmasq restart
service odhcpd restart
exit 0
```

という下記にならないのであればしょうみそのままポート変更さえしておけばあとは放置でもいいと思います。

## GUI設定

それでは、`http://192.168.1.1:3000/`にアクセスしましょう。するとWebで色々設定できると思います。Webのポートは`8080`に設定しています。また、DNSのポートは`53`に設定しておいてください。すると設定画面は以下の通りになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/c6ed392b-91c6-4c61-91e9-96e8ce4a8602.png)

## DNS設定

フォワード先のDNSを設定する必要があります。僕は以下のサーバーを指定しました。

- `1.1.1.1`
- `1.0.0.1`
- `https://cloudflare-dns.com/dns-query`
- `https://dns10.quad9.net:443/dns-query`
- `8.8.8.8`
- `8.8.4.4`

また`Parallel requests`にしています。

# 最後に

今回はAdGuard Homeを設定してみました。これ本当に速度も速いし広告もブロックしてくれるし設定も簡単だし悪いことありません。少しの手間で終わりますので、皆さんぜひやってみてください。
【Mac】コピーした内容を次々にテキストに貼り付ける方法

## 背景

複数回コピーしたものをどんどんファイル出力したい。
Cliborなどクリップボードアプリを使えば、クリップボードにある複数のコピーをまとめて出力はできるのですが、今回はbashだけでやります。

## 方法

以下のスクリプトを実行すると、ファイル（ここでは、~/Desktop/copied_texts.txt）に出力されます。
```bash
#!/bin/bash

# 直前のクリップボードの内容を保存する変数
PREVIOUS_CONTENT=""

while true; do
    # 現在のクリップボードの内容を取得
    CURRENT_CONTENT=$(pbpaste)

    # クリップボードの内容が前回と異なる場合のみ処理を実行
    if [[ "$CURRENT_CONTENT" != "$PREVIOUS_CONTENT" && ! -z "$CURRENT_CONTENT" ]]; then
        # テキストファイルに出力
        echo "$CURRENT_CONTENT" >> ~/Desktop/copied_texts.txt
        # 現在の内容を記録
        PREVIOUS_CONTENT="$CURRENT_CONTENT"
    fi

    # 少し待つ
    sleep 1
done
```

## 実演
![20250322.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610591/480fc13e-af6c-4541-b540-a4c6162ef761.gif)
家計簿アプリを作る＃２０

![スクリーンショット 2025-03-23 102045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/6231e65a-523b-48af-bebe-5fb70f78e977.png)
openとonCloseで、Drawerの表示非表示を切り替えてます。
onCloseのhandleDrawerToggleの関数を確認してみます。

![スクリーンショット 2025-03-23 102301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/e957a7e8-514b-4a76-acce-4ca53e8e4ad1.png)
AppLayout.tsxの中のhandleDrawerToggleを見てみると、setMobileOpenとして、mobileOpenをTrueであれば、false、falseであれば、Trueに、！を使って切り替えてます。

![スクリーンショット 2025-03-23 102553.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/e2f8f4ee-3fb0-4d99-83b2-fd83fc190860.png)
mobileOpenはこちら👆で定義されています。初期値は、falseのStateです。

![スクリーンショット 2025-03-23 102738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/f4fe5e3c-3074-4389-b38b-d5765799f4bf.png)
mobileOpenは、Drawerのopenで使われています。このmobileOpenがTrueの時は、モバイル用のDrawerを表示して、falseの時は、非表示にしています。

![スクリーンショット 2025-03-23 103013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/c2afecf4-752b-4862-aa2a-784efed20148.png)
アイコンを押されたときも、Drawerの表示非表示が切り替わるようにしたいので、👆handleDrawerToggleを使ってます。

これらは、サイドバーの説明です。
考えすぎるAIはもういらない：LLM推論を高速・低コスト化する“Efficient Reasoning”完全ガイド

# Chain-of-Thoughtの終焉か？進化か？――効率的推論（Efficient Reasoning）で再定義されるAIの“思考”

---

## はじめに：問題提起の再定義

私たちは今、**「考えるAI」**に対して、新たな問いを突きつけています。

- なぜAIは「たかが2+3」で600語も使うのか？
- 本当に「たくさん考えること」は賢さなのか？
- それは「人間の知的振る舞い」に近づいているのか？

2025年、Rice大学の研究チームはこの問いに正面から挑みました。  
それが今回ご紹介する論文：

### **Stop Overthinking: A Survey on Efficient Reasoning for Large Language Models**

本稿では、この論文の本質・方法・インパクト・限界・展望を、**研究史／実装戦略／社会実装／未来展望**という多層構造で解き明かします。

---

## 論文情報

- **タイトル**: Stop Overthinking: A Survey on Efficient Reasoning for Large Language Models  
- **arXiv**: [https://arxiv.org/abs/2503.16419](https://arxiv.org/abs/2503.16419)  
- **著者**: Yang Sui, Yu-Neng Chuang 他（Rice University）  
- **GitHub**: [Awesome-Efficient-Reasoning-LLMs](https://github.com/Eclipsess/Awesome-Efficient-Reasoning-LLMs)  
- **分野**: LLM最適化、推論効率、CoT制御、RL/SFT技術、プロンプト制御

---

## 1. Chain-of-Thought（CoT）推論の進化史

| 年代 | フェーズ | キーワード |
|------|----------|------------|
| ～2021年 | 前CoT期 | 次トークン予測（GPT系） |
| 2022年 | CoT導入期 | CoT Prompting（Wei et al.） |
| 2023年 | 多様化期 | Tree-of-Thought / Self-Consistency |
| 2024年 | 強化学習期 | RLHFでCoTを内在化（DeepSeek-R1など） |
| 2025年〜 | 効率化期 | **Efficient Reasoning**の誕生（本論文） |

---

## 2. Efficient Reasoningとは何か？

### 定義：
> **「推論長を最小限に保ちつつ、正答率と説明力を維持する」こと**

### 背景：
- LLMの出力は推論長に比例して**コスト・遅延・バグ率が上がる**
- CoTは「冗長な安全策」として設計されているが、**計算的には非効率**
- 本論文はこれに対し、「**短くても正しく考えるAI**」を目指す研究群を分類・比較しています

---

## 3. 技術分類：3次元マトリクス（構造 × 出力 × 入力）

| 軸 | 手法群 | 実装例 | 適用モデル |
|----|--------|--------|------------|
| **構造ベース** | RL報酬制御 / SFT短CoT | O1-Pruner / TokenSkip | DeepSeek, Qwen |
| **出力ベース** | Latent Reasoning / Dynamic Routing | Coconut / ST-BoN | Frozen LLM, LoRA対応 |
| **入力ベース** | Token-Budget Prompt / Routing by Difficulty | TALE-EP / SoT | Claude, RouteLLM |

---

## 4. メタ視点：LLM設計哲学としてのEfficient Reasoning

| 観点 | 従来LLM | Efficient Reasoning |
|------|----------|----------------------|
| 思考の定義 | 出力されたCoT | 潜在的思考 or 最小限表現 |
| 成功条件 | 高精度 + 高冗長 | 高精度 + 低冗長 |
| 制御手段 | モデルサイズと温度調整 | 推論長制御・ルーティング |
| ユーザーとの関係 | 解釈可能だが冗長 | コンパクトで操作可能 |

---

## 5. 認知的含意：人間の思考とLLMの違いは何か？

| 項目 | 人間の思考 | LLMの推論 |
|------|------------|-----------|
| 推論停止のタイミング | 自信 or 疲労 | トークン制限 or モデル判断 |
| 冗長性の制御 | 無意識の省略 | 明示的な長さ制御が必要 |
| 推論戦略の切替 | 問題に応じて柔軟 | RoutingやRLで模倣可能 |
| メタ認知 | 自分の不確かさを知る | Certaindexなどで模倣中 |

---

## 6. 社会的インパクトと倫理的視点

| 観点 | 影響 |
|------|------|
| **コスト** | 1Mトークン→1000トークン以下に短縮すれば、90%以上削減可 |
| **レスポンスタイム** | リアルタイム処理（医療・自動運転）での適用が現実に |
| **アクセシビリティ** | 小型LLMでも高性能を発揮＝低リソース国や教育現場への応用 |
| **リスク** | 推論短縮により説明性が低下、倫理的な判断材料が消える可能性あり |

---

## 7. 未来戦略：研究者・実務者のための研究マップ

| 分類 | 研究テーマ例 |
|------|--------------|
| **基礎** | 「推論長 vs 精度」の理論限界の定式化（例：Token Complexity Theory） |
| **応用** | 医療現場での短CoT生成支援モデルの構築 |
| **理論** | Efficient Reasoningの数理モデル（例：最適停止理論との接続） |
| **実証** | プロンプト制御によるリアルLLM APIコスト削減のケーススタディ（SaaS現場）

---

## 結論：AIは「短く考えて、よく当てる」存在になれるか？

本論文は、LLMが「思考らしきもの」を生成するようになった今、**思考とは何か？どこまで必要か？**という問いを社会全体に投げかけています。

Efficient Reasoningは、ただの“軽量化手法”ではありません。  
それは **“人間らしい思考を模倣しながら、計算機的に最適化された知性”** を実現するための哲学です。
HP作成備忘緑：S3バケッットにFormSubimtフォームを配置する方法について解説してみた

## はじめに

AWSのS3バケットを使って静的Webサイトを構築し、FormSubmitでメールフォーム機能を実現する方法を解説します。
サーバーレスで簡単にフォームが作れるので、個人サイトや小規模な事業所のホームページにも最適です。
## 書こうと思ったきっかけ

実際にサーバーを持たない状態で問い合わせフォームを設置したいという相談を受けたことがきっかけです。

:::note warn
**S3とFormSubmitの組み合わせなら簡単に実装できると感じたため、その手順を共有しようと思いました。**
:::

静的なお問い合わせフォームを手軽に実装したいときに便利なのが、FormSubmit。そして、AWSのS3バケットは静的なHTMLサイトをホスティングできる強力な選択肢です。

:::note info
「S3に置いたHTMLフォームから、FormSubmitでメール通知できるの？」という疑問に対して、答えはYES！ただし、正しい設定が必要です。
:::

この記事では、S3バケットに配置したフォームから、FormSubmitで通知を受け取るための具体的な手順と注意点を解説します。

---

## S3バケットの作成とファイル配置

まずは、S3で静的ウェブサイトを構成しましょう。

- S3バケットを作成（例：honda-sr-office-site）
- 「パブリックアクセスを許可」に設定（公開用サイトの場合）
- HTMLファイルをアップロード（例：index.html、contact.html）
- ファイルにブラウザでアクセスできるURLを確認
  - 例：https://honda-sr-office-site.s3-website-ap-northeast-1.amazonaws.com/contact.html

---

## 静的ウェブサイトホスティングの有効化

S3でHTMLをそのままウェブサイトとして公開するには、次の設定が必要です。

- バケットの「プロパティ」タブを開く
- 「静的ウェブサイトホスティング」を有効化
- インデックスドキュメントに index.html を指定（任意）
- 表示されたURLをメモしておく（このURLが公開サイトの入口）

---

## FormSubmitとの組み合わせ時の注意点

### HTTPS対応のURLでアクセス

S3バケットのURLが `http://〜` 形式の場合、セキュリティの理由でFormSubmitが動作しないことがあります。

→ CloudFrontでHTTPS化することも可能ですが、テスト用途であれば formsubmit.co 側で問題なく処理されることもあります。

### CORSの設定は不要

FormSubmitはフォーム送信時にクライアントから直接POSTする方式なので、JavaScriptベースのAPI通信のようなCORS設定は不要です。

---

## HTMLコード例（S3対応）

以下のコードを `contact.html` に記述して、S3にアップロードするだけでOKです：

```html
<form action="https://formsubmit.co/tbentian37@gmail.com" method="POST">
  <!-- 送信後に移動するページ（任意） -->
  <input type="hidden" name="_next" value="thanks.html">

  <!-- スパム対策（任意） -->
  <input type="text" name="_honey" style="display:none">
  <input type="hidden" name="_captcha" value="false">

  <!-- 入力フィールド -->
  <input type="text" name="name" placeholder="お名前" required>
  <input type="email" name="email" placeholder="メールアドレス" required>
  <textarea name="message" placeholder="お問い合わせ内容" required></textarea>

  <button type="submit">送信する</button>
</form>
```

---

## まとめ

S3バケット上で静的ウェブサイトホスティングを有効にし、そこにHTMLファイルを配置すれば、FormSubmitは問題なく利用できます。

:::note warn
***WordPressやサーバーなしでも、コードだけで実現できるお問い合わせフォームはとても手軽で便利です。***
:::

ぜひS3とFormSubmitを活用して、シンプルなフォームサイトを構築してみてください！
【PHPStan】nullチェック後もPHPStanの指摘が出る原因と解決策

# 初めに
PHPStanを導入すると、nullチェックをしたにもかかわらず、null許容型と判断され、`Cannot call method `が出てしまうこともあるかもしれません。
ここでは、その際の解決方法について説明します。

# 問題：nullチェック後もnull許容型であることを指摘されてしまう

以下のようなコードを解析してみます。
* `$fuga`は`Fuga|null`型のためnullチェックを実施
* Exceptionの呼び出しのために共通的なメソッドを使用

```php:解析対象
class Hoge
{
    public function hogeMethod():void
    {
        // 返却値がnull許容型のメソッドを呼び出す
        /** @var Fuga|null $fuga */
        $fuga = $this->getFuga();

        // null の場合は共通的なエラーを返すメソッドを呼び出す
        if (is_null($fuga)) {
            $this->throwCommonException();
        }

        // null じゃなくなったので、安全に呼び出せるはず
        $piyo = $fuga->getPiyo();
    }

    /**
     * 共通エラーを返すメソッド
     */
    private function throwCommonException(): void
    {
        throw new Exception(
            "common error",
            500
        );
    }
}
```

解析したところ、nullチェックしたにも関わらず`Cannot call method `の指摘が出てしまいました。

```powershell: 実行結果
$ ./bin/phpstan analyse

:14	   Cannot call method getPiyo() on Fuga|null.
```

# 原因：nullチェック時に呼び出す共通エラーメソッドの戻り値がvoidになっている
この原因は`throwCommonException()`の戻り値がvoidになっていることです。
このメソッドでは`throw`しかしていませんが」、phpstanは中身を気にしません。voidであればこの後も処理が継続されると認識してしまいます。

```php
    /**
     * 共通エラーを返すメソッド
     */
    private function throwCommonException(): void
    {
        throw new Exception(
            "common error",
            500
        );
    }
```

# 解決策1：nullチェック時にreturnする
一つ目の解決策は「nullチェックの中でreturnしてあげること」です。
とはいえ、PHPStanのために意味のないreturnを書くのは少し気になりますね。

```php
    public function hogeMethod():void
    {
        // 返却値がnull許容型のメソッドを呼び出す
        /** @var Fuga|null $fuga */
        $fuga = $this->getFuga();

        // null の場合は共通的なエラーを返すメソッドを呼び出す
        if (is_null($fuga)) {
            $this->throwCommonException();
            // 明示的にリターンする！
            return;
        }

        // null じゃなくなったので、安全に呼び出せるはず
        $piyo = $fuga->getPiyo();
    }
```

# 解決策2：neverを用いる
二つ目の解決策はPHPのnever型を用いることです。
returnを用いる場合と違い、余計な処理を書かなくて済むのは嬉しいですね。

```php
    /**
     * 共通エラーを返すメソッド
     */
    private function throwCommonException(): never
    {
        throw new Exception(
            "common error",
            500
        );
    }
```

PHP公式ドキュメントには、never型について以下のように書いてあります。

> never は、 関数が戻ってこないことを示す戻り値の型です。 これは、関数の中で exit() がコールされるか、 例外がスローされるか、 無限ループに入るかのいずれかであることを意味します。 

https://www.php.net/manual/ja/language.types.never.php

これによって、処理が終わることをPHPStanに明示的に示すことができました。


# 終わりに
neverはPHP8.1から登場した比較的新しい型です。
PHPStanを既存のシステムに導入すると、このような問題に直面するかもしれません。
その際はnever型に置き換えることも検討してみてください。

ここまでご覧いただきありがとうございました！
重い処理をサボるデザインパターンの図的理解

巷で（多分） proxy パターンと呼ばれているデザインパターンを図的に理解しよう[^1]。
[^1]:名前に関しては自信がないので、違ってたら教えて下さい

# 重い処理
画像に示すような激重処理があったとする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/2482abb7-01a5-405e-a558-7084b7ee0339.png)

# 入出力の分割
重い処理の入力部分・処理部分・出力部分を別々に切り分けると必要なときに必要な分だけ処理できるようになる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/d05ba008-3d36-47ce-a033-b638b238cc80.png)

全体的な複雑性は増しているが、各部分の処理に着目するとシンプルになっている

## 出力部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/0f3f3833-0643-4c25-acdd-0feb1422b03a.png)
重い処理の部分は必要になるまで待機している (lazy load)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/ccb4fe4e-7541-40a4-879c-d9c040dc17aa.png)
注文が入ると重い処理が動き、出力する

## 入力部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/9eaf94ee-ebdc-4993-b546-5d5620d606dd.png)

計算に必要なリソースを取ってくる領域を確保しておき、計算するときに取ってくる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/a7d5f926-9ad2-4cfd-8668-d215661104b3.png)
リソースを配置する処理は別で行われても良い。
図ではストリームをバッファに溜め込んでおき、ある程度時間が経ったら捨てる処理をイメージしている。
このような処理は、例えば、信号処理をリアルタイムに行う場合などに現れる。
【不具合解消】Astroにremark-link-cardを導入するとページ末尾にリンクカードが表示されたりひとつしか表示されなかったりする

# 前提

| 環境              | 値                                            |
| ----------------- | --------------------------------------------- |
| OS                | Mac（Intel）                                     |
| IDE               | VisualStudioCode   |
| Astroテンプレート               | Fuwari |

# 事象

AstroテンプレートのFuwariにremark-link-cardを導入したところ、下記の事象が発生した。

```javascript
// astro.config.mjs
  markdown: {
    remarkPlugins: [
      remarkMath,
      remarkReadingTime,
      remarkExcerpt,
      remarkGithubAdmonitionsToDirectives,
      remarkDirective,
      remarkSectionize,
      parseDirectiveNode,
      [remarkLinkCard, { // <- プラグイン追加
        cache: false,
        shortenUrl: true,
      }],
    ],
```

- 元のリンクテキストが残ってしまう
- リンクカードがひとつしか表示されない
- markdownで定義した構造を無視して末尾にリンクカードが出力される

![実際の表示結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900794/6865e21f-f39b-4546-8ab2-81e4ab0b4af9.png)

# 解消できた方法

remarkSectionizeによってMarkdownの構造が書き換えられていることが原因だった。
プラグインの記述順をremarkSectionizeよりも手前に記述することで解消された。

```javascript
// astro.config.mjs
  markdown: {
    remarkPlugins: [
      remarkMath,
      remarkReadingTime,
      remarkExcerpt,
      remarkGithubAdmonitionsToDirectives,
      remarkDirective,
      [remarkLinkCard, { // <- 順番をremarkSectionizeより手前に書く
        cache: false,
        shortenUrl: true,
      }],
      remarkSectionize,
      parseDirectiveNode,
    ],
```

![解消けっk](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900794/ac95dcc3-f5e6-4e0a-b80a-11bf8e30dc77.png)

元々の実装が間違っているのだろうかとか色々試行錯誤してしまいましたが、単純に順番の問題でした。
プラグインを追加するだけでOKと思っていたので、順番までは考えられてなかったです。
ひとまず無事解決できてよかった。
GTMデバッグURLで確認したJSファイルのデータ構造を調べてみる

# ▼調べ方
GTMのプレビューURLにて開いたページであれば検証ツールにて変数やトリガー、タグがどのように設定されてるかを確認することが出来る。

検証ツールのSourcesタブの`www.googletagmanger.com`配下のJSファイルを開く(debugという文字列がある方を選択)

# ▼データ構造を調べる
`data`というオブジェクトの中に`resource`というキーがあり、その中に変数とタグとトリガー条件などが格納されていそうだ
それぞれについて見ていく。

## ➀変数
`data>resource>macros`というオブジェクトの階層になっている。

`macros`に変数が入っている。ここには組み込み変数とユーザ定義変数が格納されていそうだ。GTMにて追加した変数のみが表示される
- function名として変数タイプを表す文字列が書かれている
    - 例えば、__jsmであればカスタムJS変数

ex)カスタムJS変数
```javascript
"function": "__jsm",
"instance_name": "タイトル取得変数",
"vtp_javascript": ["template", "(function(){return document.title})();"]
```

## ➁タグ
`data>resource>tags`

`tags`にタグが入っている。タグの種類ごとに持つキーの種類が違いそうだ。一つ一つのタグにはIDが振られている。instance_nameにはタグ名が入っている。
- function
    - __googletag
        - Googleタグ
    - _gaawe
        - GA4イベントタグ
    - __html
        - カスタムHTML

ex)GA4イベントタグ
```javascript
"function": "__gaawe",
"instance_name": "falseClickタグ",
"metadata": ["map"],
"once_per_event": true,
"vtp_sendEcommerceData": false,
"vtp_enhancedUserId": false,
"vtp_eventName": "falseClisk",
"vtp_measurementIdOverride": "G-XXXXXXX",
"vtp_enableUserProperties": true,
"vtp_enableMoreSettingsOption": true,
"vtp_enableEuid": true,
"vtp_migratedToV2": true,
"vtp_demoV2": false,
"tag_id": 28
```

## ③トリガー条件
`data>resource>predicates`

おそらくトリガーが入っている。トリガーの中でもその中の発生条件単位で格納されている。一つのトリガーに複数のドメインを条件として追加したとすると、ドメインごとにデータが格納される仕組みのようだ
- functionにはマッチタイプが入っている
    - __eq
        - 完全一致
    - __re
        - 正規表現に一致
    - cn
        - 含む

ex)カスタムイベントトリガー
```javascript
"function": "_eq",
"arg0": ["macro", 0],
"arg1": "consent_update"
```

これは、0番目の変数が"consent_update"とに完全一致するという条件となる。
0番目の変数はmacrosオブジェクト配列の0番目を確認すると以下のようになる。

"function": "__e",
"instance_name": "_event"

イベント名を取得する変数であると推測出来る。
まとめると、このトリガーはイベント名がが"consent_update"とに完全一致ものに発火するものであると理解できる

# ▼分かったこと
GTM UIにて設定した変数・タグ・トリガーはオブジェクトとして格納されている。
以下のようにオブジェクトのキーが対応する。補足説明についても記載する。
- 変数
    - macros
        - 組み込み変数とユーザ定義変数の両方が入っている
- タグ
    - tags
        - タグの種類ごとに持つ属性が異なる
- トリガー条件
    - predicates
        - トリガー単位ではなく、トリガーの詳細条件という単位で格納される
        - macrosに格納されたものを呼び出している

また、今回調査をしなかったが推測出来たもの、見つけたものについても述べる
- rulesにトリガーが格納されており、if文とaddを駆使してそのトリガーを発動させている。
- runtime属性
    - 何が行われているか分からなかった
- entities
    - よくわからなかったが複数キーに対してtrueという値を設定していた
- permissions
    - あらゆるものに対しての許可設定を行っている箇所だと推測する

理解不能な箇所も多いが、GTMが裏側で行っている処理が少しは見えてきた気がする。
CSVからDBにINSERTする方法を調べてみた

最近はCSVからあらかじめ入れておく情報をDBに移す作業をしている。

最初はCSVから直接DBに流した。

次はテーブル間の情報等もあり少し面倒だったので
仮テーブルを作成して一度仮テーブルに入れてから、各テーブルに情報を振り分けた。

他にも取り込む方法はあるんだろうなーと思って調べてみた。

# 直接既存テーブルにINSERTする方法

CSVを1行ずつ既存のテーブルにINSERTしていく方法。

## メリット
### 1.	実装がシンプル
簡潔なスクリプトで実装できるケースが多い。
### 2.	中間テーブルが不要
別途テーブルを作らず直接テーブルへ書き込むためテーブルが複雑化しにくい。
### 3.	ツールによる速度向上
大量データの場合でもDBが提供するバルクロード機能を利用すれば高速にインポートできる。

## デメリット
### 1.	エラー処理の難しさ
1行でも不正データが混じっているとインポート全体が失敗する可能性がある。
部分的にエラーをスキップするなどの制御には追加の工夫が必要。
### 2.	ロールバックやトランザクションの負荷
途中でエラーが発生すると大きなロールバックが走る可能性がある。特に大量データの扱いではパフォーマンスに影響が出やすい。
### 3.	本番環境への直接影響
取り込み中に既存の本番テーブルにロックがかかったり、ユーザー操作に影響が出る場合がある。


# 仮テーブルを経由する方法
「仮テーブル」に取り込みその後加工・バリデーション・重複チェックを行う。
その後テーブルへ移行する方法。

## メリット
### 1.	バリデーションや加工が容易
仮テーブルで一旦データを受け取り変換や重複チェックなどをじっくり行ったうえで本番テーブルにINSERTできる。
### 2.	エラー処理がしやすい
不正データのみを仮テーブルから除外・修正するなどの柔軟な対応ができる。途中経過を確認することも容易。
### 3.	本番テーブルへの負荷軽減
大量のINSERTを本番テーブルへ一度に流さず処理を分割できるため、運用影響を低減できる。

## デメリット
### 1.	追加のテーブル管理が必要
仮テーブルを作成・削除・メンテナンスするコストがかかる。
### 2.	データ移行フローが複雑化
仮テーブルへ取り込み → バリデーション → 本番テーブルへINSERTという複数の工程が必要になり、運用フローが煩雑になる場合がある。
### 3.	ディスクスペースの追加消費
仮テーブルに大量データを一時的に保管するため、ディスク容量が余分に必要になる。


# 3. ETL/ELTツールやフレームワークを利用する方法
AWS Glue, dbt などのETL/ELTツールを使いGUIや設定ファイルベースでデータ取り込みから加工までを一元管理する方法。
最近はCloudサービスと組み合わせてデータパイプラインを構築しパイプラインの一部としてCSVをDBへ取り込むケースが増えているらしい。

**※パイプライン＝社内のデータを収集し分析するツール**


## メリット
### 1.	GUIや設定ベースでの開発が可能
コーディング量が減り、開発効率が上がる場合が多い。
### 2.	リトライやエラー通知などの運用機能が充実
組み込みの機能でジョブスケジューリングや監視、ログ収集を行うことができる。
**※ジョブスケジューリング＝プログラムを登録して起動の順番や実行状態の管理**

### 3.	大規模データにも対応しやすい
分散処理やクラウドでのスケーラビリティを活用して、大量のCSVを効率的に処理できる。

## デメリット
### 1.	ツール導入やライセンスコスト
商用ETL製品やクラウドサービスにはコストがかかる場合がある。
操作習得にも学習コストが必要。
### 2.	環境構築の手間
ツールを導入するためのサーバーやクラウド環境の準備・構築が必要。
### 3.	ツールへの依存
ツール特有の機能に依存する部分が増えるため、将来的に乗り換えが発生する場合、移行が大変になることがある。

# 4. 自作スクリプト（Python, Rubyなど）で取り込む方法


PythonやRuby、Bashスクリプトなどで独自にCSVを読み込み、DBへINSERTする処理を組む方法。
バッチやシェルスクリプトを組んで定期的に取り込む、CI/CDパイプラインに組み込む、などの運用が可能に。

## メリット
### 1.	柔軟性が高い
ロジックを自由にカスタマイズできるため、独自ルールのバリデーションや複雑な前処理などを簡単に実装しやすい。
### 2.	ライブラリが豊富
PythonなどではCSVパースやDB接続用のライブラリが充実しており、比較的短時間で実装可能。
### 3.	ランタイム環境さえあればOK
ツールのインストールや大掛かりな環境構築が不要で、スクリプトを動かせる環境があれば実行できる。

## デメリット
### 1.	保守性・可読性
開発者が独自実装を行うため、コードの書き方によっては保守が難しくなる可能性がある。
### 2.	運用管理の手間
エラー検知・通知やジョブスケジューリングの仕組みを自前で整えなければならない。
### 3.	高速化には工夫が必要
大量データを逐次INSERTするとパフォーマンスが低下しやすい。バルクINSERTやマルチスレッド化などを意識した実装が必要。

## 5. 一時ファイルや中間処理を挟む方法（ファイル分割など）

•	CSVファイルが非常に大きい場合、事前に分割してからDBに取り込み、または一時的に別の形式（Parquetなど）に変換した後、まとめてDBにロードする方法です。
•	こちらは「取り込みの前段階の準備」としてよく行われる手段です。

メリット
	1.	メモリや時間の節約
CSVファイルを分割することで、一度に読み込むデータ量を小さくし、失敗やロールバックの範囲を限定できる。
	2.	複数プロセスで並行処理
分割したファイルを複数のバッチやスクリプトで同時に処理できるため、大量データの取り込み速度を向上できる。
	3.	フォーマット変換による速度向上
DBが直接扱いやすいフォーマット（Parquet, ORCなど）に変換することで、取り込み時のオーバーヘッドを削減できる場合がある。

デメリット
	1.	前処理の手間
CSV分割やフォーマット変換のために追加のスクリプトやツールが必要になる。
	2.	管理が複雑化
多数のファイルを扱うことで、ファイルごとのエラー管理や再取り込みが煩雑になりやすい。
	3.	ストレージの消費
CSVのほかに変換後のファイルも保存する場合、ストレージ容量が余分に必要。


# 結局どれを選ぶ？

個人の勝手な見解だけど、データ量が少なく、単純なCSV取り込みであればRDBMSのバルクロード機能を利用した直接INSERTがシンプルそう。
大規模系は今後のことを踏まえてETL/ELTツールが現場負担も少なくて済みそう。
個人的には自作スクリプトを作成するのが楽しそうではある。
HP作成備忘録：サーバー不要で実現！HTMLフォームからメール送信する方法をまとめてみた

## はじめに

企業や個人事業のWebサイトに「お問い合わせフォーム」を設置するのはとても一般的ですが、サーバーを用意せずにメール送信機能をつけたい方も多いはずです。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

この記事では、無料で使える外部サービス Formsubmit を使って、HTMLフォームの内容を特定のメールアドレス（例：info@example.com）に送信する方法をわかりやすく解説します。

---

## Formsubmitにメールアドレスを登録する

1. [https://formsubmit.co](https://formsubmit.co) にアクセスします
2. 中央の入力欄に受信したいメールアドレス（例：info@example.com）を入力します
3. 「Submit」ボタンを押すと、確認メールが届きます
4. メール内の「Verify」ボタンをクリックして認証を完了します

---

## HTMLフォームのコードを修正する

既存のHTMLファイルの `<form>` タグを以下のように修正します。

```html
<form action="https://formsubmit.co/info@example.com" method="POST">
  <input type="hidden" name="_captcha" value="false">
  <input type="hidden" name="_next" value="thanks.html">

  <label for="name">お名前：</label><br>
  <input type="text" id="name" name="name" required><br><br>

  <label for="email">メールアドレス：</label><br>
  <input type="email" id="email" name="email" required><br><br>

  <label for="message">お問い合わせ内容：</label><br>
  <textarea id="message" name="message" rows="5" required></textarea><br><br>

  <button type="submit">送信する</button>
</form>
```

### 解説
- `action` のURLに登録したメールアドレスを含めることで、そこに送信されます
- `_captcha` はスパム防止機能をオフにする設定です
- `_next` は送信完了後に遷移するページの指定です

---

## 完了メッセージ用のHTMLを作る（thanks.html）

フォーム送信後に「ありがとうございました」と表示したい場合は、以下のような `thanks.html` を作成します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>送信完了</title>
</head>
<body>
  <h2>お問い合わせありがとうございました！</h2>
  <p>内容を確認後、折り返しご連絡いたします。</p>
  <a href="index.html">トップページに戻る</a>
</body>
</html>
```

---

## フォーム送信をテストする

1. Webページをブラウザで開き、フォームに情報を入力
2. 「送信する」をクリック
3. 指定したメールアドレスに通知が届いているか確認
4. `thanks.html` が表示されれば成功！

---

## より便利なオプション（必要に応じて）

| 機能         | 入力項目例                                                                 |
|--------------|------------------------------------------------------------------------------|
| 自動返信     | `<input type="hidden" name="_autoresponse" value="お問い合わせありがとうございます。">` |
| スパム対策無効 | `<input type="hidden" name="_captcha" value="false">`                        |
| 完了ページ指定 | `<input type="hidden" name="_next" value="thanks.html">`                       |

---

## 注意点

- 無料プランでは1日100通までの送信制限があります
- Gmailなどでは迷惑メールフォルダやプロモーションタブに入ることがあります

---

## まとめ

Formsubmit を使えば、サーバーを準備しなくても、簡単にお問い合わせフォームからの内容をメールで受け取ることができます。

今回紹介した方法をそのまま使えば、ホンダ社労士事務所のお問い合わせフォームから info@example.com 宛に自動で連絡が届くようになります。
ChatGPT に CSS を追加するだけ

ChatGPT に CSS を追加するだけです。独自 CSS を追加できるブラウザ拡張機能 (Stylus など) で追加する必要があります。以下のような見た目になります。

<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177688/00608064-ee77-44bf-895e-9e6fc440f196.png">

## CSS

ライトテーマに追加するので、設定からテーマを「ライト」にしておく必要があります。

### 色の変更
```css
/*----- 色の変更 -----*/
main {
  background: #fdfcf5;  /* デザイン上メイン画面の後ろをクリーム色で塗る */
}
.light {
  --text-primary: #564c3e;  /* 文字をこげ茶色に */
  --text-secondary: #564c3e;  /* 文字をこげ茶色に */
  --sidebar-surface-primary: #dcf0d0;  /* サイドバーを薄緑色に */
  --sidebar-surface-secondary: #addfaa;  /* 過去チャットをマウスオーバー時はやや濃い薄緑色に */
  --sidebar-surface-tertiary: #91cf9c;  /* 選択中のチャットはさらにやや濃い薄緑色に */
  --main-surface-primary: #b7e6e5;  /* メイン画面のヘッダ部と入力部を水色に */
  --message-surface: hsla(0, 0%, 91%, .8);  /* 自分が入力したメッセージの灰色をやや濃い目に */
  --main-surface-secondary: hsla(0, 0%, 91%, .8);
}
*, :hover {
  /* sidebarをやや濃いパステル色にするとsidebarのscrollbarが見づらくなるのでこげ茶に */
  scrollbar-color: #564c3e transparent;
}
.text-token-text-primary, .p-1 {
  /* sidebarのChatGPTアイコンの背景が--main-surface-primaryになることへの対処 および
     過去のシステム回答へのFB箇所に--main-surface-primary色の領域が浮くことへの対処 */
  background-color: transparent;
}
h1 {
  /* 新規チャット画面の「お手伝いできることはありますか？」もこげ茶色に */
  color: #564c3e;
}
.bg-black,
[data-radix-popper-content-wrapper] div,
[data-radix-popper-content-wrapper] div:hover {
  /* オンマウスで出てくる吹き出しの背景色もこげ茶色に */
  background-color: #564c3e;
  color: #fdfcf5;
}
p.placeholder::after {
  /* プレースホルダの「質問してみましょう」がみづらくなることへの対処 */
  color: #564c3e !important;
  opacity: 0.8;
}
```
### フォントの変更
```css
/*----- フォントの変更 -----*/
:host, html {
  font-family: 'Verdana', 'BIZ UDGothic', sans-serif;
}
```
### フォントサイズを縮めて行間を詰める変更
```css
/*----- フォントサイズを縮めて行間を詰める変更 -----*/
:host, html {
  /* 基準のフォントと行間をやや縮める */
  font-size: 15px;
  line-height: 1.35rem;
}
.h-9 {
  /* サイドバーのチャット履歴が一つ一つ縦幅があるので縮める */
  height: 1.65rem;
}
.p-2 {
  /* サイドバーのチャット履歴の縦幅を縮めたのに伴い文字の余白も縮める必要がある */
  padding-top: .2rem;
  padding-bottom: .2rem;
}
.text-base, .prose {
  /* 自分のメッセージとシステム回答のフォントと行間をやや縮める */
  font-size: .9rem;
  line-height: 1.35rem;
}
.prose :where(hr):not(:where([class~=not-prose] *)) {
  margin: .75rem 0;  /* システム回答の水平線の上下が広すぎるので縮める */
}
.prose :where(li):not(:where([class~=not-prose] *)) {
  margin: .15rem 0;  /* システム回答の箇条書きの行間が広すぎるので縮める */
}
.markdown pre {
  margin-top: .15rem;  /* システム回答のpreの上に余白があるので縮める */
}
```
レアゾン・ホールディングス 2024新卒エンジニア セキュリティ研修・クラウド研修 -フィッシングサイトに飛ばされて-

## 導入・挨拶
2024年新卒、menu事業部マイクロサービス基盤チームの立木です。
大学院で5年間マウスの脳を研究していました。卒業後エンジニアを志し、新卒就活を経て株式会社レアゾン・ホールディングスに入社。現在はmenuアプリのマイクロサービス基盤のインフラや運用改善、およびGoによるアプリ開発に携わっています。
## 研修の概要
研修の概要はオウンドメディアの記事で詳しく紹介していますので、こちらからご覧ください。

https://media.reazon.jp/special/NewGraduate_engineer
## セキュリティ研修
### テーマの概要（セキュリティ研修）
セキュリティ研修では、講義形式で、セキュリティがなぜ必要か・ないと会社にどのような損害があるか・基本的なセキュリティの考え方や用語などを教わりました。
### テーマの詳細（セキュリティ研修）
講義は主に研修の運営責任者である窪田さんにより、日英スライド・日本語スピーチで行われました。
以下のような流れで講義は進んで行きました。

- セキュリティの必要性
- 情報セキュリティの三大要素（可用性・完全性・機密性）
- クライアントサイドのセキュリティ
- サーバーサイドのセキュリティ
- インフラのセキュリティ
- ゲームのセキュリティ
- 認証・認可の考え方

まず窪田さんから研修資料のURLが共有され、僕たちは疑うことなくそのURLを開いてしまったのですが、そのURLの先は...

僕たち研修生は配布されたURLの怪しさに気づくことなくフィッシングサイトのリンクを開いてしまい、のっけからセキュリティリテラシーの大切さを叩き込まれたのです...

Owasp Juice Shopを使用した実践形式のセッションもありました。これは脆弱性を発見するゲーム形式のアプリケーションで、社内サーバーでホスティングされ、全員で同時に取り組みました。（以下サイトで配布されていますhttps://owasp.org/www-project-juice-shop/ ）。講義中もポコポコと誰かが発見した脆弱性報告が流れてきて楽しかったです。
### 技術的なお話（セキュリティ研修）
認証と認可について、かなり間違えやすいなと思いました。

1. 認証(Authentication)：ユーザーが本人かどうかを確認する
2. 認可(Authorization)：認証後、ユーザーにリソースへアクセスする権利を付与・確認する

セキュリティは知識ゲーという窪田さんのお言葉が印象に残りました。

## クラウド
### テーマの概要（クラウド研修）
クラウド研修では、主にハンズオン形式で、フロントエンドアプリとバックエンドアプリをそれぞれGoogle Cloud Runにデプロイし、協調させるというものでした。

### テーマの詳細（クラウド研修）
研修は全体的に弊社エンジニアのKurtisさんを中心に、主に英語で行われました。

初めは英語で行われる研修に戸惑いましたが、三分の一近くがバイリンガルである新卒エンジニアとグローバル化を推進する弊社の組み合わせならではと納得しました。
私自身は海外留学経験もないですが、しばらく聴いていると英語に耳が慣れてきました。またお二人とも日本語が上手なので、本当に困ったときは日本語で質問できて助かりました...
講習パートは、チームごとに「クラウドコンピューティング」についてネットで調査し、発表しました。

ハンズオンパートは下のような流れで進んで行きました。

- 講師陣の用意したフロントエンド（Next.js）とバックエンド（Ubicorn）のアプリをそれぞれDockerイメージにビルドする
- Artifact Registryにイメージをアップロードする
- それぞれのアプリをCloud Runでデプロイし、DNS設定を追加する。
![20240927115943.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4025713/cf413e59-d570-4360-9b4a-4703a5f6e7e7.png)

### 技術的なお話（クラウド研修）
- Dockerファイルやdocker-composeを書いてイメージを作った経験が皆あまりなく、皆戸惑っている様子でした...
- またnpmのパッケージがとんでもなく容量を食うため、デプロイの至る所で重く、かなりデプロイに時間がかかりました。マルチステージビルドなどを使って、node_modulesを抜いた軽量なイメージをデプロイすべきだったなと思います。
- GCPを使ったdeployはほぼ全員が未経験だったので大変でしたが、講師の方々がせっせと回って解決してくださるおかげでなんとか食らいつくことができました。


## まとめ
セキュリティの基本概念を新卒エンジニア研修で学べたことは非常によかったです。現代の開発では、多くのセキュリティ対策がフレームワークに組み込まれていますが、基礎的な考え方は開発プロセス全体を通じて重要だと思っています。実務でセキュリティを試行錯誤しながら学ぶのは困難なため、キャリアの初期段階でこうした知識を得られたのは大変良かったと感じます！

Docker とクラウド技術に関する研修経験も、実務において非常に有用でした。 特に、ローカル環境でのみ動いていた成果物を、より広範囲にアクセス可能な形で公開する過程を学べたことは貴重な経験だと思います。実際には社内IP からのみアクセス可能な設定でしたが、一応世界に成果物を公開するプロセスは、実務でのデプロイを理解する上で大変参考になりました！

研修も業務も勉強することばかりで楽しいです。学ぶことに興味ある方は是非弊社に！

### **▼採用情報**
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。

現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

https://recruit.reazon.jp/
日本語プログラミング言語 Mindをシンタックスハイライトする VSCode-Extensionがマイナーアップデート2

# はじめに
日本語プログラミング言語Mind（マインド）のシンタックスハイライトとスニペットが使用可能なVSCode拡張機能（の非公式プレビュー版）がマイナーバージョンアップしました！まだまだ粗削りの状態ですが、引き続きみなさまのご意見ちょうだいいただきたく、よろしくお願いいたします。:bow:

# 前提条件
Windows11 Pro 22H2
VSCode(Visual Studo Code)　1.95.1


## VSCodeの拡張機能
mind-extension-preview 0.0.2

# 「日本語プログラミング言語MindのVSCode拡張（非公式）」0.0.2のインストール

VSCodeの拡張機能の検索で、「mindv」くらいまでタイプすると下図のような検索結果が表示されます。スクショはアッパーキャメル風になっていますが、全部小文字でもだいじょうぶです。

![vscode-mind-syntax7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/678d701f-6f07-e555-2242-9ec76505f941.png)


検索結果ペインで「MindVsCodeExtension」の「インストール」をクリックするとインストールされてエディタウィンドウにドキュメントが展開します。

![vscode-mind-syntax8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/fa14a098-0a40-aab4-dbf6-d761530ce7ed.png)

既に以前のバージョンをインストールしていただいている環境では下図のような状態になります。アップデートが検出されてエクステンションの再起動が促された状態です。

![vscode-mind-syntax-2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/87cd72c5-1850-4f0a-bce7-213b50ea3361.png)

[拡張機能の再起動]をクリックしてください。VSCodeが再起動されるというわけではなく、当該エクステンションがそのまま再ロードされてアップデートします。

# シンタックスハイライトの様子

Mindのソースコードがシンタックスハイライトされている様子です。

![vscode-mind-syntax-2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/06f4c8e7-d17a-4e2e-89be-e63f1369cd3f.png)

筆者の環境はハイライトの着色を少しカスタマイズしているので、色の付き具合は環境により異なるかもしれません。
詳しくは[こちらの記事](https://qiita.com/mylifewithviolin/items/5761f0f29255b121eee9)をご参照ください。

# コードスニペットの様子
このバージョンではコードスニペットも一部の構文で対応しています。
詳しくは[こちらの記事](https://qiita.com/mylifewithviolin/items/5eec7787c1b76cd9fcea)をご参照ください。

# ソースコードをVSCodeでビルドする方法
Mind7とMind8とMind9βのソースコードをVSCodeでビルドする環境を構築する方法はこちらもご参照ください。

https://qiita.com/mylifewithviolin/items/cf8b531bc98a518e3710

# おわりに
いかがでしたでしょうか？なにかのお役に立てればと思います。シンタックスハイライトの守備範囲はまだ不十分なので、引き続きバージョンアップしていけたらと考えております:relaxed:

2025年は日本語プログラミング言語Mind生誕４０周年です。