OmniAICreator/Qiita-1.07M huggingface dataset:
Power Query: URL Decode (Uri.UnescapeDataString) は、Uri.Parts()[Query] を利用する

# 背景

単に、URL Decode をしようとして、Uri.UnescapeDataString がなかったので、どうすれば？ってことを調べた記録

# 結論

- Uri.Parts() の [Query] を利用して Decode を行う。

## 例

> Uri.Parts("http://contoso?a=" & data)[Query][a]

但し、URL パラメーターが複数あって、それらを必要とする場合には、以下のようにして、パラメーターを接続する必要がある。

> Uri.Parts("http://contoso?a=" & data)[Query][a] & Uri.Parts("http://contoso?a=" & data)[Query][{second parameter}]

# 説明

## Uri.Parts の Query解析を利用する

MS-Learn に、以下の例で載っている・・・が分かりにくい・・

```perl: 例
let
    UriUnescapeDataString = (data as text) as text => Uri.Parts("http://contoso?a=" & data)[Query][a]
in
    UriUnescapeDataString("%2Bmoney%24")
```

https://learn.microsoft.com/ja-jp/powerquery-m/uri-parts#example-2

## Uri.Parts の Query とは

> https://***.sharepoint.com/sites/TestForTeams/Shared%20Documents/Forms/AllItems.aspx?id=%2Fsites%2FTestForTeams%2FShared%20Documents%2F%E4%BD%9C%E6%A5%AD%E7%AE%A1%E7%90%86&viewid=7c268b5c%2Dc958%2D412c%2D91f8%2D4b365959236a

こんな感じの Share の URL があったとｓて、単純に Uri.Parts({uri})に喰わせると以下になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/162470ac-3dd7-b90a-84c6-37b2c6db176e.png)

これで以下のことが分かる

- Query では、URL Parameter を抽出してくれる
- Query では、Decode されている

そう、これを利用して、MS-Learn のサンプルでは、以下の部分で Decode してる。

> Uri.Parts("http://contoso?a=" & data)[Query][a]

但し、この場合、data に、URL Parameter が含まれている場合、二番目のパラメーター以降は、[Query][{parameter}] として分離されてしまう。

今回の例であれば、以下

- 一つ目のパラメーター id は、そのまま [a] に付随。アクセスするには [Query][a]。サンプルはこれ
- 二つ目のパラメーター viewid は、viewid として分離。アクセスするには [Query][viewid]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f7a7ddcc-7583-b58d-0863-bebb400e8d4b.png)


## 今回のURL例に対する利用例

```perl: SiteURL や FolderURL を取得する例
let
    ソース = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("ZYxBDoIwEEXvQjJbCpVWamJMFUxc6w5ZlFpDIwXCFPX4Flcmrv68+TOvqqLW+xE3hGBrnXrMTsXYqsmMg+19rAdH0HqD5GLQH4fpYpRDcl4ubkCTYtCzM71HErpQyK47eeMwVji+d/a2BXr8/of8NQT8d4QllBnsCxAHKDlIBrKAcg2yBJkug0gg59c5SSh/WvMK/rWmPG+YBlpowfIQWUoXEun9S82KM8EEXXEV1fUH", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [CopiedURL = _t]),
    変更された型 = Table.TransformColumnTypes(ソース,{ {"CopiedURL", type text}}),
    DecodedURL = Table.AddColumn(変更された型, "DecodedURL", each Uri.Parts("https://contso.com?url_1stParam=" & [CopiedURL])[Query][url_1stParam], Text.Type),
    uri = Table.AddColumn(DecodedURL, "uri", each (Uri.Parts([CopiedURL])), Text.Type),
    id = Table.AddColumn(uri, "id", each ([uri][Query][id]), Text.Type),
    viewid = Table.AddColumn(id, "viewid", each ([uri][Query][viewid]), Text.Type),
    SiteURL = Table.AddColumn(viewid, "SiteURL", each ([uri][Scheme] & "://" & [uri][Host] & "/sites/" & Text.BetweenDelimiters([DecodedURL], "/sites/", "/") & "/"), Text.Type),
    FolderURL = Table.AddColumn(SiteURL, "FolderURL", each ([uri][Scheme] & "://" & [uri][Host] & [id]), Text.Type)
in
    FolderURL
```

# あとがき

単純に、UnescapeDataString() が欲しいよね :sweat:
データベース【概要】

# データベースとは
データベースはDB（Databaseの略称）と表記され、構造化した情報またはデータの組織的な集合であり、通常はコンピューター・システムに電子的に格納されている。 

通常、データベース管理システム（DBMS）で制御する。 データとDBMS、およびそれらに関連するアプリケーションをまとめてデータベース・システムと呼ぶ。

## データベースの定義
ただ単に、紙ベースの情報をデジタル形式の表にしただけでデータベースという訳ではなく、あくまで ***「特定の文字・数値や条件式によって、対象となるデータを取り出せる表」*** のことであり、文字や数値を単に羅列し、どこに何のデータがあるか検索できない表はデータベースと呼ばない。

例えばExcelで管理しているな住所や電話番号が集まった「住所録」は、立派なデータベースだと言える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887960/d71bc7de-8a65-c31d-b6db-42bc15287b83.png)

以下はデータベースの一例。
- 市役所の住民基本台帳
- 銀行の口座情報
- 通販サイトの商品一覧

他にも、さまざまな形を持ったデータベースが存在する。

## データベースの必要性
Webアプリ開発においてデータベースは必須。
以下はAmazonなどのショッピングサイトでのデータベースがない場合に起こり得る事象。
| Webアプリの機能 | データベースを使わない場合 |
|:-|:-|
| ログイン機能 | Webアプリにログインしても、データベースがないと会員情報を照会できないため、Webアプリにログイン機能を作れない。 |
| 商品一覧を表示する機能 | データベースがないと商品データを保管できないため、商品一覧を表示する機能が作れない。 |
| 商品を購入する機能 | 購入した商品データがデータベースに保管されないと、会員情報が取得できずに商品が手元に届かない。 |

データベースがあるからこそ、Webアプリでログイン処理や商品の購入など便利な機能を使うことができる。

## データベースの種類
データベースには以下の3種類が存在する。

1. リレーショナル型データベース（表形式）
2. 階層型データベース（ツリー状）
3. ネットワーク型データベース（網目状）

データベースの作り方には、さまざまな特徴があり、どのデータベースも一長一短あるが、今回は最も一般的によく使われるリレーショナル型データベースについて解説していく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887960/c51ef51a-1704-3c78-aaa7-75f2cb637dd8.png)

## リレーショナル型データベースとは
リレーショナル型データベースとは、Excelの表のように列と行から成るテーブルが関連づいて構成されているデータベースのこと。複数のテーブルが関連づいて（relational）いるため、リレーショナル型データベースと呼ばれていいる。

また、この関連性をリレーション（relation）という。

イメージとしては、「テーブルA」「テーブルB」「テーブルC」など複数のテーブル（表）があり、それらが関連づけられて構成されている。

例えば、Xの1人のユーザーが複数のつぶやきを投稿した場合、リレーショナルデータベースは以下のようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887960/cb52b801-9d3a-70cd-4284-7ced71630c2c.png)

つぶやき投稿テーブルには1人のつぶやいたデータが複数あり、ユーザー情報テーブルのユーザーIDによって2つのテーブルはリレーション（関連性）を持っていることがわかる。

## リレーショナル型データベースの種類と特徴
最後に、リレーショナル型データベースの種類について。

リレーショナル型データベースはさまざまな分野で使用されており、現場によって採用されるデータベースは異なる。

| データベース名 | 特徴 | 料金 |
|:-|:-|:-|
| MySQL  | Oracle社が開発したデータベース。処理速度が速く、世界でも最も多く利用されている。Web開発に向いている。  | 無料  |
| PostgreSQL  | さまざまなデータ形式をサポートしていて多機能。  | 無料  |
| SQLite  | 動作が軽快で、サーバーにインストールせずに、アプリケーションに組み込んで使用可能。  | 無料  |
| Oracle  | Oracle社が開発・販売する商用データベース。ライセンス費用は高く、高機能高性能。銀行や官公庁など大規模かつ堅牢なシステムに利用されることが多い。  | 有料  |
| Microsoft SQL server  | Microsoft社が開発・販売する商用データベース。Oracleと同じく、大規模システム向け。  | 有料  |

# データベースを扱う仕事
データベースをよく取り扱うエンジニアの一例は以下。

- Webエンジニア
- 機械学習エンジニア
- データサイエンティスト
- 組み込み系エンジニア

## Webエンジニア
プログラミング言語やデータベース言語を用いて、Webアプリや大規模なシステム開発を行う。

例えばECサイトの開発であれば、会員情報や商品一覧の取得、コメントの投稿などをデータベースに保管する。
ECサイトのように複雑な処理の場合は、PHPなどのプログラミング言語に、SQLなどのデータベース言語を埋め込んで使用する。

## 機械学習エンジニア
多量のデータを用いて学習を行い、予測モデルを作成してAI・人工知能の開発を行う。

予測モデルを搭載したWeb・スマホアプリ、大規模システム開発において、データベースから多量のデータを取得する。

作成した予測モデルは、以下のような用途で使われる。

- 画像や音声認識
- 株価の予測
- 顔で認証するセキュリティ
- 車の安全機能

## データサイエンティスト
機械学習エンジニアと同様にビッグデータを収集・分析して、ビジネスや社会問題の解決を図る。

統計解析を行うデータは数千から数十万程度必要となるため、データベースから取得して使用する。

## 組み込み系エンジニア
日々の生活で使用する家電製品から、工業機械などが動作するシステムおよびソフトウェアを開発する。

開発したシステム・ソフトウェアにデータベースを入れ、日々の稼働状況や誤動作を起こしたときのエラーを記録するのに使用する。

近年ではIoT技術が盛んになってきたため、組み込み系エンジニアの現場でデータベースを活用する頻度は増えていきる。

# まとめ
- データベースとは「特定の文字・数値や条件式によって、対象となるデータを取り出せる表」のこと
- Webアプリ開発では、リレーショナル型データベースであるMySQLを使用することが多い
- データベースを使用する仕事としては、Webエンジニアや機械学習エンジニアなどがある
新型milk-v duoについて

# 前振り

詳細は @kazueda さんの記事を読みましょう。

https://qiita.com/kazueda/items/ec1ce95d09b80b54ccdd

# なぜメモリ256MB版が必要だったか？

旧バージョンのmilk-v duoはCV1800Bでメモリが64MBしかありませんでした。各所で言われていたのですが、かなり無理なスペックです。ISP（画像処理エンジン）で半分のメモリがリザーブされていて、Linuxで使えるのは残りの半分。これでカメラで撮像してAI処理、動画配信なんて普通に考えたら無理です。

特にAI処理などは監視カメラで最もニーズがあると思われるYolo-v5については、iPhoneでも古いモデルだとメモリが足りなくなるぐらいなので、とても実用的に使えるとは思えません。

現実的には256MBというのはそれでも少ないレベルなので、最初からこうするべきではという気はします。ただまあ、64MBのやっすいLinux MCUでなにをやるかが一番面白いところだったんですけどね。

# 気に入らないところ

何でARM（Cortex-A53）を載せる必要があったのか不明です。あとRISC-V側にリアルタイムコアも付いてるので8051もいらいないと思うんですけどねえ。特にARMコアはコスト的にはかなり上乗せになるのでやめて欲しかったです。

milk-v duoのモジュールのMCU変えただけで価格も2ドル強上がっているわけで、狙っている価格帯の製品としては、ちょっと許容できるコストアップではないです。メモリを256MBしにてTPUを0.5→1.0TOPsにするのは良かったんですけど。

全体的に訳のわからないデバイスになってしまいました。自分はロマンを追い求めるのでCV1800Bを追い求めますぞ。
rm -rf アプリ名　というコマンド

ファイルやディレクトリを削除するために使用する

```
 rm -rf アプリ名
```

このコマンドについて備忘録

- `rm`これは「remove」の略で、ファイルやディレクトリを削除するコマンドです。

- `-r`このオプションは「recursive（再帰的）」を意味し、指定されたディレクトリとその中の全てのファイルとサブディレクトリを削除します。

- `-f`「force（強制）」の略で、通常、削除前に確認を求められることなく、すべてのファイルを強制的に削除します。


このコマンドを使用する際には、非常に慎重に行う必要があります。`-rf`オプションは非常に強力で、復元不可能な削除を行うため、間違ったディレクトリやファイルを指定しないように注意が必要です。
quiclyを使ってC++でHTTP/3サーバをお試し実装

# 作ったもの

https://github.com/YasunoriHigashiyama/quic_test


# HTTP/3について

以下の資料が参考になります。多分HTTP/2をそれなりに理解していたほうがいいと思います。

* [n月刊ラムダノート Vol.2, No.1(2020)](https://www.lambdanote.com/products/nmonthly-vol-2-no-1-2020)
* https://github.com/flano-yuki/http3-note
* [QUICをゆっくり解説](https://eng-blog.iij.ad.jp/quic)


# 実装について

[cli.c](https://github.com/h2o/quicly/blob/05d20c7e985ca7dcc25e6787fe830963db5f88a3/src/cli.c)を参考に実装しています。QPACKについては実装していません。


# 試験方法

## ビルド方法

依存ライブラリの以下部分を修正しないとC++だとエラーになります。

* quicly/deps/picotls/t/util.h:306

``` C
// uint8_t *へのキャストを追加する
uint8_t *info = (uint8_t *) malloc(info_prefix.len + end - (src - 4));
```

* quicly/deps/picotls/t/util.h:350

``` C
// uint8_t *へのキャストを追加する
ech.config_list.base = (uint8_t *) malloc(65536);
```

## 試験ツール

とりあえずcloudflareのツールが使えるようなので、それで試します。`--wire-version 1`を指定しないとうまくいかないです。

``` bash
git clone --recursive https://github.com/cloudflare/quiche
cd quiche/
cargo build
./target/debug/quiche-client --http-version HTTP/3 --wire-version 1  --no-verify http://127.0.0.1:4433/hoge1.html http://127.0.0.1:4433/hoge2.html
```

# パケットキャプチャしてみる

上記のquiche-clientは`SSLKEYLOGFILE`変数に指定されたファイルに秘密鍵を出力するので、このファイルを使えば復号化することができます。

``` bash
SSLKEYLOGFILE=hoge.txt ./target/debug/quiche-client  --wire-version 1  --no-verify http://127.0.0.1:4433/hoge1.html http://127.0.0.1:4433/hoge2.html
```

このhoge.txtをwiresharkの「設定→Protocols→TLS」の「(Pre)-Master-Secret log filename」に指定すればOK。
setTimeoutの型注釈がnumber型ではエラーになる理由

## はじめに
実務でsetTimeoutを使うことになりました。
かなりTypeScriptの型推論に振り回されたので、共有したいと思います。

### 自己紹介
私は2023年9月1日にフロントエンドエンジニアとして自社開発のSaaS企業に入社しました。
未経験独学で、薬剤師からの転職です。
詳しくはこちらをご覧ください。

https://qiita.com/odendayoko/items/f616b2f1952897a9af5d

## 結論
setTimeoutの型注釈は以下のように書く。
```typescript
const timeoutId = useRef<ReturnType<typeof setTimeout>>();
```
## 具体例で説明
### 背景
ある条件を満たした時に、フラッシュメッセージを表示するという実装を行う。
まずは表示するロジックを作りたい。
10秒後に消すという要件を満たすために、初めて`setTimeout`を使うことになった。

### 要件
- フラッシュメッセージを表示する
- 表示したフラッシュメッセージは10秒後に消す

### 設計
- フラッシュメッセージの表示ロジック
    - 表示状態を表すstateを定義（boolean）
- 10秒後に消す
    - `setTimeout`使う
    - `timeoutID`を`ref`に入れて管理する
### 問題
以下、私が書いたソースコードです。
```react
const [showFlashMessage, setShowFlashMessage] = useState(false);
const timeoutIdRef = useRef<number>();

// フラッシュメッセージを表示
setShowFlashMessage(true);
// 10秒後に非表示にする
timeoutIdRef.current = setTimeout(() => {
  setShowFlashMessage(false);
}, 10000);
```
まずは表示状態を表すstateを宣言しました。
そして条件を満たした時に、`setShowFlashMessage`でstateを`true`に切り替えて表示します。
次に、[`setTimeout`](https://developer.mozilla.org/ja/docs/Web/API/setTimeout)を使って、10秒（=10000ミリ秒）後に非表示にするようにstateを`false`に切り替えて、非表示にします。
timeoutIDは設計通り、refに入れています。
**返される timeoutID は正の整数値**なので、型はnumberとしました。

しかし、ここでTypeScriptのエラーが出ました。
```
型 'Timeout' を型 'number' に割り当てることはできません。ts(2322)
```
🤔（あれ…number型じゃないの？？）
正しいtimeoutIdの型と解決方法を調べてみました。
### setTimeoutの型
結論から言うと、以下のように書けば良いそうです。
```typescript
const timeoutId = useRef<ReturnType<typeof setTimeout>>();
```
こちらに回答が載っていました。
世界にも同じように悩んだ方がいたんですね！

https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window

どうやら原因は、**TypeScriptのコンパイラがsetTimeout関数の型をNode.js環境向けに推論していること**にありそうです。
ブラウザでは`number`を返すのに対して、Node.jsでは`Timer型（NodeJS.Timer）`を返します。
そのため、ブラウザで正常に動作したとしても、Node.js環境ではエラーになってしまいます。
よって、解決するためには、プラットフォームに関係なく動くような型指定が必要です。

`ReturnType<typeof setTimeout>`で何をしているのかを考えてみます。

まずは[`typeof`](https://typescriptbook.jp/reference/values-types-variables/typeof-operator)でsetTimeoutの型を取得します。
次に[`ReturnType`](https://qiita.com/NOMURA_keibyou38/items/fc9d21aee217b4213430)は、関数の型から戻り値の型を取得するTypeScriptのユーティリティ型の１つです。よって`ReturnType<typeof setTimeout>`と組み合わせることで、setTimeout関数の戻り値の型を取得できるというわけです。
これにより、number型やNodeJS.Timer型など、setTimeout関数が返す型が正確に指定されるため、プラットフォームに関係なく型を指定することができました。

### 実装
timeoutIDの型を変更してエラー解消です！
```diff_typescript
const [showFlashMessage, setShowFlashMessage] = useState(false);
- const timeoutIdRef = useRef<number>();
+ const timeoutIdRef = useRef<ReturnType<typeof setTimeout>>();

// フラッシュメッセージを表示
setShowFlashMessage(true);
// 10秒後に非表示にする
timeoutIdRef.current = setTimeout(() => {
  setShowFlashMessage(false);
}, 10000);
```

## おわりに
TypeScriptの型推論に振り回された話でした。
結果的に、特殊な型指定の方法を学ぶことができました！
今後も出てきそうな実装なので、頭に入れておきたいと思います。

それにしても、同じように悩んだ人が世界のどこかにいるというのは、ちょっと嬉しいですね。
大変助かりました🙏
rails newしたら何が起きるか？

現在、CRUDを学ぶべくTODOアプリを作成していたのですが

以前、Railsを学習したときに

```ruby
rails new アプリ名 _6.0.0_ -d mysql
```

このコマンドを打った事を思い出しました。

しかし、色々な記事や動画、リファレンスを見ていると

```ruby
rails new アプリ名
```

これだけでも雛形が作成できると書いてあります。

### `rails new`したら何が起きているかというと

-  **新しいアプリケーションの「土台」が作成される**：
新しいアプリケーションのための基本的なファイルやフォルダが自動的に作成されます。これは、家を建てる時にまず土台を作るようなものです。アプリの土台ができることで、開発を始める準備が整います。
<br/>

- **必要なファイルの自動生成**：
アプリケーションを開発する際に必要となる多くのファイルが自動的に生成されます。これには、アプリの設定ファイル、初期の画面を表示するためのファイルなどが含まれます。この自動生成機能により、開発者は一から全てを作り出す手間を省けます。
<br/>

-  **開発に必要な「ツール」の設定**：
このコマンドは、アプリ開発に必要な様々なツールやライブラリ（アプリを作る際に使う便利な機能や部品の集まり）の設定も自動的に行います。これにより、開発者はアプリの機能を追加するための準備が整います。
<br/>

 - **カスタマイズの準備**：
生成されたファイルは基本的な形が整っていますが、開発者はこれを自分のアプリに合わせてカスタマイズ（変更や追加）を行います。例えば、新しい機能を追加したり、アプリの見た目を変更したりすることができます。

うんうん、なんかとりあえず `**rails new**` すれば簡単にアプリの雛形が作成されるんだな😅

先日フレームワークを使用せずにアプリを作成してみた私はフレームワークってありがたすぎる事に気づきます。

`rails new`ってすごい！ありがとうRails！(語彙力)

### じゃあ、`rails new アプリ名` だけで雛形が作成されるとしたら、バージョンやDBはどうなっているんだろう？

-  **Railsバージョン**: システムにインストールされている最新のRailsバージョンを使用してアプリケーションを作成される。特定のバージョンを使用したい場合は、`rails _バージョン_ new my_todo_app` のようにコマンドを指定する必要がある。
<br/>

-  **データベース**: RailsはデフォルトでSQLiteをデータベースとして使用される。これは、軽量で設定が簡単なため、開発初期段階や小規模アプリケーションに適しているため。もし別のデータベース（例えばPostgreSQLやMySQL）を使用したい場合は、アプリケーション作成時に `-d postgresql` や `-d mysql` のようにオプションを付けて指定する必要がある。

 なるほど！！！

```ruby
rails new アプリ名 _6.0.0_ -d mysql
```

バージョンとDBを指定して、アプリを作成してたってわけか！

上記のコマンドの `-d` はデータベースの種類を指定するものです。具体的には、このオプションを使うことで、新しく作成するRailsアプリケーションがどのデータベースシステムを使うかを選べます。

再度の説明になりますが、デフォルトは `SQLite`です！

### 指定せずにアプリを作ってしまった！そんな時は

-  **既存のアプリケーションフォルダを削除する**：
最初に作成したアプリケーションのフォルダを削除する。これにより、同じ名前で新しいアプリケーションを作成する際に名前の衝突を避けることができる。コマンドラインでアプリケーションのフォルダに移動し、削除コマンド（例えばLinuxやMacでは **`rm -rf フォルダ名`**）を使ってフォルダを削除する。
**`rm -rf フォルダ名`** -rfオプションは非常に強力で、復元不可能な削除を行うため、間違ったディレクトリやファイルを指定しないように注意が必要です！気をつけて！[rm -rfについて](https://qiita.com/HACHI32/items/76503d4f0e452d9b1097)
<br/>

-  **新しいコマンドでアプリケーションを作成する**：
正しいバージョンとデータベースオプションを指定して、 `rails new`コマンドを再度実行する。例えば、**`rails _6.0.0_ new アプリ名 -d mysql`** 。これにより、指定したバージョンのRailsとMySQLデータベースを使用する新しいアプリケーションが作成される。
<br/>

-  **必要な設定を行う**：
新しく作成されたアプリケーションでは、必要に応じてデータベース設定（**`config/database.yml`**）を確認し、必要な変更を加える。また、他の設定や依存関係も適宜更新することが必要。
<br/>

-  **以前の作業を移行する**：
もし、間違って作成したアプリケーションで既に作業を進めていた場合、必要なファイルやコードを新しいアプリケーションにコピーすることができる。ただし、依存関係や設定ファイルに注意しながら行う。
<br/>

これでアプリを作る時もちょっと安心して作成できますね！

一度で覚えられる人はなかなかいないと思うので繰り返し学習する、なぜ？を大事にするという事を学びました。
Microsoft Power BI で地図利用

## はじめに 🤗 
:::note info
本エントリーは [Microsoft Power BI Advent Calendar 2023](https://qiita.com/advent-calendar/2023/powerbi)の 10日目の記事です。
:::

Microsoft Power BI には地図を使用する機能として幾つかありますが、今回は、Microsoft Power BI にマップのビジュアルとして追加できるアドインの ArcGIS for Power BI について簡単に紹介したいと思います。

## ArcGIS マップについて

ArcGIS for Power BI で使用している ArcGIS (アークジーアイエス) ですが、あらゆる業務で地図を最大限に活用し、迅速かつ合理的な意思決定を実現する GIS プラットフォームを提供しているサービスです。いわゆる、[GIS](https://www.mlit.go.jp/kokudoseisaku/kokudoseisaku_tk1_000041.html) と呼ばれる地理情報システムの機能をプラットフォームとして提供しているサービスです。開発元は、[Esri（エスリ）](https://www.esri.com/ja-jp/home)と呼ばれる米国企業が提供しており、グローバルで事業を展開しています。日本では、[ESRIジャパン](https://www.esrij.com/)という企業で提供しているようです。

https://www.esrij.com/products/arcgis/

ArcGIS for Power BI は、Microsoft Power BI にマップのビジュアルを追加できるアドインで、Power BI の可視化の機能と組み合わせて、データの傾向の把握を強力に支援することができます。
ArcGIS for Power BI の主な機能としては、

- Microsoft Power BI に標準搭載
- 多彩な地図表現
- すぐに使える世界中の豊富なマップ コンテンツ
- 対話的なオブジェクト

が機能として提供されています。

ArcGIS for Power BI の詳細については、以下のサイトをご確認ください。

https://www.esrij.com/products/arcgis-for-power-bi/

また、ArcGIS for Power BI の利用方法についても幾つかドキュメントも提供されており、Microsoft 社が提供している「Power BI で ArcGIS マップを作成する」が参考になります。

https://learn.microsoft.com/ja-jp/power-bi/visuals/power-bi-visualizations-arcgis

また、Esri からは、learn ArcGIS の「ArcGIS for Power BI を試す」も参考になります。

https://learn.arcgis.com/ja/paths/try-arcgis-for-power-bi/

## 渋谷区での事例

実際に ArcGIS マップを使用した事例としては、渋谷区が提供している「渋谷区の「いま」を把握し、「これから」を考えるためのデータ活用プラットフォーム」がございます。

https://shibuya-data.jp/citydashboard/

![2023-12-10_16h17_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/346ab23d-2499-8356-ebca-b89167091578.png)

![2023-12-10_16h17_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102251/e7806cf5-6f9b-9c4a-40b7-88ad07e1889d.png)

## ArcGIS マップの利用について

ArcGIS for Power BI は匿名ユーザーとして無償からの利用が可能です。また、ユーザー タイプとしてそれぞれ用意されており、ArcGIS のライセンスを取得することで、ArcGIS for Power BI のすべての機能も使用できるようになります。

詳しくは以下のサイトを確認していただければと思います。

https://www.esrij.com/products/arcgis-for-power-bi/license/

## まとめ

Power BI 初心者ですが、無償の範囲でも ArcGIS for Power BI と多くの機能が使用できるので驚きでした。簡単な地図の表現程度あれば無償でも良いとは思いますが、GIS としての機能をフルに活用する場合は、ArcGIS のライセンスを使用した方が良いのかなと思いました。

以上、参考になれば幸いです。
rex0220 計算式プラグイン GPTs からの回答で関数を追加

GPTs に計算式の Q&A を作ってもらったりする中で、使えない関数を提案されることがあった。
使えないことを教えるより、関数を追加する方が楽なので追加することにした。

# 概要

GPTs に計算式の問題と解答を作ってもらうと、計算式プラグインでは使えない関数を回答すことがある。
その関数の機能を数個の関数を組合せて実現することは可能ですが、１関数の方が分かりやすいのでいくつかの関数を追加することにしました。

GPTs に関数が使えないことを教えるよりも、関数の使い方を教えることの方がはるかに簡単です。
GPTs は、計算式プラグインに足りない機能を教えてくれる効果もありますね。

# 追加した関数

・MOD 関数を追加。剰余を求める関数。※ % 演算子でも剰余計算は可能
　MOD(10, 3) -> 1
・ARRAY_EQUALS 関数を追加
　２つの配列のすべての要素が等しいか判定。
　ARRAY_EQUALS(ARRAY(1,2,3),ARRAY(1,2,3)) -> true
・ARRAY_EVERY 関数を追加
　配列のすべての要素が特定の条件を満たしているか判定。
　ARRAY_EVERY(ARRAY(1,2,3),XX,XX>0) -> true
・ARRAY_SOME 関数を追加
　配列内の少なくとも1つの要素が指定された条件を満たしているか判定。
　ARRAY_SOME(ARRAY(1,2,3),XX,XX>1) -> true
・ISBLANK 関数を追加
　指定されたパラメータがブランクか判定
Fluentdを一番シンプルに試す

# やりたいこと

- Fluentdを設定し、外部のサーバからのログを受け付けるようにする

# 検証環境

- VagrantでホスティングしたUbuntu Server 22.04 LTS

# インストール

- makeやruby-devがインストールされていないとFluentdのインストールに失敗するため注意

```bash
$ sudo apt update
$ sudo apt install make -y
$ sudo apt install ruby-dev -y
$ sudo gem install fluend
```

# 設定する

- リモートからログを受け取るための設定
- TCPポート24224番で待ち受ける設定
- 受け取ったログを標準出力に出力する設定

```bash
$ vim fluent.conf 
<source>
  @type forward
  port 24224
</source>

<match **>
  @type stdout
</match>
```

- UFWを有効化する設定
- TCPポート24424番への外部からのアクセスを許可する設定

```bash
$ sudo ufw status
Status: inactive

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

$ sudo ufw allow 24224/tcp
Rule added
Rule added (v6)

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
24224/tcp                  ALLOW       Anywhere                  
24224/tcp (v6)             ALLOW       Anywhere (v6)
```

# 起動する

```bash
$ fluentd -c ./fluent.conf
```

# 動作確認

- 擬似的にログを送信するコードをPythonで作成する

```bash
$ pip install fluent-logger
```

```py:client.py
from fluent import sender
from fluent import event

fluentd_host = "192.168.56.10"
fluentd_port = 24224
tag = "my.tag"

sender.setup(tag, host=fluentd_host, port=fluentd_port)

data = {"message": "hello, world!"}
event.Event(tag, data)
```

```bash
$ python client.py
```

- 上記のコードを実行すると、Fluentdの標準出力にログが流れてくることが確認できる

```bash
$ fluentd -c ./fluent.conf
...
省略
...
2023-12-10 05:54:50.000000000 +0000 my.tag.my.tag: {"message":"hello, world!"}
```
Azure 資格勉強法

## Azure 資格勉強法

昨年 Azure や Microsoft 365 の資格をいろいろ取得しましたので、その時の勉強方法を投稿させていただきます。

### 取得した資格
- Azure Solutions Architect Expert
- Azure DevOps Engineer Expert
- Microsoft Cybersecurity Architect Expert
- Microsoft Teams Voice Engineer Expert (*)
- Azure Network Engineer Associate
- Azure Support Engineer for Connectivity Specialty
- Identity and Access Administrator Associate
- Teams Administrator Associate

\* 旧資格で現在はCollaboration Communications Systems Engineer Associate となっています。

## Udemy 

\* 有料
 
以下の Alan さんの Udemy の講座がおすすめです！
トピックごとに以下の順番で進んでいくので学んだことを理解しやすいです。
1. 内容の説明
1. Azure で環境を用意して試してみる（ハンズオン）

音声は英語ですが日本語の字幕を出すことができて、実際の Azure の画面を出しながら説明してくれるので分かりやすいと思います。

さらに練習問題もついているので受験前の知識の確認もばっちりです。こちらも英語になっていますがブラウザの機能で日本語に翻訳できます。

Udemy で有料ですが、セールの時であれば各講座 1,000 円くらいで買えます。

https://www.udemy.com/course/exam-az-microsoft-azure-exam-role1/

https://www.udemy.com/course/azure100/

https://www.udemy.com/course/azure200/

https://www.udemy.com/course/azure-exam-700/

https://www.udemy.com/course/azure-exam-1/

以下は Teams の資格の講座で別の講師の方ですがこちらもおすすめです。

https://www.udemy.com/course/microsoft-teams-examlabpractice/

## Youtube

\* 無料

以下の Savil さんのチャンネルがおすすめです！
こちらも音声は英語ですが日本語字幕を表示できます。

https://www.youtube.com/@NTFAQGuy

現役の Microsoft 社員の方 (?) のようで、ホワイトボードを使って講義形式ですごく丁寧に説明してくれます。アイアンマンレースとかも出られてるみたいでめちゃくちゃ強そうです(笑)

https://www.youtube.com/watch?v=vq9LuCM4YP4&t=3s&pp=ugMICgJqYRABGAHKBQtKb2hvbiBzYXZpbA%3D%3D

https://www.youtube.com/watch?v=nVZYDhB_M64&list=PLlVtbbG169nGeFODKRZhjqdSxFpSPXVOa&pp=iAQB

https://www.youtube.com/watch?v=6vISzj-z8k4&list=PLlVtbbG169nHw9T1L_CiLxC-DTwKu-BZG&pp=iAQB

https://www.youtube.com/watch?v=2Qu5gQjNQh4&list=PLlVtbbG169nHcbeVtWUfP8BeEjGniBJeb&pp=iAQB

https://www.youtube.com/watch?v=LGpgqRVG65g&list=PLlVtbbG169nGj4rfaMUQiKiBZNDlxoo0y&pp=iAQB

他にも、Azure の各サービスについての解説や、毎週 Weekly Update として Azure の更新情報の解説動画を配信してくれていてためになります。


## おまけ

Udemy にはその他にもいろいろ Azure / Microsoft 365 資格の講座が販売されていて、練習問題だけのもの販売されています。その内容を見ると、実際の試験問題と全く同じ内容の問題も販売されていたりします。

さすがにグレーだと思うのですが、仕事の都合などでどうしても期日までに資格を取らないといけない、といった場合は頼るのもありだと思います。
Workato：SQL Transformationを活用して、Workatoで簡単にデータを変換する方法の紹介

今回は、Workato上の「SQL Transformation」というアプリの使用方法を紹介したいと思います。
# はじめに
SQL Transformationは、以下の操作を実現したいな方におすすめです：
・変更データキャプチャ（CDC）の実現：データの変更は簡単に追記できます。
・データの標準化/クレンジング/変換の実現
・データエンリッチ化：SQLのJoin操作で、複数のソースからデータを結合します。

# 使用方法
レシピのActionsで「SQL Transformations by Workato」を選択、設定を進めます。
**⒈データソースの設定**
![Screenshot 2023-12-10 at 15.10.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635209/4777371f-cfd1-cdd1-2787-580e003566e9.png)
**1.1 Data Source name**
ソース表に別名を入力します。
**1.2 Data source type**
データを取得するデータソースタイプを選択します。CSV stream inputとFileStorage file path二種類を選んできます。
**1.3 Data schema**
データを照会するために、データスキーマを設定する必要があります。スキーマ入力で提供された上から下への列名は、実際のデータの左から右への列と順序が一致します。スキーマと実際のデータのカラム数が一致しない場合、エラーを出ている可能性があります。
**1.4 Ignore CSV header row**
CSVヘッダー行を無視するがどうかをために設定しています。デフォルトではNOで無視されていないです。
**1.5 Column delimiter**
CSVデータの区切り文字の種類を選択します。

**2.クエリの設定**
必要なクエリーステートメントを入力します。
![Screenshot 2023-12-10 at 15.33.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635209/35461061-eb4c-4dff-e159-95a98738825c.png)
例をとして、指定されたデータ構造から新しい形式に変換するを入力しました。UNION ALL句を使用して、異なる列からのデータを単一の列に結合することができます。

**2.出力の設定**
![Screenshot 2023-12-10 at 15.37.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635209/9200a86b-ab19-0275-b3a7-7dd1f81e6085.png)
最後は、出力タイプや出力データ内容の他の特定のオプション機能を設定することができます。

# 終わりに
[Workato：公式ドキュメント](https://docs.workato.com/features/sql-transformations.html "公式ドキュメント")
最後は、Workatoの公式ドキュメントを活用しましょう！ここでは、いくつかのSQL Transformationのユースケースを紹介しましたので、ぜひ活用してください。

もし、もっと詳しくを知りたい方がいましたら、このコースも非常に良い勉強資料です：[Workato：Advanced data transformations with SQL, Python, and Javascript](https://www.workato.com/product-hub/advanced-data-transformations-with-sql-python-and-javascript/ "Advanced data transformations with SQL, Python, and Javascript")
軽深演習 #10 終了する


### 軽深（かるしん　なんちゃって圏論） Advent Calendar 2023 10日目の記事です。

演習形式をとっているので、ぜひ　回答を試みてください。


### 前提知識　終了する

圏は、射つまり矢印が重要です。私達は、普段よく矢印をつかっています。そんな矢印で圏論的な解釈をすると仕事の効率をあげることができます
忙しい人には朗報です。

仕事の流れは、図式で書くとこうなります。効率化の議論は、多くの場合、実行についてのものが多い気がします。実際には、これでやりとげることができると開始段階で見通しをたてることが重要です。
私の体験からは、自信はないけど、行けそうだと見通しがたったところで、システム構築に踏切り、
大手上場企業向けのサービスをリリースしました。

```mermaid
flowchart LR
A[開始]-->B[実行]-->C[終了]
```

終了できるかどうかを事前に判断することは非常に難しいです。でも、無理やり終了させるぞとモチベーションをやる気を高めることが可能です。
終了を意識するだけで、多くの気づきがあるはずです。
小学生でもすぐわかる図式ですが、実際の仕事で終了判定条件が事前に実践的に確実に設定されているんでしょうか？　大阪万博をみればそうとはとてもいえません。そんなわけでせめて締め切りの効果だけを思い起こしましょう。
演習　**終了する**　を提示します。

### 演習　締め切りを設定すると工夫や、知恵がでてくるものです。部屋の片付けですが、北海道の甥っ子夫婦が宿泊することになり、必死でやったら、なんとかなりました。締め切りがあるおかげでできたことは、どんなことがりますか？
1TBで3,000円？


![DALL·E 2023-12-08 15.00.16 - A person looking frustrated and disappointed, holding a plain, fake, low-quality USB memory stick. The USB stick should have no wires, hair-like stran.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/55f02d4d-6a18-b0af-98a9-b83a02febea3.png)

# はじめに

まんまと騙されました。そんな上手い話があるわけない。

# TVチューナーの録画用に購入したのがきっかけで。。。

Xit AirBoxというTVチューナーを購入しました。自宅のパソコンでTVを観るのはもちろんのこと、外出時であってもスマフォで現在放送中のTVや録画したTVが見れる面白い製品です。
私はもっぱら、埃をかぶっていた2019年購入のAmazon HD Fire 8を使ってTVを観ています。(便利だなー)
このチューナーは、それほど高機能とは呼べないのですが、価格が安い、TV録画が可能(クラウドorUSB)という特徴を持っています。

と言うことで、そこそこ容量が大きくて、料金がお手頃のUSBメモリを探していたところ、あるUSBメモリに辿り着きました。
なんと、3,000円そこそこで、1TBと正に求めていた商品です。
![Untitled1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/b1eea7fa-4bff-6d0c-118f-1ae0d4025456.png)

不覚にもあまり考えずにポチりました。それが運の尽き。

# 何かがおかしい。。。
私が今ハマっているNHK朝ドラの『ブギウギ』を、Xit AirBoxで毎日録画をしております。
たまたまお客様コールが9時からという日がありまして、その日は『ブギウギ』をリアルタイムで見ることができませんでした。
自宅に戻り、夕食を取った後に早速再生をしてみます。
録画リストにはちゃんと表示があります。
さっそく再生を始めるのですが、一向に映像が現れません。
「あれ？調子悪いのかな？Xit AirBoxをリブートしてみるか」とリブートを試すも改善せず。
次はUSBの抜き差しを試しますが、改善せず。 
「もしかして、世間で言われている偽造USBメモリを掴んでしまったのか？」

# いざ、調査！

単純にWindows10を使って容量を確認すると、

**Windows10 ディスクの管理画面**
![Screenshot 2023-12-08 132434.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/ad661ab3-6f77-ecb0-41f7-17c64037ac4a.png)

Windows10は、刺さっているUSBメモリは976.56GB(ほぼ1TB)だと示しています。

ここで安心してはいけません。偽造USBは見掛けの容量を偽造しています。
そこで登場するのが容量偽装を見破るためのツールです。
私は、**H2testw**を使用しました。容量が多かったせいもあり、結果が出るのに4日弱かかりました。
結果は!!??
* 書き込みエラーが発生している
* 書き込み速度が異常に遅い

(注) 実はスクリーンショットを取り損いまして、他の方が取得されたスクリーンショットをお借りしております

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/6d8662f9-eaa6-1ee8-0d26-1f1fcf6ebd79.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/4ea83f50-9082-9488-bdf6-ac5af332eb57.png)

とあり、やはり、容量偽造USBメモリ確定です。

https://win-tab.net/deskapp/h2testw_2109073/

# 終わりに

「損しちゃった」という状況で落ち込んでいるかといえば、その逆で、今は騙されないようにするためのお守りとしてカバンにつけて毎日歩いております。

**撮影用に一時的にバックパックから取り外して撮影しました**
![mo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/73872526-d5b5-4b50-b92e-6cb90795cb51.jpeg)


# 参考

https://akiba-pc.watch.impress.co.jp/docs/sp/1502734.html

https://korekore.sakura.ne.jp/h2testw_1tb/

https://win-tab.net/deskapp/h2testw_2109073/

https://www.pixela.co.jp/products/xit/
KalidoKitのPoseがReactで動くサンプルを作成した

# 背景
[Kalidokit](https://github.com/yeemachine/kalidokit)はブラウザ上でWebカメラを使ってVRMモデルを動かせる素晴らしいツールですが、`docs`以下になるサンプルが生jsで書かれており、poseをReact componentとして動かすサンプルは(自分の探した限り)見つかりませんでした。

また、公開が2021年ということもあり、three-vrmの最新バージョンに対応していなかったりと不便なところがありました。

# 説明
サンプル作成しました↓
https://github.com/one-color-low/kalido-react
WSL2で快適なzsh環境を作る

## この記事の終着点

- WSL2で **「強靭！無敵！最強！」** な環境を作る。
- ZSHを触ってみる

## Bashはいいけど見た目が嫌い

個人的な話なんですが、Bashの見た目がどうしても嫌いなんですよね。  
なんか、 **THE TERMINAL** って感じがしません？
モダンに行こうぜ(過激派)

## ターミナルをZSHにする (改宗)

### zshインストール
```sh
sudo apt install zsh
```
でインストール可能。
```sh
chsh
```
で
```
/usr/bin/zsh
```
にして、初期ターミナルをzsh化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821686/5e459eb8-9a14-77e3-f39e-a335b62c062a.png)
適当に設定して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821686/d311ad03-eaf4-d1ea-1839-c53c2cf9df4c.png)
おん、見にくいなお前
### Oy my zshを導入
公式からの教えに従い
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
```
で導入する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821686/a1062fef-0cce-d522-41f4-1e0da53089ff.png)
ミニマルすぎんか？好きだけど。

### powerlevel10kを導入
自分好みのテーマがほしい。
Oh My Zshの拡張機能としてテーマをたくさんインストールできるらしい。
```
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
```
しかもクローンするだけ。便利な時代だなぁ。
最後に
`ZSH_THEME="powerlevel10k/powerlevel10k"`を`~/.zshrc`に記述するだけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821686/00dadbc4-7c6a-97fb-dfe5-f8ee4eb3db57.png)
セットアップが始まると。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821686/9c390afe-1959-c97e-ebb5-d23e8e1f4edf.png)
自分はこんな見た目に落ちつきました。美しい。

## おわりに
乗り換えてみましたが特に手こずることもなく簡単にできました。
見た目もよし！
zsh!zsh!zsh!

以上！
Crystalでclifford attractorを描出したった

## はじめに

アドベントカレンダーですが、ネタがありません。そこで Crystal で Clifford Attractor を描くのをやってみました。Clifford Attractor は簡単にかけて綺麗ですのでこういうネタ切れのときに重宝します。

![clifford.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/f61eb4b4-6903-6874-04d5-71ccbb0490c0.png)

### Clifford Attractor生成

```cr
n = 2000000  

a, b, c, d = -1.3, -1.3, -1.8, -1.9
θ = 0.007

xs, ys = [0.0], [0.0]

n.times do |i|
    xs << Math.sin(a * ys.last) + c * Math.cos(a * xs.last) * Math.cos(θ)
    ys << Math.sin(b * xs.last) + d * Math.cos(b * ys.last) * Math.cos(θ)

    θ += 0.007
end

# p! xs
# p! ys
```

### 画像のサイズをスケールする準備

```cr
x_min, y_min = xs.min, ys![clifford.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/bc06d4a0-b23b-3345-f5c4-98d01b4be7be.png)
.min
x_max, y_max = xs.max, ys.max

display_size = 4000
offset = 100
area_size = display_size - offset * 2
scale = area_size.to_f / [x_max - x_min, y_max - y_min].max
```

### 画像にする配列を作成

```cr
# Create black (false) 2d array
image_arr = Array.new(display_size) { Array.new(display_size, false) }

# Draw fractal on array
n.times do |i|
  x_pos = ((xs[i] - x_min) * scale + offset).to_i
  y_pos = ((ys[i] - y_min) * scale + offset).to_i

  image_arr[y_pos][x_pos] = true
end
```

## 画像書き出し

今回は単純に[PBM形式](https://ja.wikipedia.org/wiki/PNM_(%E7%94%BB%E5%83%8F%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88))で書き出すことにしました。高速ですがファイルサイズは大きくなります。ちなみに、PBMを出力する関数は ChatGPT 書いてもらいました。すごいですね。

```cr
# Write PBM file
File.open("clifford.pbm", "w") do |f|
  f.puts "P1"
  f.puts "#{display_size} #{display_size}"
  image_arr.each do |row|
    row.each do |pixel|
      f.print pixel ? "1 " : "0 "
    end
    f.puts
  end
end
```

### 全体

全体像は上をつなげてこんな感じです。

```cr
n = 10000000

a, b, c, d = -1.3, -1.3, -1.8, -1.9
θ = 0.007

xs, ys = [0.0], [0.0]

n.times do |i|
  xs << Math.sin(a * ys[i]) + c * Math.cos(a * xs[i]) * Math.cos(θ)
  ys << Math.sin(b * xs[i]) + d * Math.cos(b * ys[i]) * Math.cos(θ)

  θ += 0.007
end

x_min, y_min = xs.min, ys.min
x_max, y_max = xs.max, ys.max

display_size = 4000
offset = 100
area_size = display_size - offset * 2
scale = area_size.to_f / [x_max - x_min, y_max - y_min].max

# Create black (false) 2d array
image_arr = Array.new(display_size) { Array.new(display_size, false) }

# Draw fractal on array
n.times do |i|
  x_pos = ((xs[i] - x_min) * scale + offset).to_i
  y_pos = ((ys[i] - y_min) * scale + offset).to_i

  image_arr[y_pos][x_pos] = true
end

# Write PBM file
File.open("clifford.pbm", "w") do |f|
  f.puts "P1"
  f.puts "#{display_size} #{display_size}"
  image_arr.each do |row|
    row.each do |pixel|
      f.print pixel ? "1 " : "0 "
    end
    f.puts
  end
end
```

完全に一発芸ですね。できあがった画像は ImageMagick のコマンドを使ってPNGに変換します。まあCrystalのライブラリとか使って頑張ってもいいのですが、素直にコマンド操作した方が楽だと思います。

```
convert clifford.pbm -resize 1000 clifford.png
```

この記事は以上です。
Github ActionsでDocker Imageが自動ビルドされるようにしてみた話

## はじめに
前回はfluxを使ってhelmやkustomizeを自動で適用できるようにしました。

https://qiita.com/piny940/items/e99fea7fcba720047b11

今回は、前々回導入した自動デプロイ機能に関連して、自動ビルド基盤を作っていこうと思います。

完成品はこちらのリポジトリで公開しています。
https://github.com/piny940/portfolio

## 権限の設定
レポジトリの設定から、ワークフローに権限を与えます。

![workflow permission](https://user-images.githubusercontent.com/1736354/187890839-2f26ce10-2e20-4d7e-ab6e-311c898fc416.png)

![actions permissions](https://user-images.githubusercontent.com/9700541/187891526-5938feb5-d380-4574-a81a-9b621779dead.png)

参考: https://github.com/docker/build-push-action/issues/687

## workflowを設定
`.github/workflows/release.yaml`に次のように記述
```yaml
name: Docker Build for Release
on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  frontend:
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v3

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: Githubアカウント名
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Build and push Docker images
        uses: docker/build-push-action@v5
        with:
          push: true
          context: .
          file: Dockerfile
          tags: |
            ghcr.io/Githubアカウント名/アプリ名:v1.0.0-${{ github.sha }}-${{ github.run_number }}
            ghcr.io/Githubアカウント名/アプリ名:latest
```
2~5行目: mainブランチにpushされたときにworkflowを実行します。
6行目: 手動でフローを実行できるようにします。
12~17行目: ghcr.ioにログインします。
20~28行目: DockerイメージをBuild・Pushします。

これでmainブランチにpushしたら自動でDockerイメージがビルドされるようになります。作成されたImageはGithubの`Profile > Packages`から確認できます。

## 最後に
今回はGithub Actionsを用いて自動ビルドの基盤を整えました。次回はStaging環境の作成に挑戦したいと思います。

## 参考資料

https://docs.docker.com/build/ci/github-actions/

https://qiita.com/chroju/items/d98ea757f906a9b5d683

https://github.com/docker/build-push-action/issues/687
Laravel初心者向け、よく使うCollectionの整形系メソッド

## 概要

自分が普段仕事で良く使うCollectionのデータ整形系メソッドを抜粋して紹介します。
EloquentCollection特有のメソッドは除外しています

## 一覧

### map
mapメソッドは、クロージャを利用して、各要素を整形します。

```php
$people = collect([
    ['name' => 'John', 'age' => 30],
    ['name' => 'Jane', 'age' => 25],
    ['name' => 'Doe', 'age' => 30],
]);

// 各人の名前を大文字に変換して新しいコレクションを作成
$uppercasedNames = $people->map(function ($person) {
    return [
        'name' => strtoupper($person['name']),
        'age' => $person['age']
    ];
});

dd($uppercasedNames->all());

// 結果:
//array:3 [▼ 
//  0 => array:2 [▼
//    "name" => "JOHN"
//    "age" => 30
//  ]
//  1 => array:2 [▼
//    "name" => "JANE"
//    "age" => 25
//  ]
//  2 => array:2 [▼
//    "name" => "DOE"
//    "age" => 30
//  ]
//]

```

https://readouble.com/laravel/10.x/ja/collections.html#method-map

### mapWithKeys
mapWitKeysメソッドは、クロージャを利用して各要素のキーと値を整形します。

```php
$people = collect([
    ['name' => 'John', 'age' => 30],
    ['name' => 'Jane', 'age' => 25],
    ['name' => 'Doe', 'age' => 30],
]);

// 名前をキー、年齢を値とする連想配列を作成
$keyedData = $people->mapWithKeys(function ($person) {
    return [$person['name'] => $person['age']];
});

dd($keyedData->all());

// 結果:
//array:3 [▼ 
//  "John" => 30
//  "Jane" => 25
//  "Doe" => 30
//]
```

https://readouble.com/laravel/10.x/ja/collections.html#method-mapwithkeys

### flatten
flattenメソッドは、どのような多次元の配列であればフラットな配列に整形します。
```php
$nestedArray = collect([
    ['John', 'Jane', 'Doe', 'colors' => ['orange', 'black', 'white']],
    ['PHP', 'Laravel', 'JavaScript'],
    [30, 25, 30],
]);

// 多次元の配列をフラットな配列に変換
$flattenedArray = $nestedArray->flatten();
dd($flattenedArray->all());

// 結果:
//array:12 [▼ // app/Filament/Pages/Dashboard.php:33
//  0 => "John"
//  1 => "Jane"
//  2 => "Doe"
//  3 => "orange"
//  4 => "black"
//  5 => "white"
//  6 => "PHP"
//  7 => "Laravel"
//  8 => "JavaScript"
//  9 => 30
//  10 => 25
//  11 => 30
//]
```

https://readouble.com/laravel/10.x/ja/collections.html#method-flatten

### flatMap
flatMapメソッドは、flattenメソッド と mapメソッド を合体させたようなメソッドで、
クロージャを利用して整形した要素を、フラットな配列に変換します。

```php
$people = collect([
    ['name' => 'John', 'age' => 30],
    ['name' => 'Jane', 'age' => 25],
    ['name' => 'Doe', 'age' => 30],
]);

// 各人の年齢を2倍にして1つのコレクションにまとめる
$flatPeople = $people->flatMap(function ($person) {
    return [$person['name'], $person['age'] * 2];
});

dd($flatPeople->all());

// 結果: 
//array:6 [▼ // app/Filament/Pages/Dashboard.php:36
//  0 => "John"
//  1 => 60
//  2 => "Jane"
//  3 => 50
//  4 => "Doe"
//  5 => 60
//]
```

https://readouble.com/laravel/10.x/ja/collections.html#method-flatmap


#### 実際に書くようなコード
DevelopmentApprovalオブジェクトが羅列されている

```php
$this->projects->flatMap(function(Development $development){
    return $development->developmentApprovals);
});

// DevelopmentApprovalモデルオブジェクトが羅列されている一次元配列が出来上がる
```
Okta - 便利なChrome拡張機能 - rockstar

# はじめに

今回はOktaの様々なデータをCSVでダウンロードすることができるChrome拡張機能「rockstar」について記載していきます。

# rockstar

https://chromewebstore.google.com/detail/rockstar/chjepkekmhealpjipcggnfepkkfeimbd

# 使い方
## ユーザーのリストを取得

Directory > People を開き、rockstar から Export Users を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/618f7fd9-5ea2-730a-0eca-7e43be2a436d.png)

エクスポートしたい属性値を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/ee23cd9b-2d59-cae2-c6e3-92f0d8ee690f.png)

Profile Editor で追加したカスタム属性値も選択できます。
OktaのReportsの機能でユーザーのリストを出力することはできますが、カスタム属性値は対象にできません。
カスタム属性値をエクスポートしたい場合は rockstar を使うと簡単です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/a014484f-e376-1f7c-564a-58f01d66cedd.png)

Export ボタンを選択するとCSV形式でダウンロードできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/f5f166f4-fa07-a835-e3c1-6d2ba356fc4a.png)

ちなみに、Peopleからユーザーを選択した後は rockstar が以下のようになります。
パスワードの設定とかできそうですね（やったことないですが）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/65628b5c-8dc6-9d34-752b-b41ef604ce2e.png)



## グループのリストを取得

Directory > Groups を開いて、rockstar から Export Groups を選択します。
選択するとCSVのダウンロードが始まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/9ba4c525-ab8a-8b0f-05b5-7f25564d4440.png)


## グループルールのリストを取得

Directory > Groups を開いて、rockstar から Export Group Rules を選択します。
選択するとCSVのダウンロードが始まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/c2e70267-3847-ee53-8a9a-46dc52c63965.png)


## アプリのリストを取得

Applications > Applications を開いて、rockstar から Export Apps を選択します。
選択するとCSVのダウンロードが始まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/7714ca1b-1a82-5e6a-a7fe-289b08a6d77e.png)

Export Apps (custom) を選択するとエクスポートする項目を選択できます。
選択可能な項目は以下の通りです。
- App Id
- Name
- Label
- Status
- Created Date
- Last Updated Date
- Sign On Mode
- Features
- Username Template
- AWS Identity Provider ARN
- SSO ACS URL
- Post Back URL
- Embed Links

## 任意のAPIを実行する

任意の画面で rockstar から API Explorer を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/e8382cb3-a980-4ffc-59dd-4abcd426da54.png)

メソッドとAPIエンドポイントを指定して Send でAPIを実行することができます。
正直GET以外は使いたくないです。GETはサクッとできるのでお勧めです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/236a920e-732d-5e20-33cd-fc5775b244f1.png)


# さいごに

rockstar を使うことで簡単にデータをエクスポートすることができるのでお勧めです。
この拡張機能を知る前は頑張ってGASでツール作ったりしてました。
もちろんできないこともありますが、ツールを作る前にまずrockstarでできないか？は確認してみてもよいと思います。

今回はここまで。ありがとうございました。
完全初心者がモバイルアプリを作成するまでの備忘録_事前勉強編

タイトルの通り、モバイルアプリ未経験の筆者が何とかしてリリースまでこぎつけるまでの備忘録。都度追記したりするはず。

# 前提 #

筆者のスキル

- SES７年目
- 使える言語はjavaのみ
- サーバサイドしか触っておらず、JavascriptはおろかHTMLも書き方がよくわかっていない

# 環境

~~macOS Monterey ver.12.7.1~~
macOS Sonora 14.2.1 ※2023/12/23追記

※都度追記していく

# なんでモバイルアプリ作ろうと思ったの？

諸々あってスキルアップのため、何かしら自己学習せねばと考えた。

# この記事の目的

初心者がいきなりモバイルアプリを作るのは不可能なので（確信）、とりあえず事前に勉強したことを書き連ねていく。

## homebrew ※2023/12/23追記
macOSのパッケージ管理ツール。macで開発するならとりあえずこれ入れろってものらしい。

## React native

モバイルアプリ開発用のフレームワーク。一回コードを書けばiOSとAndroidの両方のアプリが作れちゃうらしい。
ベースはJavascriptのフレームワークであるReact。
流し見した記事ではこれがモダンらしいと判断して採用。
他にもFlutterやXamarin、Cordovaなんかも見たが、言語の関係から今回はパス。
Javaしか触ってこなかった筆者にとってDartやC#の学習コストはさすがに高すぎると判断。

## Expo

どういうものかは結局調べてもよくわからなかった。アプリをデプロイしてテストする際に、AppStoreを介さず実機に持ってこれるらしい。よくわからないけどこれぐらいの理解でいいでしょ

## Node.js

サーバサイドのJavascript実行環境。Javascriptでアプリケーションを開発するなら必須。とにもかくにもNode入れろ。

## yarn

javascriptのパッケージマネージャ。APIとかをインストールするときにこれがないと一個一個正しい位置に配置して…とかやらなきゃいけないので必須。
node.jsにはnpmというパッケージマネージャが標準で搭載されているが、yarnのほうが早いらしい。特に深い理由はないが使ってみることにする。



コメントにて訂正、指摘などお待ちしております。
角ばった形状は保持しつつカーブを滑らかにする

# 概要

Houdiniはカーブ全体を単純に滑らかにするのは簡単に出来ますが、下図のように角ばった形状は保持しつつ滑らかにするのは工夫が必要です。

![](https://paper-attachments.dropboxusercontent.com/s_8E0136D5FDC1C9F1FF2B2276E5E4AEBA57BFFAF2FC5D5BC3F954612697E4DF40_1702183647128_2023-12-10_13h11_33.png)

![](https://paper-attachments.dropboxusercontent.com/s_8E0136D5FDC1C9F1FF2B2276E5E4AEBA57BFFAF2FC5D5BC3F954612697E4DF40_1702183672146_2023-12-10_13h11_46.png)


この記事で紹介する手法は特徴点を取得し、その場所を基準にカーブをバラバラにしてから滑らかにする手法です。

# 特徴点の取得

まずPoint Wrangleで、特徴点を取得します。
特徴点の指定はポイントの角度を基準に、一定角度以下のポイントをグループに登録します。
```C#
    // 隣のポイントを取得
    int nb_pts[] = neighbours(0, @ptnum);
    // 隣にあるポイントの数が2個じゃなければ処理を飛ばす
    if (len(nb_pts) != 2)
        return;
    // 隣のポイントの位置を取得
    vector p0 = point(0, "P", nb_pts[0]);
    vector p1 = point(0, "P", nb_pts[1]);
    // 隣の位置に向かうベクトルを取得
    vector dir0 = normalize(p0 - @P);
    vector dir1 = normalize(p1 - @P);
    // 角度の取得
    float dot = dot(dir0, dir1);
    float angle = degrees(acos(dot));
    // 一定角度以下ならグループに登録
    i@group_feature = angle < chf("angle_threshold");
```
![](https://paper-attachments.dropboxusercontent.com/s_8E0136D5FDC1C9F1FF2B2276E5E4AEBA57BFFAF2FC5D5BC3F954612697E4DF40_1702183681904_2023-12-10_13h03_10.png)


ここでは120度以下のポイントを`feature`というグループに登録しました。

# 特徴点を基準にカーブを切り分ける

取得した特徴点を基準にカーブを切り分けていきます。
まずはすべてのポイントをばらばらにします。
カーブのすべてのポイントをばらばらにするには`Convert Line`を繋げてから`Split Points`を繋げます。
見た目は変わっていませんが、エッジごとにカーブが分かれた状態で切り分けられます。

![](https://paper-attachments.dropboxusercontent.com/s_8E0136D5FDC1C9F1FF2B2276E5E4AEBA57BFFAF2FC5D5BC3F954612697E4DF40_1702184270094_2023-12-10_13h09_14.png)


次にFuseノードを繋げ、Group欄に`!feature`と指定し(!を付けることで指定したグループ以外になります)、先ほど取得した特徴点以外のポイントを繋げます。
ただそのままではプリミティブは分かれたままなので、`Poly Path`を繋げてポイントが繋がってる場所は一つのカーブになるようにする必要があります。

![](https://paper-attachments.dropboxusercontent.com/s_8E0136D5FDC1C9F1FF2B2276E5E4AEBA57BFFAF2FC5D5BC3F954612697E4DF40_1702184308413_2023-12-10_13h09_53.png)

# 滑らかにする

最後にResampleノードを繋げ、間隔を設定し、**Treat Polygon As**を**Subdivision Curves**にするとポイントを増やしながらカーブを滑らかに出来ます。

![](https://paper-attachments.dropboxusercontent.com/s_8E0136D5FDC1C9F1FF2B2276E5E4AEBA57BFFAF2FC5D5BC3F954612697E4DF40_1702184343380_2023-12-10_13h11_08.png)


一連の流れのhipファイルは下記にアップしています。説明上開いたカーブで説明しましたが、hipファイルでは閉じたカーブで行ってます。
もしもっと良い方法を知ってる方がいれば[Twitter](https://twitter.com/d658t)かコメントで教えてください。

https://www.dropbox.com/scl/fi/d46if49cd8cppeehjhsh7/SmoothCurves.hipnc?dl=0&rlkey=tdnp72jpkt6h54qxcoh8ztpsc
Microsoft マネージド条件付きアクセス ポリシーで条件のひとつとなっていた「ユーザーごとの MFA」について

2023 年 11 月から 12 月後半にかけて、「Microsoft マネージド 条件付きアクセス ポリシー」の機能が導入されることが先日発表されました。
「Microsoft マネージド 条件付きアクセス ポリシー」とは、2020 年に Microsoft Entra ID (旧 Azure AD) で導入された「セキュリティの既定値群」の条件付きアクセス版のようなものです。

この機能は、Microsoft Entra ID P1 および P2 ライセンスを持っているにもかかわらず、まだ条件付きアクセス ポリシーを有効活用していないと思われるテナントに対して、自動的に条件付きアクセス ポリシーが作成される機能です。
この機能の有効化対象となったテナントでは、以下の 3 つのポリシーがテナントに自動的に作成されます (必ずしも 3 つ全てが作成されるわけではありません)。

・Microsoft 管理ポータルへアクセスする管理者に多要素認証を必須とする
・「ユーザーごとの MFA」 機能を使用しているユーザーに多要素認証を必須とする
・リスクの高いサインインに対して多要素認証と再認証を必須とする

詳細は以下の公開情報に情報があります。
https://learn.microsoft.com/ja-jp/entra/identity/conditional-access/managed-policies

この「ユーザーごとの MFA」機能が若干公開情報などを確認してもわかりずらかったのでこちらでまとめました。

「ユーザーごとの MFA」は Microsoft Entra ID ポータルの以下の画面の赤枠からいくことができる機能のことをさします。
![mfa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3081934/ac0e8986-dc69-4f02-f65e-47df3be3efcd.jpeg)

実際に画面遷移した絵は以下となります。
![mfa2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3081934/fd8dba6f-dfb4-b490-7e23-25e8ef2ff8b3.jpeg)

URL の部分をみると "windowsazure" なる文字もある通り、このページは昔 MFA を設定する際に利用されていたページで今はこちらからの設定は推奨されていません。
その為今回の Microsoft マネージド条件付きアクセス ポリシーでの制御対処になったものと思われます。
炎上案件が初PMだった去年の自分へ捧ぐ、プロジェクトマネジメントの勘所〜契約書編〜

# はじめに
元々バックエンドエンジニアをしていた筆者。
プロジェクトマネージャーが休職や退職で、複数の案件がPM不在となり急遽プロジェクトマネージャーとして案件を担当することに。
引き継ぎもなくPMとしてアサインされた案件は、n億円規模の新規モバイルアプリ開発。
見るからに遅延していて高稼働なメンバーたち。
案件のルールや各メンバーの責任範囲が不明瞭、開発するものがどこまでの範囲かメンバーもわかっていないなどなど、火種がそこら中にある状態。
そんな中、PMとして立ち回り、あの時こうしておけばよかったと考えた事を振り返りたい。

# 契約書
まずは契約書を見る。
契約書には大体下記の内容が書かれているはず。

・プロジェクトの範囲
・契約（請負か準委任か）
・納期とスケジュール
・変更管理
・品質保証と保証

上記の内容をおさえた上で、案件の現状が契約した内容とどれだけズレているか把握をしていくのが第一歩。
特に、QCDに関わる内容がどうなっているかが重要。
品質はどこまで担保しないといけないのか、コストを掛けてもよいのか、納期は絶対にズラせないのかなど、炎上している状態から正常に持っていく為にQCDは指標になる。
案件にアサインされた当時は、目の前にある課題を一生懸命潰そうとしていたが、契約を知った上で課題を見て対処する優先順位をつけるべきだった。

ちなみに、社長の知り合いの会社の案件だったからなのか、契約の内容が大雑把で上に書いている内容も詳細には書かれていなかった。
炎上していた原因は契約の段階からだったのかもしれない。

# おわりに
契約書は発注者と受注者で合意した内容。
契約書には、責任範囲やお金が発生するのはどういう時か記載されている。
記載されている条件を念頭に置いておかないと、お客様と交渉する時に観点がズレた事を言ったり、契約の範囲に無い無駄な作業をしてしまう場合もある。

筆者自身PMとしての経験は浅いので、こういう観点もあるよなどあれば是非コメントいただけると嬉しいです。
Windowsでのdocker導入からlaravelプロジェクト立ち上げまでメモ

## 概要
windowsマシンでlaravel環境の立ち上げ(filamentのキャッチアップ)をしようとした際の諸々環境構築を記事にします。

## 手順
dockerインストールは省略

https://chigusa-web.com/blog/windows%E3%81%ABdocker%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6python%E7%92%B0%E5%A2%83%E3%82%92%E6%A7%8B%E7%AF%89/#%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89

## wsl2インストール
コマンドプロンプトから以下のコマンドを叩く
```terminal
$ wsl --install
```


## ubuntu内に環境構築する準備
windowsの中にプロジェクトファイルを置くと重くなるらしいので、ubuntu内にプロジェクトファイルを置く準備


1. Docker Desktop for Windows を起動します。
2. [Setting] > [Resources] > [WSL Integration] に移動します。
3. [Enable integration with additional distros:] で “Ubuntu-22.04” を ON にします。
4. [Apply & restart] をクリックします。


https://blog.soln-sns.net/how-to-seup-docker-laravel-develop-environment-for-windows-using-ubuntu/



### docker is not runningの対処

https://www.codelab.jp/blog/?p=3803

## ubuntuに入る
コマンドプロンプトから以下のコマンドを叩くか、アプリケーション一覧からubuntuをクリック
```terminal
$ wsl -d ubuntu
```
## laravel sailで新規プロジェクトで作る
https://readouble.com/laravel/10.x/ja/installation.html?header=Sail%25E3%2582%25B5%25E3%2583%25BC%25E3%2583%2593%25E3%2582%25B9%25E3%2581%25AE%25E9%2581%25B8%25E6%258A%259E

① プロジェクトを配置して良いディレクトリに移動して、以下のコマンドを叩く

```terminal
$ curl -s "https://laravel.build/laravel-app" | bash
```

> すでにプロジェクトがある場合は↓を代わりに叩く(composerが無い為)
```terminal
$ docker run --rm \
-u "$(id -u):$(id -g)" \
-v "$(pwd):/var/www/html" \
-w /var/www/html \
laravelsail/php82-composer:latest \
composer install --ignore-platform-reqs
```

② sailのコンテナを立ち上げる
```terminal
$ cd laravel-app
$ ./vendor/bin/sail up
```



## filamentインストール

```php
./vendor/bin/sail composer require filament/filament:"^3.0-stable" -W
./vendor/bin/sail artisan filament:install --panels
```
管理者名を求められる（初期値はadmin)
指定した名前がfilamentパネルのURLに影響する

初期のままOKした場合
```
/admin/login
```
がログイン画面になる


### 設定の公開

```
./vendor/bin/sail artisan vendor:publish --tag=filament-config
```

このパッケージは他の Filament パッケージに依存しているため、次のコマンドを使用してこれらのパッケージの言語ファイルを公開できます。

```
./vendor/bin/sail artisan vendor:publish --tag=filament-actions-translations
 
./vendor/bin/sail vendor:publish --tag=filament-forms-translations
 
./vendor/bin/sail vendor:publish --tag=filament-notifications-translations
 
./vendor/bin/sail vendor:publish --tag=filament-tables-translations
 
./vendor/bin/sail vendor:publish --tag=filament-translations
```

### laravelの日本語化

config/app.phpを以下のように日本の設定に変更する。

```php
'timezone' => 'Asia/Tokyo'
'locale' => 'ja'
'faker_locale' => 'ja_JP'
```
### マイグレーションの実行
```terminal
$ ./vendor/bin/sail artisan migrate
```
### 初期ユーザーの作成

次のコマンドを使用して、新しいユーザー アカウントを作成できます。
```terminal
$ ./vendor/bin/sail artisan make:filament-user
```

ユーザー情報が求めらるので入力する

## filamentチュートリアル
チュートリアルに従ってキャッチアップ！！！

https://filamentphp.com/docs/3.x/panels/getting-started
Okta - 便利なChrome拡張機能 - SAML-tracer

# はじめに

今回はサービスとのSAML設定で躓いたときに役に立つChrome拡張「SAML-tracer」について記載します。

# SAML-tracer

SAML-tracer を使うことでSAML認証時に受け渡されるResponseの値などをログから確認することができるようになります。

https://chromewebstore.google.com/detail/saml-tracer/mpdajninpobndbfcldcmbpnnbhibjmch


# 使い方

拡張機能から SAML-tracer を起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/af918d16-21a4-f6fa-98c9-70019094d8aa.png)

OktaアプリからSAML認証のアプリを選択してサインインすると、SAML-tracerにログが記録されます。

ログの右端に SAML のマークがついているログからSAMLタブを開くと、SAML Responseなどが記録されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/a4bb7ed0-ddd5-ea6f-6e06-0440c0153109.png)


# どんな時に使うか

例えば、Oktaとサービス側の両方の設定をちゃんと入れているはずなので、なぜかログインできないとき。
実際にAssertionで渡されているNameIDが正しいかなど確認する際に利用できます。

SAMLタブを開いて下にスクロールすると、NameIDで受け渡されている値を確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/74d061c1-0f5e-743b-f3bc-b8fdfb775bb5.png)

以前遭遇したケースとしては、IdP(Oktaではない)でNameIDとしてメールアドレスとは別の属性値を指定しているにも関わらず、実際に受け渡されている値はメールアドレスになっているということがありました。

なぜそうなるのかどうしても分からなかったので、IdPのサポートに問い合わせたところ、IdPのサービス側でメールアドレスに固定するように設定されていました。。。

設定値には誤りがないはずだけどサインインできない、という時にはSAML-tracerで実際のデータを確認してみると何かわかるかもしれません。

# おわりに

SAML-tracer は常に便利というわけではありませんが、いろいろ確認する際の手段の一つとして持っておくとよいのではないかと思います。
今回はここまで。ありがとうございました。