OmniAICreator/Qiita-1.07M huggingface dataset:
あえてライブラリを使わずにReactでアニメーションを作る

## この記事の概要

[Framer Motion](https://www.framer.com/motion/)などを使えば良い感じのアニメーションをすぐ作ることができますが、そんな中であえて何も使わずにやってみた記事です。

## 方針

- Create React Appを使う
- スタイリングやアニメーション用のライブラリは使わない
- 何かしらのstate変更でアニメーションを起こす

## 完成物

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/b5869d71-881b-b3fa-5f59-6ed2abaac25c.gif)

## コード

```javascript:App.jsx
import React, { useState } from "react";
import clsx from "clsx";
import "./App.css";

function App() {
  const [fullSize, setFullSize] = useState(false);
  return (
    <main className="main">
      <div
        className={clsx("card", fullSize && "card--fullsize")}
        onClick={() => setFullSize((current) => !current)}
      >
        <img src="https://picsum.photos/500" alt="" className="card__image" />
        <p className={clsx("card__title", fullSize && "card__title--fullsize")}>
          Card title
        </p>
        <p className={clsx("card__lead", fullSize && "card__lead--fullsize")}>
          Lorem ipsum dolor sit amet,
        </p>
        {fullSize && (
          <p className="card__text">
            consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
            labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
            exercitation ullamco laboris nisi ut aliquip ex ea commodo
            consequat. Duis aute irure dolor in reprehenderit in voluptate velit
            esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
            cupidatat non proident, sunt in culpa qui officia deserunt mollit
            anim id est laborum.
          </p>
        )}
      </div>
    </main>
  );
}

export default App;
```

`css:App.css
.main {
  display: grid;
  min-height: 100%;
  padding: 16px;
  place-items: center;
}

.card {
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 14%);
  cursor: pointer;
  line-height: 1.5;
  max-width: 480px;
  padding: 16px;
  width: 100%;
}

[class^="card"] {
  transition: all 250ms ease-in-out;
}

.card--fullsize {
  box-shadow: none;
  padding: 0;
}

.card__image {
  aspect-ratio: 2 / 1;
  border-radius: 4px;
  display: block;
  object-fit: cover;
  width: 100%;
}

.card__title {
  font-size: 32px;
  font-weight: 700;
  margin-top: 16px;
}

.card__title--fullsize {
  font-size: 40px;
}

.card__lead {
  font-size: 20px;
}

.card__lead--fullsize {
  font-size: 24px;
}

.card__text {
  margin-top: 16px;
}
`

## やったこと

- stateにあわせてclassNameを追加する
- `[class^="card"]`と前方一致で指定することで都度`transition`を指定しないで済むようにする

## まとめ

- 最終的に昔ながらのアニメーションのさせ方みたいになった
- しかし、stateにあわせてどんなclassNameがつくのかが予め分かっているので同じようなアプローチにしても分かりやすくなっているかもしれない
[デジタル開発]気体の物性をPythonで自動取得

#Pythonで気体物性を取得する

▶︎ 気体の物性を扱えるライブラリは以前はあまりなかったのですが便利なものも出てきています。

http://www.pyromat.org/index.html

``````Python:ThermodynamicProperty.py
import pyromat as pm
import numpy as np
import matplotlib.pyplot as plt

T   = np.linspace(300.,5000.,201)
air = pm.get('ig.air')

plt.xlabel('Temperature[K]')
plt.ylabel('Cp[-]')
plt.plot(T, air.cp(T))
plt.show()

plt.xlabel('Temperature[K]')
plt.ylabel('Cv[-]')
plt.plot(T, air.cv(T))
plt.show()

plt.xlabel('Temperature[K]')
plt.ylabel('gamma=Cp/Cv[-]')
plt.ylim([1.0,1.5])
plt.plot(T, air.cp(T)/air.cv(T))
plt.show()
``````

![E0264058-4D69-4FFE-BF82-63026E57EEC2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487027/d91ba488-83e7-0771-f9e9-ee6ad54b94d3.jpeg)
Ibexa DXP の管理画面を拡張する

### 再利用可能なコンポーネント¶
バックオフィスを拡張する場合、テーブルやタブなどの一般的に使用されるUIコンポーネントにベースTwigテンプレートを使用できます。

使用可能なテンプレートは次のとおりです。

@ezdesign/ui/component/table/table.html.twig
@ezdesign/ui/component/tab/tabs.html.twig
コンポーネントを使用するにはembed、テンプレートでそれらを使用します。を使用embedすると、含まれているテンプレート内で定義されているブロックをオーバーライドできます。

### テーブル¶
テーブルコンポーネントは、次のブロックで構成されています。

header -テーブルセクションの見出し
headline -テーブル名
actions -アクションボタン（作成、一括削除など）
table -テーブル自体
thead -テーブルヘッダーの内容
tbody -テーブル本体の内容
テーブルコンポーネントは、次の変数をサポートします。

table_class-<table>タグに付加された追加のCSSクラス

```twig
{% embed '@ezdesign/ui/component/table/table.html.twig' %}
    {% block headline %}
        Headline
    {% endblock %}

    {% block actions %}
        <a href="#" class="btn btn-icon">
            <svg class="ibexa-icon ibexa-icon--small ibexa-icon--create">
                <use xlink:href="{{ ez_icon_path('create') }}"></use>
            </svg>
        </a>
    {% endblock %}

    {% block thead %}
        <tr>
            <th></th>
            <th>Column A</th>
            <th>Column B</th>
            <th>Column C</th>
        </tr>
    {% endblock %}

    {% block tbody %}
        {% for i in 1..10 %}
            <tr>
                <td></td>
                <td>A{{ i }}</td>
                <td>B{{ i }}</td>
                <td>C{{ i }}</td>
            </tr>
        {% endfor %}
    {% endblock %}
{% endembed %}
```

### タブ¶
タブコンポーネントは、次のブロックで構成されています。

tab_content -タブの内容
タブコンポーネントは、次の変数をサポートします。

tabs
id -タブID
label -タブの人間が読めるラベル
active -タブがアクティブな場合はtrue
content-tab_contentオーバーライドされていない場合のタブのHTMLコンテンツ
tab_content_class -追加のCSSクラスが添付されています .tab-content
tab_content_attributes -追加されたHTML属性 .tab-content

```twig
{% embed '@ezdesign/ui/component/tab/tabs.html.twig' with {
    tabs: [
        { id: 'first', label: 'First' },
        { id: 'second', label: 'Second' },
     ]
} %}
    {% block tab_content %}
        {% embed '@ezdesign/ui/component/tab/tab_pane.html.twig' with { id: 'first', active: true } %}
            {% block content %}
                First
            {% endblock %}
        {% endembed %}

        {% embed '@ezdesign/ui/component/tab/tab_pane.html.twig' with { id: 'second' } %}
            {% block content %}
                Second. <p>Some <b>Rich</b> HTML <a href="#">content</a></p>
            {% endblock %}
        {% endembed %}
    {% endblock %}
{% endembed %}
```

タブを使用includeするとembed 、テンプレートのレンダリング中にタブのコンテンツを変数として渡す場合の代わりに使用できます。

```twig
{% include '@ezdesign/ui/component/tab/tabs.html.twig' with {
        tabs: [
          { id: 'first', label: 'First', content: 'First tab content' },
          { id: 'second', label: 'Second', content: 'Second tab content', active: true },
        ]
} %}
```
Ibexa DXP でのマルチサイト構築について

マルチサイト¶
マルチサイト構成は、SiteAccessesを使用して行われます。

SiteAccessは、特定のアドレスを介してサイトにアクセスするときにアプリケーションが使用する構成設定のセットです。ユーザーがサイトにアクセスすると、システムはURIを分析し、構成で指定されたルールと比較します。一連のフィッティングルールが見つかった場合は、このSiteAccessが使用されます。

たとえば、さまざまなユースケースをカバーするSiteAccessesを使用してマルチサイトセットアップを作成できます。

Webページの異なる言語バージョン
キャンペーンまたはイベント用の特別なサブサイト
追加のバックオフィス
マルチサイト設定では、SiteAccessごとにさまざまな設定を行うことができます。次に例を示します。

テンプレートとデザイン
言語
木の根
リポジトリとキャッシュ戦略
アプリケーションの他の多くの設定もSiteAccessごとに構成されます（「SiteAccess対応」とも呼ばれます）。

ヒント

可能な場合は、常にセマンティック（SiteAccess対応）構成を使用してください。内部設定を手動で編集することは可能ですが、予期しない動作が発生する可能性があるため、自己責任で行ってください。

事前定義されたサイトテンプレートを使用して新しいサイトをすばやく設定するには、SiteFactoryを使用します。
ダークウェブ とは

## 勉強前イメージ

悪いイメージはある・・・
けどわからんなぁ、、、、

## 調査

### ダークウェブ とは

そもそもインターネットのwebサイトは以下2つに分類されます。

- サーフェスウェブ(表層web)

一般に公開されているwebサイトで、不正なものも含まれている。
普通のwebブラウザで閲覧ができ検索結果にも表示される。

- ディープウェブ(深層web)

ログインを必要とするなどアクセス制限をかけられているwebサイトで、不正なもの以外も含む。
普通のwebブラウザで閲覧できるが、検索エンジンの検索結果に表示されない。

ディープウェブの一部で、 `ダークウェブ` というものも存在している。
匿名性があり、追跡回避などの技術が使用されていて専用のソフトがないと使用できないなどの
制限があるwebサイト。
不正なもの以外も含まれますが、非合法な活動の温床になっている場合があります。

### ダークウェブの例

有名なダークウェブはTor(トーア)というツールを使用したネットワークで、
世界中のボランティアが運営する中間時点を何段階も経由しないと接続できず、
Tor経由でないと接続できないように設定されているものもあります。
運営者も高度に匿名されていて、接続元などの情報を得るのも困難です。
その匿名性から非合法の活動に悪用される場合もあり、
薬物や個人情報、機密情報などの取引がされていると言われています。

## 勉強後イメージ

そういう物があるって知らなかった・・・
web上ですぐ検索できるものが全てだと思ってたけど、
普通には見えないような構造のwebサイトもあるのね。

## 参考

- [ダークウェブってなに？　情報流出への備えと、もしものときの対処法](https://www.ntt.com/personal/ocn-security/case/column/20200423.html)
- [ダークウェブ 【dark web】 ダークWeb](https://e-words.jp/w/%E3%83%80%E3%83%BC%E3%82%AF%E3%82%A6%E3%82%A7%E3%83%96.html)
VMware Cloud on AWS シングルホスト構成によるPoC利用のすすめ

# 1. はじめに
「[VMware Cloud on AWS](https://www.vmware.com/jp/products/vmc-on-aws.html)」では検証用途に限りですがシングルホスト構成(VMware ESXiホストを1台だけ稼働させるイメージ)で利用可能です。スモールスタートが可能ということで、利用にかかるハードルがグッと下がるのではないでしょうか。メリットや注意点などまとめます。

# 2. あらためてVMware Cloud on AWS って？
オンプレとクラウドのそれぞれに強みを持つ両社が共同開発したクラウドサービスです。「[VMware Cloud Foundation](https://www.vmware.com/jp/products/cloud-foundation.html)」のテクノロジーをベースに「[Amazon EC2](https://aws.amazon.com/jp/ec2/)」ベアメタルインスタンス上にVMware仮想環境が構築されています。既存のVMwareテクノロジーのスキルや知見をそのまま活かせるだけでなく、マネージドサービスなので煩雑な物理インフラ管理からも解放されます。
(私もさむーいデータセンターでラッキング、ケーブリング、ソフトウェアインストールからトラブルシュートまで経験してきたので物理インフラからの解放はとても魅力的。。！)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/20ffd036-6af8-5ee6-4bcd-e7f2919d06eb.png)
> *VMware Japan Blog 「[VMware Cloud on AWS の責任共有モデル](https://blogs.vmware.com/vmware-japan/2021/02/vmware-cloud-on-aws-shared-responsibility.html)」から図を抜粋。*

# 3. VMware Cloud on AWS のシングルホスト構成

VMware Cloud on AWS を試したい、でもいきなり本番利用はハードルが高い、、そんな場合はシングルホスト構成が最適かと思います。以下、メリットと注意点を箇条書きでまとめます。

##### オンデマンド料金は 7 ドル/ホスト/時間

US N.Virginiaリージョンにおけるi3.metalの参考価格。東京・大阪リージョンおよび最新価格は[VMware社公式サイト](https://www.vmware.com/jp/products/vmc-on-aws/pricing.html)を要確認ください。とはいえ半日5時間利用して35ドルというのは、お財布にも優しい。

::: note warn
シングルホストは、1年または3年の標準サブスクリプションを利用できないのでご注意ください。オンデマンド課金となります。
::: 

##### VMware HCX、VMware vMotion　を利用できます

VMware Cloud on AWS 側で複数のVMware ESXiホストを必要としない機能は利用できます。なのでオンプレミスVMware仮想環境とVMware Cloud on AWS 間のハイブリッド運用などがお手軽に試験できます。

##### 2ホスト構成にスケールアップできます

「ADD HOST」することで、いつでも本番稼働が可能な2ホスト以上の構成にスケールアップできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/24c1777b-a845-12b9-fa8e-62b5cde7aa6d.png)

##### シングルホスト構成は60日間に限ります

シングルホストのSDDCは60日後に削除され、データもすべて失われます。2ホスト以上の構成にスケールアップすればデータはすべて保持されます。

##### 高可用性（HA）、2つのAWSアベイラビリティゾーンにわたるストレッチクラスタは利用できません

これはイメージしやすいかと思います。シングルホスト構成(1台のVMware ESXiホスト)なので当然の制約ですね。VMware社の問い合わせサポートは提供されますが、SLAは提供されません。あくまで検証用途であるので、SLAが提供されて有効期限もないのは2ホスト以上からです。


# 4. まずは試してみよう！無償ハンズオンのススメ。

とは言っても個人では費用もかかるし、、という場合は「[VMware HoL](https://www.vmware.com/content/microsites/learn/ja/jphol.html)」と言ってお手軽にハンズオンできる素敵なVMware社の**無償**オンラインコースもあります。まずはこちらからトライしてみるのも手かもしれません。過去記事でVMware HoLについてもまとめているのでご参考ください。

https://qiita.com/sanjushi/items/ba6426b202215f39ba22

# 5. 参考資料

https://pages.awscloud.com/rs/112-TZM-766/images/202310_AWS_CDP_PoC_with_VMwareCloudOnAWS_i3metal.pdf

https://qiita.com/sanjushi003/items/175aad0ccdbb3488bfda
すぐに忘れるTerraformコマンドの備忘録

```
terraform --version
terraform init
terraform plan
terraform apply
terraform show
terraform destroy
```

## terraform --version
Terraformのバージョンを確認できる。

## terraform init
ワークスペースを初期化するコマンド。
.tfファイル内で呼ばれているplugin(プロバイダなど)のダウンロードが走る。

## terraform plan
実行計画を確認できる。
つらつらと出てくるので、あんまりよくわからんw

## terraform apply
tfファイルを元に構成するコマンド。
今の構成情報が`terraform.state`
過去の構成情報が`terraform.tfstate.backup`
に残るようになっていて、こいつらが重要らしい。
GCSで管理しているので、CircleCIで毎回別のコンテナが立ち上がっても、同じファイルを参照できるようにしている。


## terraform show
`terraform.state`
を元に現在の構成情報を表示してくれる。

## terraform destroy
`terraform.state`にできているリソースを全部削除するコマンド
Cloud NAT を導入した話

## Cloud NAT

https://cloud.google.com/nat/docs/

要するにマネージドなNAT
GAEやFunctionには対応していない。
GCEにだけ対応しているみたい。

## 仕組み

- アタッチしたnetworkのアウトバウンドのトラフィックが丸っと対象になる。
- GCEのタグとか、Podのタグとかはつけられない。ネットワークのタグだけが対象。
    - まぁ、発展途上なのかなぁとしか言えない。
    - この辺はAWSの方が優秀だよなぁとおもう。
- GCEに対して外部IPアドレスをアタッチしているとそっちが優先される。(最悪)
    - このせいで、Private ClusterにしかCloud NATが適応できない。
    - Public Clusterで組んでしまったけれど、後からIPを剥がせない。

## 実装
この辺をTerraformでやるのしんどくて諦めたので、コマンドここにおいておきます。

```
### Create a VPC
gcloud compute networks create mynavi-gw-vpc \
    --subnet-mode custom
### Create a subnet
gcloud compute networks subnets create mynavi-gw-vpc \
   --network mynavi-gw-vpc \
   --region asia-northeast1 \
   --range 192.168.2.0/24
### Create a cloud router
gcloud compute routers create mynavi-gw-router \
    --network mynavi-gw-vpc  \
    --region asia-northeast1 
### router config 
gcloud compute routers nats create mynavi-gw-nat-config \
    --router-region asia-northeast1  \
    --router mynavi-gw-router \
    --nat-all-subnet-ip-ranges \
    --auto-allocate-nat-external-ips
```

## 参考
https://cloud.google.com/nat/docs/using-nat#step_1_create_a_vpc_network_and_subnet
https://cloud.google.com/nat/docs/using-nat#step_6_create_a_router_name_short
https://cloud.google.com/nat/docs/using-nat#step_7_add_a_nat_configuration_to_the_router_name_short
M1 Mac を買った人のための、開発環境構築

M1 MacBook Proを買って、もろもろ開発環境構築をしたので、
M1しんどいよって人向けに自分がやったことはまとめておこうと思いました。

やったこと順にまとめていきます。

## システム環境設定

### キーボード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309507/08504a56-0096-aa74-7dcd-8ea28d7d4222.png)

さらに、「装飾キー」を選び、CapsLockにControlを割り当てます。

### トラックパット

そして、トラックパットの軌跡を最速に。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309507/4bca1780-dc41-5a1e-29e3-95915ac04183.png)

同時に、タップでクリックを追加しておきます。

## brewのinstall

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/ryota/.zprofile


ryota@ryota-yamadanoMacBook-Pro ~ % brew --version
Homebrew 3.1.5
Homebrew/homebrew-core (git revision 52744bd65d; last commit 2021-05-10)

```

### サウンド

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309507/a613f539-51e4-93e0-63b1-b21da26d5629.png)

チェックを全て外しておきます。

## Google Chromeのインストール

私は諸々のパスワードなどを全て、Googleアカウントに紐付けて、Chromeで管理しているので、これがないと始まりません！w

```
brew cask install google-chrome
```

システム環境設定、一般、デフォルトのブラウザを選んで、Chromeに変更しておきます。

## LINE

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309507/298173c2-f310-9362-bede-283dde6d2ea6.png)

Rosettaがないと動かないので注意。



## oh my zsh

https://github.com/ohmyzsh/ohmyzsh

## GitHub

https://qiita.com/riita10069/items/e875ae6b96756abd0956

## Xcode

```
xcode-select --install
```

## emacs 

テキストエディタにemacsを使っているので、これを設定します。

```
vim .emacs
(setq make-backup-files nil)
(setq auto-save-default nil)

brew install emacs

emacs .zshrc
export EDITOR="emacs"
```

## gcloud

```
curl https://sdk.cloud.google.com | bash
cd google-cloud-sd
./install.sh 
```

## kubectl 

```
brew install kubernetes-cli
kubectl version --client
```

## VSCode

https://code.visualstudio.com/Download#

universalよりもApple Siliconを選んだ方がサイズ小さいので、おすすめです。


## JetBrain IDE

toolboxでApple Silicon用のものがあるので、ここからインストールするようにするのが早いと思われます。

### Goland

December 30, 2020
のブログから引用
> Apple SiliconM1プロセッサ用のビルドを提供します。それらはmacOSのダウンロードページにあります。 Delveはまだサポートされていないため、M1を使用するとデバッガーが機能しないことに注意してください。

だそうですが、とりあえず対応してくれているようですね。
Ibexa DXP の設定について

## 構成設定
Ibexa DXP の設定は、いくつかの目的別の設定ファイルを使って提供されます。これらのファイルには、コンテンツリポジトリの選択からサイトアクセス、言語設定まで、あらゆるものが含まれています。

### 設定ファイルのフォーマット
推奨される設定フォーマットは YAML です。これはカーネルでデフォルトで使用されています (そしてドキュメント中の例でも使用されています)。しかし XML や PHP の形式を設定に使うこともできます。

### 設定ファイル
設定ファイルは `config` フォルダに格納されます。設定はパッケージごとに `config/packages` フォルダに、経路はパッケージごとに `config/routes` に定義されています。

`config/packages/ibexa.yaml` には基本的な設定項目が含まれています。特に、サイトアクセスの情報やコンテンツビューの設定などが格納されています。

その他の設定は、 `config/packages/ibexa_admin_ui.yaml` や `config/packages/ibexa_cache.yaml` などの各ファイルで提供されます。

環境ごとにフォルダを分けて、環境固有の設定を行うことができます。これらのファイルは追加の設定を含み、他のケースで適用される一般的な (環境固有ではない) 設定を指します。

:::note
**ヒント**
Symfony で設定がどのように扱われるかについては詳しくは[こちら](https://symfony.com/doc/5.4/best_practices.html#configuration)をご覧ください。
:::

### 設定のハンドリング
:::note
**備考**
設定は[サービスコンテナ](https://doc.ibexa.co/en/latest/api/service_container/)と密接に関係しています。これを完全に理解するためには、サービスコンテナと[その設定](http://symfony.com/doc/5.4/service_container.html#service-parameters)について熟知している必要があります。
:::

Ibexa DXP での基本的な設定の取り扱いは、 Symfony で一般的に可能なものと同様です。設定ファイルの中でキーと値のペアを定義することができます。

内部的に、また慣習的に、キーはドット構文に従い、異なるセグメントは設定階層に従います。キーは通常、アプリケーションに対応する名前空間がプレフィックスとしてつきます。配列やディープハッシュなど、あらゆる種類の値を使用することができます。

エンドユーザー（またはエンドデベロッパー）に公開されることを意図した設定の場合、通常、[セマンティック設定](https://symfony.com/doc/5.4/components/config/definition.html)も実装するのがよいでしょう。

[サイトアクセスを意識したセマンティック設定](https://doc.ibexa.co/en/latest/guide/multisite/siteaccess_aware_configuration/)も実装できることに注意してください。

例えば:
```yaml
parameters:
    myapp.parameter.name: someValue
    myapp.boolean.param: true
    myapp.some.hash:
        foo: bar
        an_array: [apple, banana, pear]
```
```php
// Usage inside a controller
$myParameter = $this->container->getParameter( 'myapp.parameter.name' );
```

### 構成設定
具体的な構成設定については、以下を参照してください。
* 管理画面設定
* リポジトリ設定
* コンテンツビュー
* マルチサイト設定
* 画像バリエーション
* ロギングとデバッグ
* 認証
* セッション
* 永続キャッシュ
zsh_historyを見て2021年を振り返る

# はじめに

新年明けましておめでとうございます。

2021 年はいかかでしたでしょうか。
僕は新卒 2 年目として多くのものを得ることができた 1 年だったなと思います。

そこで、zsh_history を見て 2021 年はどんなことをしてたんだろうと振り返っていたら、2021 年に使うようになったコマンドがいくつかあったので今回はそれをまとめます。

# ripgrep

https://github.com/BurntSushi/ripgrep

ファイル内検索を高速にできるツールです。

以前までは VS Code の検索機能や`git grep`を使っていましたが、ファイル数が多い場合 VS Code の検索機能では限界が来たり、git 管理下でないと使えないなどの成約がありました。ですが、`ripgrep`は非常に高速、どのディレクトリでも検索ができる、`git grep`に比べ見やすいなどの理由で利用するようになりました。

# GitHub CLI

https://cli.github.com/

GitHub での操作がターミナル上でできるようになるツールです。

コードレビュー時のブランチへの checkout や Pull Request のページを開くのに主に使っています。

```
$ gh pr checkout 100
$ gh pr create --web
$ gh pr view --web
```

# 現時点で 2022 年に使いこなしていきたいもの

- [peco](https://github.com/peco/peco)
  - Qiita の記事で見たけど結局触れていない
  - 作業効率・スピードが上がりそう
- [Neovim](https://neovim.io/)
  - [VS Code の Vim 拡張](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim)で試しに触ってから手の楽さに虜になった
  - ただ、まだ思考のスピードで使えていない & 仕事の開発で使えるレベルに設定できていない
  - 仕事でも使えるように調整していきたい

# 最後に

新卒 1 年目で入社したての頃に比べ作業効率・スピードは上がってきてはいますが、まだまだ先輩エンジニアに比べ無駄が多い部分はあります。
2022 年はより作業効率・スピードを上げて、思考のスピードで開発できるようにしていきたいです。
『分析者のためのデータ解釈学入門』を読んで①

## はじめに
今回は[『分析者のためのデータ解釈学入門』](https://www.amazon.co.jp/%E5%88%86%E6%9E%90%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E9%87%88%E5%AD%A6%E5%85%A5%E9%96%80-%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%9C%AC%E8%B3%AA%E3%82%92%E3%81%A8%E3%82%89%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-%E6%B1%9F%E5%B4%8E%E8%B2%B4%E8%A3%95/dp/4802612907/ref=nodl_)を読んだ内容を、自分への備忘録として残しておきたいと思います。

本は3部構成になっていて、以下のような内容になっています。

- 第一部：データの性質に関する基礎知識
- 第二部：データの分析に関する基礎知識
- 第三部：データの解釈・活用に関する基礎知識

この記事では、第一部の内容をまとめていきたいと思います。

## 内容
### 観測は簡単ではない
- データ分析の結果はデータの質で決まる
    - そのため質のいいデータがあれば、よい分析結果が得られる可能性が高まる
- 必ず欲しいデータを入手できるわけではない
    - 観測しにくいデータももちろんあり、測れるもので代替することが多い
    - ただ代替のものを用意することで、本来測りたいものとは違うものを測ってしまうことがあるので、そこは注意

### 誤差とばらつき
- 誤差とは
    - 真の値とのずれのことを、誤差という
    - 誤差には、ランダム誤差とバイアスがある
        - ランダム誤差：計測ごとに変化する誤差のこと
        - バイアス：計測によらず一定の誤差のこと
    - ランダム誤差は、その誤差がどのようにばらついているかを調べることである程度情報を知ることができる
- 確率分布
    - ランダム誤差の値を限りなく多い回数計測していくと、どの値がどの頻度で観測できるかわかる
    - その頻度を曲線で表現したものが確率分布

### データに含まれるバイアス
- 測定基準
    - 表現されたデータがどういった基準でまとめられたかわからないと結果の受け取り方が変わってしまうので、常に測定基準を確認する習慣付けが必要
- 選択バイアス
    - 全体から見て一部のデータが選択されたことに起因するバイアス
    - 例えばあるサービスの認知度アンケートを取る場合、アンケート参加者はある程度関心がある人である可能性が高くなってしまう
- 質問は難しい
    - アンケートでは質問によって結果が大きく変わってしまう
    - 回答を歪める心理学的効果を知っておかないといけない
- チェリーピッキング
    - 自説の決定を正当化するために都合の良いデータや事象だけを集めること
    - メディア等で日常的に行われているため、そこに注意してデータを見る必要がある

### 交絡因子と因果関係
- 相関と因果関係
    - ある事象が他の事象に対して影響を与えるとき、その事象の間に因果関係があるという
    - データを見たときに相関があることはわかるが、因果関係があるか結論づけることは難しい
- 交絡因子
    - 原因となる変数と関連し、かつ結果の変数と因果関係を持つ要因のこと
- 数理モデルの手法
    - 重回帰分析
    - ロジスティック回帰

### データサンプリングの方法論
- 標本調査
    - 対象となる集団の一部からデータを観測し、そこから全体の性質に関する推論を行うこと
- 無作為抽出の方法
    - 集団からランダムに抽出することを、無作為抽出という
    - 単純無作為抽出法
        - リストから乱数を使ってサンプリングしていく方法
    - 系統抽出
        - リストから一定間隔でサンプリングしていく方法
    - 層化多段抽出法
        - 個々の対象が所属するブロックのレベルでランダムにサンプリングしていく方法

## さいごに
今回は[『分析者のためのデータ解釈学入門』](https://www.amazon.co.jp/%E5%88%86%E6%9E%90%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E9%87%88%E5%AD%A6%E5%85%A5%E9%96%80-%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%9C%AC%E8%B3%AA%E3%82%92%E3%81%A8%E3%82%89%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-%E6%B1%9F%E5%B4%8E%E8%B2%B4%E8%A3%95/dp/4802612907/ref=nodl_)の第一部で知ったことをまとめてみました。今後、第二部、第三部をまとめていこうと思います。
漫画やスライドの配信に特化したwebアプリを考えた

# はじめに
この記事はアドベントカレンダー[ライブ配信/ビデオ通話SDK（Agora）を使用したサービスのアイデアを大募集！](https://qiita.com/advent-calendar/2021/agora)の参加記事になります。なんとか実装までしてから出したかったのですが年明けに間に合いそうにないのでアイディアだけ共有します。

# 目的
今回作成するのはpdfや漫画を読みながら配信するといった「大学などのオンライン授業」や「漫画や本などの読み聞かせ配信」といったユースケースに特化したwebアプリになります。
特徴としては

- 手軽な反応であるリアクションが使え、またリアクションは配信者が設定できる
- ページごとのリアクションやコメントを記録し、配信者へのフィードバックとして使える
といったものを想定しています。

以下のようなユースケースを想定しています

- 漫画の配信をして
    - 視聴者はエモいシーンでスタンプを送り合いたい
    - 配信者はどこで盛り上がったかをしりたい
- 映像講義をするときに
    - 生徒は資料でわからないところを手軽に主張したい
    - 先生はどこがわからないかを知りたいし、逆に評判の良い部分を知って資料の改善に役立てたい


# イメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100303/16820291-e330-18c4-c9e9-43a229ece291.png)
- これに加えて配信者の声が聞こえているイメージ
    - Agoraの[Voice Call](https://docs.agora.io/en/Voice/landing-page?platform=Web)を使用する

# 1:漫画やスライドを配信する部分
- 配信者が配信する画像やスライドを表示する部分
- [live-streaming](https://docs.agora.io/en/live-streaming/landing-page?platform=Web)ですかね？
    - 画像をたまに切り替えるだけだからもう少しコストが良い配信ができそうな気がする


# 2:ページを切り替える部分
- ここは配信者だけが使える想定
- 前ページ、次ページを押すとpdfのページが切り替わる
    - pdfの表示には[pdf.js](https://mozilla.github.io/pdf.js/)の使用を想定
- 切り替わると視聴者の画面も切り替わるシステム


# 3:リアクション欄
- ボタンをクリックすることでリアクションを送れる
    - ここに設定されるリアクションは配信者が決められることを想定
    - ページごとに集計しておくことで、後で配信者に配信時の反応をフィードバックするために使用
    - また、おっかけ配信で見るときにも各ページにどんな反応がついたかがわかり没入感が増す
- Agoraの[Real-time Messaging](https://docs.agora.io/en/Real-time-Messaging/landing-page?platform=Web)を使用？
    - 各視聴者がリアクションをするたびにカウント→全視聴者に配信？
    - 負荷がすごそう、もう少しいい感じのやり方を考えたい
        - 中央に集めて→一定時間ごとに全視聴者の状態を更新するとか(やり方は不明)

# 4:コメント欄
- 各ユーザーが送ったコメントを全部表示する部分
- リアクションと同じくAgoraの[Real-time Messaging](https://docs.agora.io/en/Real-time-Messaging/landing-page?platform=Web)を使用する想定
- リアクションと同じくページごとに集計する

# このシステムの想定する強み
pdfの配信に特化しているので、コメントやリアクションをページごとに集計する機能がついています。これによって以下のことが可能です

- ページごとの視聴者の反応やコメントが後から確認できる
    - 授業であれば「わかりにくかった点」を後から見直して修正できたり、より「質問」に事細かに答えることができるでしょう
    - 漫画の配信だったりすると視聴者がエモを感じた部分がわかるでしょう
    
- 何らかの形でリアクションやコメントを保存しアタッチすることで、生放送でなく見るときに(追っかけで見るときに)リアクションやコメントをリアルタイムに近いかたちで味わうことができる
    - リアルタイムに近い没入感や共感を味わうことが可能

# 終わりに
どうすればこれを実現できるんだろう、ってのが満載な感じにはなりましたが一応考えたので上げておきます。「こうしたらええんちゃう？」みたいなコメントありましたらいただければ幸いです！！
ClojureのArrayMapにnextした場合の挙動とコンテナ実装の内部構造について

[Clojure advent calendar](https://qiita.com/advent-calendar/2021/clojure) 17日目です。遅刻組です。

ClojureのArrayMapをnextした場合の挙動から、Clojureランタイム、各interface、実装の理解を深めたいと思います。

## ありがちなLispのコンテナの実装
ありがちな教科書的実装なLispでは、リストは2つのポインタをもった構造体から成り、ベクタはn個のポインタを格納できる配列から成る程度には表現が簡単です。そして、それらを組み合わせて遅延リストやハッシュテーブル、セットなどを作ります。そして、新しく作ったコンテナへのアクセスする関数を新たに定義します(lazy sequenceならlseq-carなど)。例えば、pairだけでなく、lazy sequenceもcarと言う名前の関数で1つめの要素にアクセスしたい場合は、carを新たに再定義して置き換える必要があります。Lispの名前空間の使い方によってはこの方法は難しいことがあります(少なくともR7RS Schemeなどでは)。そんなわけで実装ごとに操作するインターフェースフェースが用意されることがほとんどです。

## Clojureのコンテナの実装
Clojureの各コンテナは、Javaのクラスで実装されています。
SequenceやLazySeq、PersistentList、PersistentArrayMap、PersistentVectorなどがあります。遅延シーケンスやリストで共通するfirst、nextのような操作は、それらを持たせたISeqなどのInterfaceをimprementsしています。それから、sequential?やsorted?等の性質の判定のために、PersistentVectorやPersistentListは、Sequentialを(間接的に)imprementsし、 PersistentTreeMapは、Sortedをimprementsしています。

## Clojureのコンテナ周りは何を読めばよいのか
まず、map関数などの単純な操作を組み合わせてできるコンテナを操作する関数は、clojure.core(src/clj/clojure/core.clj)を見ればよいです。nextやassocなどの単純なコンテナ操作の関数はRuntime(src/jvm/clojure/lang/RT.java)とsrc/jvm/clojure/lang内の各コンテナの実装を見れば良いです。


## PersistentArrayMapのnext
Clojureでは、リストだけでなくmapに対してもfirst,nextすることができます。

```clojure
user=> (next {:a 3, :b 4})
([:b 4])
```
clojure.coreのnext関数は、中でRuntimeのnextメソッドを呼び出します。
[RT.java](https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L711)では、次のような処理になっています。
与えたオブジェクトがISeq(をimprementsしたもの)であれば、そのnextを呼び出し、そうでなければISeqに変換してそのnextを返すようにしています。

```Java
static public ISeq next(Object x){
	if(x instanceof ISeq)
		return ((ISeq) x).next();
	ISeq seq = seq(x);
	if(seq == null)
		return null;
	return seq.next();
}
```
PersistentArrayMapはISeqではないので、seq()してnextします。PersitentArrayMapをseqすると、[PersitentArrayMap独自のSeq実装](https://github.com/clojure/clojure/blob/abe19832c0294fec4c9c55430c9262c4b6d2f8b1/src/jvm/clojure/lang/PersistentArrayMap.java#L355)を返します。

```clojure
user=> (class (next {:a 1 :b 2}))
clojure.lang.PersistentArrayMap$Seq
```
このPersistentArrayMap$Seqは、first()するとkey,val対を返すようなものになっており、ArrayMapをその場で単純にListに変換するよりもメモリの効率がよくなるようになっています。
これは、ある種の遅延シーケンスのような挙動をしますが、countはArrayMapのもつ要素数から出すことができるので、全部舐めなくてよいという違いがあります。


```java
	public Object first(){
		return MapEntry.create(array[i],array[i+1]);
	}

	public ISeq next(){
		if(i + 2 < array.length)
			return new Seq(array, i + 2);
		return null;
	}

	public int count(){
		return (array.length - i) / 2;
	}
```
参考までに、ArrayMap$Seqのarrayとは、ArrayMapのkey、value対を格納しているarrayであり、奇数番目がkeyで偶数番目がvalになっています。

## 終わりに
Clojureのコンテナの実装はとてもおもしろいので一度くらいは見てみるとよいと思います。
grep sed awkでの文字列除外②

またまた基礎学習
2つ以上の文字列を除外する場合
sedの場合は、2つ以上の命令をする場合は、「-e」が必要です。

```
 sed -e /cpu/d -e /ctxt/d sedtest.txt
```

egrepの場合

```
egrep -v "cpu|ctxt" sedtest.txt
```

awkの場合
※まだ理解はできていませんが

```
awk '$0 !~ "cpu|ctxt" {print $0}' sedtest.txt
```

このサイト凄い。。。
https://qiita.com/yusukew62/items/f9502a3ddd6087a496ce
IbexaDXP を macOS または Windows にインストールする手順

# macOS または Windows に Ibexa DXP をインストール
このページでは、macOS または Windows に Ibexa DXP をインストールする方法について説明します。

:::note warn
**注意**
この手順は、**開発目的のみのもの**です。実稼働目的での Ibexa DXP のインストールは Linux でのみサポートされています。

Linux に製品をインストールする方法については、「[Ibexa DXP のインストール](https://qiita.com/bezeklik/items/8dee078a4d8ed2cc7f22)」を参照してください。
:::

## 作業環境の準備
Ibexa DXP をインストールするには、MySQL と PHP のスタックが必要です。さらに、アセット管理には Node.js と Yarn が必要です。Web サーバーを使用する場合はそのインストールも必要です。

* Windows の場合: Apache
* macOS の場合: Apache / Nginx

以下の手順は、Apacheを使用することを前提としています。

### Windows
php.ini ファイルを見つけ、テキストエディタで開きます。関連するパラメータ、例えば `date.timezone` や `memory_limit` に不足している値を入力してください。
```ini:php.ini
date.timezone = "Asia/Tokyo"
memory_limit = 4G
```

プロジェクトに関連する拡張機能、例えば PHP の `opcache` 拡張機能 (推奨、必須ではない) をアンコメントまたは追加します。
```ini
zend_extension=opcache.so
```

管理者としてCMDで以下のコマンドを実行することで、ApacheをWindowsサービスとしてインストールすることができます。
```winbatch
httpd.exe -k -install
```

その後、以下のように起動します。
```
httpd.exe -k start
```

Apache 設定ファイル httpd.conf を編集します。例えば、`ServerName localhost:80` のように、プレースホルダーの値をあなたのプロジェクトに対応する値に置き換えます。関連するモジュールのコメントを解除します。
```apache
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
```

## Composerの入手

### macOS
[Homebrew](https://brew.sh/) などのパッケージマネージャーを使用して、 Composer をインストールします。

### Windows
[Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe) をダウンロードして実行すると、最新の Composer がインストールされます。

## Ibexa DXP のインストール
この時点では、Linux にインストールする場合と同じ手順です。[Ibexa DXP のインストール](https://qiita.com/bezeklik/items/8dee078a4d8ed2cc7f22)ページの手順に従います。

## 仮想ホスト(VirtualHost)の設定
Apache ディレクトリでサイトの[仮想ホスト設定](https://httpd.apache.org/docs/2.4/vhosts/)を準備します。

Windowsの場合: `<Apache>\conf\vhosts`
macOS の場合: `/private/etc/apache2/users/`

次に、Apacheサーバーを再起動します。

## パーミッションの設定
`var` と `web/var` ディレクトリは、 CLI と Web サーバーのユーザーによって書き込み可能である必要があります。今後、この2つのユーザーによって作成されるファイルとディレクトリは、これらのパーミッションを継承する必要があります。

詳しくは、「[ファイルパーミッションの設定または修正](http://symfony.com/doc/5.4/setup/file_permissions.html)」を参照してください。

:::note
**セキュリティチェックリスト**
プロジェクトの本稼働前に対処すべきセキュリティ関連事項の一覧は、[セキュリティチェックリスト](https://doc.ibexa.co/en/latest/infrastructure_and_maintenance/security/security_checklist/)を参照してください。
:::
Ibexa Cloud への Ibexa DXP のインストール手順

https://doc.ibexa.co/en/latest/getting_started/install_on_ibexa_cloud/

Ibexa Cloudを使用すると、Platform.shサービスを使用してアプリケーションをクラウドでホストできます。

### 1.構成ファイルを準備します
composer ibexa:setupインストール中にコマンドを実行しなかった場合は、今すぐ実行してください。

```bash
composer ibexa:setup --platformsh
```

このコマンドは、IbexaCloudの使用に必要なプロジェクト構成ファイルに追加します。

次の場所で構成を調整できます。

* .platform.app.yaml -主な構成
* .platform/services.yml -検索エンジンやキャッシュなどの追加サービス
* .platform/routes.yml -Fastlyなどの追加サービスへのルート

使用可能な構成設定の詳細については、Platform.shのドキュメントを参照してください。

#### ディスクスペース
合計ディスク容量は、IbexaCloudサブスクリプションレベルによって異なります。diskキーの下のメインアプリコンテナにディスクスペースを割り当てることができます。残りのスペースは.platform/services.yaml、個々のサービス定義の下で、他のコンテナ（データベースなど）または検索エンジン間で分散できます。

#### プロセスの構築と展開
下の構成hooksは、プロジェクトを構築およびデプロイするプロセスを定義します。

ノート

ビルドフェーズ（hooks.build構成で定義）の間、プロジェクト内のファイルには読み取り/書き込み権限があります（変更可能）。

展開中（hooks.deploy構成で定義）、プロジェクト内のすべてのファイルは読み取り専用です。

#### 追加サービス
.platform/services.yaml コメントを外してSolrやElasticsearchなどのサービス、または永続的なRedisセッションストレージを有効にすることができる事前構成済みの設定ブロックが含まれています。

利用可能なサービスについては、Platform.shのドキュメントを参照してください。

いずれかのサービスを有効にする場合は、relationshipキー入力の下の関連する関係のコメントも解除する必要があり.platform.app.yamlます。

### 2.アカウントを作成します
https://cloud.ibexa.co にログインするか、まだアカウントをお持ちでない場合はアカウントを作成してください。

プロジェクトを作成し、その地域を選択します。

### 3.ホスティングの準備をします
プロジェクトが作成された後、Webサイトでは、プロジェクトをホスティングするための準備について説明します。これには、SSHキーの追加、およびgitリモートとしてのPlatform.shの追加が含まれます。

Platform.shにプッシュする前に、Composer認証トークンをプロジェクトに追加します。このトークンを環境変数として設定できます。

その場合は、Platform.sh構成の[実行時に表示]ボックスがオフになっていることを確認してください。これにより、トークンが公開されなくなります。

実行時にトークンを非表示に設定する

### 4.プロジェクトをプッシュします
構成が完了したら、プロジェクトをPlatform.shリモートにプッシュします。

```bash
git push -u <platform.sh-remote> master
```

ノート

master 実稼働ブランチのPlatform.sh名です。
Homebrewを使用してDockerをインストールする

## Goal

M1チップ搭載のMacBook AirにHomebrewを使用してDockerをインストールする手順を示します。

## References

* ["Homebrew Formulae - docker"](https://formulae.brew.sh/cask/docker). Homebrew. Retrieved December 31, 2021.

## Pre-Requisites

この文書の手順は、次の環境で実施し、動作を確認しました。

* MacBook Air (M1, 2020)
* macOS Monterey 12.0.1
* zsh 5.8
* Xcode 13.2.1
	* Command Line Tools for Xcode 13.2.0.0.1 (Dec 3, 2021)
* Homebrew 3.3.9

## How To

ターミナルを開きます。

Dockerをインストールするため、次のコマンドを実行します。

```bash
% brew install --cask docker
```

Finderでアプリケーションを開き、追加された"Docker"を起動します。

Dockerのバージョンを確認するため、次のコマンドを実行します。

```bash
% docker version
Client:
 Cloud integration: v1.0.22
 Version:           20.10.11
 API version:       1.41
 Go version:        go1.16.10
 Git commit:        dea9396
 Built:             Thu Nov 18 00:36:09 2021
 OS/Arch:           darwin/arm64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.11
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.9
  Git commit:       847da18
  Built:            Thu Nov 18 00:34:44 2021
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.4.12
  GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
 runc:
  Version:          1.0.2
  GitCommit:        v1.0.2-0-g52b36a2
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```
【IoT】近づくと音が鳴るおもちゃ

# 概要
ペットのキンカチョウが放鳥時にいつも鏡に向かって鳴いているので、鏡の中のお友達(?)が鳴き返してくれるようにしました！！
よくうさぎにもちょっかいを出すので、警戒音としても使えるのかなぁと思っています。
仕組みとしては、超音波センサーを使用していて、ある一定の距離まで近づいたら音が鳴るようにしています。

# デモ動画
デモ動画では、すずめの置物で代用しています。

https://twitter.com/mikiko_bridge/status/1391299965528412163?s=29

# 部品
|  部品名  |  品番  |
|:---:|:---:|
|  obniz本体  |  obniz Board 1Y  |
|  超音波モジュール  | HC-SR04  |
|  圧電スピーカー | ANYM-SPT08 |
| ワニ口クリップ  |  Access ワニグチクリップコード |
| 電源 |  自宅にあったモバイルバッテリー |


# 配線
![](https://camo.elchika.com/113642303695af72da0162662e0c7a2c6465cf6c/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f31353434623236332d303134652d343839392d626365662d3662623430626530613737362f30323663353136642d363862632d343666382d383631362d303134346537633333633634/)

HC-SR04 は、gnd:0, echo:1, trigger:2, vcc:3に接続し、
圧電スピーカーは、signal: 10, gnd: 11 に接続しました。

# ソースコード
```html
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <script src="https://unpkg.com/obniz@3.8.0/obniz.js"></script>
</head>
<body>
  <h1>超音波距離センサーと圧電スピーカーをつかったIoT</h1>
  <div id="dispArea"></div>
  <script>
    var obniz = new Obniz("OBNIZ_ID_HERE");
    obniz.onconnect = async function () {
      const hcsr04 = obniz.wired("HC-SR04", { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
      const speaker = obniz.wired("Speaker", { signal: 10, gnd: 11 });
      while (true) {
        let avg = 0;
        let count = 0;
        for (let i = 0; i < 3; i++) {
          const val = await hcsr04.measureWait();
          if (val) {
            count++;
            avg += val;
          }
        }
        if (count > 1) {
          avg /= count;
        }
        console.log(avg);
        document.getElementById("dispArea").innerHTML = "<h1>" + avg + " mm</h1>"
        if (avg < 200) {
          speaker.play(2500); 
        }
        else {
          speaker.stop();
        }
        await obniz.wait(100);
      }
    }
  </script>
</body>
</html>
```

# 感想
現在の改善点としては、
- 近づくと音が鳴るだけなのでできるだけ鳥っぽくしたい。
- 部品が大きく鳥が怖がってしまっている。
ということを考えて、今後改良していきたいと思っています。

最後まで読んでいただきありがとうございました！！
TypeScriptに挑戦するなら必ず覚えておきたい型定義の基本

基本的なTypeScriptの型についてまとめておく。

## TypeScriptの型(レベル1)
### 文字列型
```typescript
var name: string = 'Gorira';
name = 'GoriGorira';
```

### 数値型
```typescript
var num: number =  18;
```

### 真偽値型
```typescript
var isOpen: boolean = true;
```

### 配列型
```typescript
var keywords: string[] = ['Gorira', 'Goriko', 'Gorio'];
```
上記の場合、配列には文字列型をしていしているため、0などの数値を配列に格納すると警告が表示されてしまう。他のデータ型を配列に格納したい場合は以下のように記載する。

```typescript
var kewords: (string|number)[] = ['Gorira', 'Goriko', 'Gorio', 0];
```
このようにパイプ``(string|number)``で型を繋いであげると、文字列型も数値型も配列に格納することができる。

### タプル型
```typescript
var payment: [number, string, number] = [1, 'Gorira', 65];
```
タプル型はこのように配列で型の順番を定義することができる。
number,string,numberという順番で型を定義しているため、配列の中身が['Gorira', 'Gorira', 65]のような形ふだと警告が表示されてしまう。

### オブジェクト型
```typescript
var object: { [key: string]: string } = {
  name = 'Gorira',
  id = 'inu'
};
```

## TypeScriptの型(レベル2)
### 供用型 (Union型)
```typescript
var sample: string | number;
sample = 'Gorira';
sample = 56;
```
このように変数に文字列型も数値型も定義することができる.

```typescript
sample = trure;
```
この場合はboolean型は定義していないため警告が表示される。

```typescript
var sample: string | number | boolean;
```
とすれば問題ない。

### enum型

```typescript
enum Animals {
  Gorira = 100,
  Goriko = 3,
  Gorio = 50,
}

console.log(Animals.Gorira);    // 100
```
enum型は少し変わっているが、このようにconsole.logで参照されていることが確認できる。
また下記のような書き方もできる。

```typescript
enum Ningen {
  Gorira ,
  Goriko,
  Gorio,
}

console.log(Ningen.Gorira);   // 0
```
このような書き方をすると、自動的にインデックスが貼られる。
値を省略して書くこともできる。
もちろん数値以外でも、文字列を渡すことも可能。

## TypeScriptの型(レベル3)
### any型

```typescript
var something: any = 'foo';
something = 100;
something = true;
something = { id: 1 };
```
any型ではTypeScriptの厳格さのようなもが薄れてしまう。
そのため、このany型はできるだけ使用しないように心がけると良い。
むしろ、使わないようにした方が良い。

### null, undefined型

```typescript
var el: Element | null = document.querySelector('#app');
var gori: undefined = undefined;
```

## TypeScriptで型を指定しなかった場合

```typescript
var unknown = 'gorigorigorira';
// この時点でunknownは文字列型と推測されている。

unknown = 10;
// そのためこのように10と数値を代入すると[文字列型しか代入できない]と警告がでてしまう。
```
このように型を指定しないことももちろんできる。
このことを``型推論``という。
Ibexa DXP (旧 eZ Publish / eZ Platform) の概要

**Ibexa DXP** は北欧の**ノルウェー**の Ibexa AS 社によって開発されているオープンソースおよびその製品版の CMS の総称です。

1999年に eZ Systems AS 社によって **eZ Publish** として開発され、その後継である **eZ Platform** でフルスタックの Symfony アプリケーションとして再設計されました。
2020年に社名とブランド名が **Ibexa** （アイベクサ）へと大きく変更されました。

## Ibexa DXP の 使用技術
* 言語 **PHP** 7.4 / 8.0 / 8.1
* PHP フレームワーク **Symfony** 5.4 (フルスタック)
* テンプレートエンジン **Twig** 3.x
* JavaScript ライブラリ **React** 17.0.x (管理画面)

## Ibexa DXP の CMS としての特徴
Ibexa DXP には CMS として以下の特徴があります。
* コンテンツ管理
    * ユーザーを含めた全てのデータが「コンテンツ」として一元的に管理される。
    * コンテンツは標準で全て **ツリー構造（階層構造）** を持つ。
    * 全てのデータは項目単位で**バージョン管理**される。
    * 「ロケーション」によりコンテンツを複製せずに**ショートカット**を作成できる。
    * 全てのデータは**項目単位で多言語対応**できる。
* ユーザー管理
    * ユーザーグループとユーザーを階層構造で管理できる。
    * ユーザーの権限を標準でかなり細かい単位で設定できる。

## オープンソース版
### Ibexa Open Source
オープンソース版の Ibexa DXP
https://github.com/ibexa/oss

## 商用プロダクト
### ラインナップ
Ibexa DXP の商用プロダクトとして以下の3つがあります。
* Ibexa Content
* Ibexa Experience
* Ibexa Commerce

また、サポートするプロダクトとして以下の2つも提供されています。
* Ibexa Cloud
* Ibexa Personalization
![Ibexa-DXP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15175/e4d3a18c-9d43-0b33-197c-7c2592ea0646.png)

### 機能比較
|FEATURE	|Ibexa Content	|Ibexa Experience	|Ibexa Commerce|
|---								|:-:	|:-:	|:-:|
|構造化コンテンツ						|✓|✓|✓|
|コラボレーションとワークフロー				|✓|✓|✓|
|多言語コンテンツ管理					|✓|✓|✓|
|マルチサイト							|×|✓|✓|
|ページビルダー						|×|✓|✓|
|SEO and Social						|×|✓|✓|
|フォームビルダー						|×|✓|✓|
|User-driven personalization		|×|✓|✓|
|Behavioral-driven personalization	|✓|✓|✓|
|レコメンデーション						|✓|✓|✓|
|Content and Commerce				|limited|✓|✓|
|Buying experience					|×|×|✓|
|CRM インテグレーション					|×|✓|✓|
|B2B コーマス							|×|×|✓|


### Ibexa Content
15,000ユーロ/年 から

https://www.ibexa.co/products/ibexa-content

### Ibexa Experience
23,000ユーロ/年 から

https://www.ibexa.co/products/ibexa-experience

### Ibexa Commerce
30,000ユーロ/年 から

https://www.ibexa.co/products/ibexa-commerce

### Ibexa Cloud
14,740ユーロ (G-XL) から
https://www.ibexa.co/products/ibexa-cloud

### Ibexa Personalization
2,500ユーロ/年 から
https://www.ibexa.co/products/ibexa-personalization
Enumで遊ぼう　(with_index,filter,map)

Enumで遊んでみたいと思います
今回は
Enum.with_index
Enum.filter
Enum.map
で遊びます

#Enum.with_index
```elixir
[
  "abc",
  "def",
  "ghi"
]
|> Enum.with_index()
```

結果：配列に対して0から順番にインデックスを付けてくれます

```elixir
[{"abc", 0}, {"def", 1}, {"ghi", 2}]
```

#Enum.filter

```elixir
[
 {"abc", 0}, 
 {"def", 1}, 
 {"ghi", 2}
]
|> Enum.filter(&elem(&1, 1) in [0,2])
```

結果：　数字が0と2で絞り込みしたタプルを取得

```elixir
[{"abc", 0}, {"ghi", 2}]
```

#elemの挙動を確認してみよう


```elixir
elem({"abc", 0}, 0)
```

結果：タブルの0番目を取得

```elixir
"abc"
```


```elixir
elem({"abc", 0}, 1)
```

結果：タブルの1番目を取得

```elixir
0
```

#Enum.map

```elixir
[
  {"abc", 0}, 
  {"def", 1}, 
  {"ghi", 2}
 ]
 |> Enum.map(&elem(&1, 0))
```

結果：タプルの0番目のリストを作成

```elixir
["abc", "def", "ghi"]
```

#組み合わせてみよう

```elixir
[
  "abc",
  "def",
  "ghi"
]
|> Enum.with_index()
|> Enum.filter(&elem(&1, 1) in [0,2])
|> Enum.map(&elem(&1, 0))
```

結果：0番目と2番目のリストを作成

```elixir
["abc", "ghi"]
```

#関数化してみよう

```elixir
defmodule Hoge do
  def hoge(data, indexes) do
    data
    |> Enum.with_index()
    |> Enum.filter(&elem(&1, 1) in indexes)
    |> Enum.map(&elem(&1, 0))
  end
end


[
  "abc",
  "def",
  "ghi"
]
|> Hoge.hoge([0,2])
```

結果：0番目と2番目のリストを作成

```elixir
["abc", "ghi"]
```
EC2へnvm、Node.js、Yarnをインストールする

#nvmのインストール

まずはnvmのインストールです。なおEC2へSSHログインしている状態を「サーバー環境」として表現しています。

```:サーバー環境
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```

成功したら「このターミナルを閉じて再度起動させてね」というメッセージが出てくるのでそれに従います。
ターミナルを新規ウインドウで開き、EC2へ再度`SSHログイン`します。

```:サーバー環境
source ~/.bashrc
```

```:サーバー環境
nvm -v
```

nvmがインストールされていたらバージョンが返ってきます。

#Node.jsのインストール

```:サーバー環境
nvm install --lts --latest-npm 
```

```:サーバー環境
node -v
```
nodeがインストールされていたらバージョンが返ってきます。

#Yarnのインストール

```:サーバー環境
curl -o- -L https://yarnpkg.com/install.sh | bash
```

成功したら「このターミナルを閉じて再度起動させてね」というメッセージが出てくるのでそれに従います。
ターミナルを新規ウインドウで開き、EC2へ再度`SSHログイン`します。

```:サーバー環境
source ~/.bashrc
```

```:サーバー環境
yarn -V
```

```:サーバー環境
yarn -v
```

yarnがインストールされていたらバージョンが返ってきます。


#必要な周辺知識

###SSHログインの仕方

```:ターミナル
ssh AWSで設定したアプリ名_key_rsa
```

※cdはどこでもいいです

###SSHとは
Secure SHellの略。あるコンピューターから別のコンピューターへネットワークを通じてログインし、遠隔操作するためのプロトコル。
同じ用途で以前はtelnetが使われていたが、安全面を考慮しSSHが取って変わるようになった。

###nvmとは
`Node Version Manager`の略で、名前の通り、一つのマシンで複数のNode.jsのバージョンを管理できるライブラリです。
macOSで使用される`nodebrew`と同じ役割を持ちます。
※似た言葉で**npm**があります（`node package manager`の略）
[公式](https://github.com/nvm-sh/nvm)

###Node.jsとは
サーバーサイドで動作するJavascript。
[公式](https://nodejs.org/ja/)

###Yarnとは
npmと同じくNode.jsのパッケージ管理ツール。
npmと互換性があり、npmと比較して様々なメリットがある。(インストールが早い。セキュリティが高い。インストールするパッケージのバージョンをより細く設定できるなど。)
[公式](https://yarnpkg.com/)


#参考
[EC2にyarnをインストールする](https://fukatsu.tech/ec2-yarn)
[nvm(Node Version Manager)を使ってNode.jsをインストールする手順](https://qiita.com/ffggss/items/94f1c4c5d311db2ec71a)
[nvm + Node.js + npmのインストール](https://qiita.com/sansaisoba/items/242a8ba95bf70ba179d3)
[npm と yarn と pnpm 比較（2021年4月版）](https://qiita.com/e99h2121/items/7e38e592dc45b7c0407d)
[Flutter] 異なるWidget同士で引数を引き継いで使う方法

<h1>したいこと</h1>
<p>今回は、Flutterですごい基礎的なことですが、頻繁にコードの書き方を忘れるのでメモします。</p>
<h1>方法</h1>
<p>引数(parametor)を引き継ぐ方法は以下です。</p>

```dart
class A extend StatelessWidget {
// Named Constructor(参考サイトの2を参考ください)
 final dynamic(type) parametor_a
 final dynamic(type) parametor_b
 
 A({Key? key, required this.parametor_a, required this.parametor_b}) : super(key: key)
}
```

<b>Step1.</b> parametorを宣言する。

```dart
 final dynamic(type) parametor_a
 final dynamic(type) parametor_b
```

<b>Step2.</b> parametorをrequiredで、引き継ぐようにする。

```dart
 A({Key? key, required this.parametor_a, required this.parametor_b}) : super(key: key)
```


<h1>実装したかったこと</h1>
FirebaseのCloud Databaseにデータを追加するためのボタンを作ることが、実装したいことでした。
データを追加するボタンだけ別のクラスにした時に、値の引き継き方がわからなくなったので、メモようにこの記事を作成しました。

```dart:add_data.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyFirestorePage(),
    );
  }
}

class MyFirestorePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
            Padding(
              padding: EdgeInsets.only(top: MediaQuery.of(context).size.height*0.5),
              child: AddData(collection_name: 'test_collection', doc_name: 'test_doc', field_name: 'test_field', field_value: "test_value",)
            ),
          ],
        ),
      ),
    );
  }
}


class AddData extends StatelessWidget {
  final String collection_name;
  final String doc_name;
  final String field_name;
  final dynamic field_value;

  AddData({Key? key, required this.collection_name, required this.doc_name, required this.field_name, required this.field_value }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: ElevatedButton(
        child: Text("Create collection and Document"),
        onPressed: () async {
          await FirebaseFirestore.instance
              .collection(collection_name)
              .doc(doc_name)
              .set({field_name: field_value});
        },
      ),
    );
  }
}
```

<h1>参考サイト</h1>
<b>1. 引数(parametor)の引継ぎ方について

https://stackoverflow.com/questions/49768439/i-want-to-use-named-parameters-in-dart-for-clarity-how-should-i-handle-them

<b>2. DartのNamed Constructorについて

https://www.youtube.com/watch?v=aFr7mNHadL4


<h2>その他</h2>
3.StatefulWidgetでの、引数の引継ぎ方

https://qiita.com/keiy121/items/72656a932256ec43d893
振り返り③

振り返り3回目です。
記事投稿が遅くなりすみませんでした。

# やったこと
システム構成図作ってみるといいよ！って言われたので作ってみました。
AWSの構成図が3Dで描けちゃうかっこよくておしゃんなCloudcraftとかいうのがあったので使いました。
![システム構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2224485/bea736f9-9945-44e6-a40e-0d1770a86466.png)

# 結局
AWSのことが分かってないと描くにも描けないということに気づいたので来週はAWSのお勉強をする予定です。

written by 多和田
ラズパイのケースを自作してみた。


##きっかけ
　クラスで割り当てられるラズパイは剥き出しのままで配布されてて、素手で触るのにもはばかられるし、机の上の掃除の時にも気遣いがち。じゃぁ机の中に仕舞えばいいのだけど、アレ?誰も仕舞ってないのね。。。

ケースに収めてしまえば気にならなくなるのだけれども、お金掛けてまでケースを持参するのもどうかと。。。中身は自分のモノじゃないのに。。。

検索では１００均素材で作るケースとか出てくるけど、ちょっと無骨すぎない？
なにか他の材料でないかと思案していたその視線の先に「あるじゃないのおあつらえのが」
##ジャジャーン
![PXL_20211213_085102893.PORTRAIT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253252/4242d973-948d-376d-7de5-7a0a9582cf6d.jpeg)


「こたべ」です。
京都土産の定番「八ッ橋」のそのなかでも、小さめの可愛いやつです。

これなら、自作といえども、もうすでにケースの体をなしてるし、なによりなにより、１つ税込３６５円でケースだけでなく生八ッ橋まで入ってる。（ちなみに「八ッ橋」は「八つ橋」でも「八ツ橋」でもなく「八ッ橋」だそうです、理由までは詳しく聞けなかったけど、某八ッ橋屋さんに言われました、そういうことデス。）
京都のお土産といればコレですよねと、参考までにこんな記事もありました。
https://8284.musyozoku.com/spell-yatsuhashi/
あとこんなレポートも

http://www.ml.ist.i.kyoto-u.ac.jp/retraction

もうね、「こたべ」はお菓子付きのラズパイケースにしか見えなくなってきました。

##材料
「こたべ」の空箱
 固定用のネジ

##製作
特に加工も必要なく、まさにラズパイを収納するがために生まれてきたかの様です。
だた、高さはちょうどですが横幅奥行きがガサガサなので、固定する必要がありですね。
ラズパイの寸法図があるので、これに合わせて切り欠きを入れていきます。
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html
まぁ、素材が紙ですから簡単ですね。失敗しても買い直して何度でもやり直せます。
と、ところがジャック部分の切り欠きには思わぬ苦戦を強いられました。
![PXL_20211215_121513543.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253252/b44f7d26-3be9-5135-aab1-398be6c7fe26.jpeg)

あらかじめタミヤのハンディドリルを使ってみたりしたのですが、カッターで切り込みを入れる際には、フニャフニャするのでテーブルの角を使うなり木片を使うなり、なにかで切断面を押さえておく必要がありますね。
彫刻刀で打ち抜いた方が良いかもしれません、工作苦手なので結構ガサツに仕上げております。
![PXL_20211216_234639535.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253252/3bb75103-a546-767b-f888-92c0ea81dde8.jpeg)
あとは、底面に固定用のネジを現物合わせで押し込んであります。
#完成
![PXL_20211216_234541109.PORTRAIT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253252/3b7d20de-6073-d6cd-16df-4e305888e7be.jpeg)

　放熱が気になれば、上面に開口を開けるも簡単そうですし、ファンを取り付けるのも良しですね。
##注意
素材が紙なので、ひょっとしたら発火する？と心配になったので調べてみましたが、長時間電源入れっぱなしにしない限りは大丈夫そうですね。
https://kamiconsal.jp/kamihakkaten/
くれぐれも、火の元には気をつけて自己責任でお願いいたします。
amplify pull --appId hogehoge --envName staging がうまくいかない時の対処法

**問題**

[【Amplify と Figma の連携】Amplify Studio の UI Library を使ってみた](https://blog.serverworks.co.jp/amplify-studio-ui-library)の記事をやってみているときに発生した問題。

`amplify pull --appId hogehoge --envName staging` のコマンドを叩いても下記のエラーが発生してAmplifyからコンポーネントが生成されない。

```

ailed to pull the backend.
request to https://prod.us-east-1.appstate.amplifyapp.com/AppState/?appId=hogehoge failed, reason: getaddrinfo ENOTFOUND prod.us-east-1.appstate.amplifyapp.com
FetchError: request to https://prod.us-east-1.appstate.amplifyapp.com/AppState/?appId=d1gio7pqqkunam failed, reason: getaddrinfo ENOTFOUND prod.us-east-1.appstate.amplifyapp.com
    at ClientRequest.<anonymous> (/Users/HiguchiShuya/.nodebrew/node/v16.13.0/lib/node_modules/@aws-amplify/cli/node_modules/node-fetch/lib/index.js:1483:11)
    at ClientRequest.emit (node:events:390:28)
    at ClientRequest.emit (node:domain:475:12)
    at TLSSocket.socketErrorListener (node:_http_client:447:9)
    at TLSSocket.emit (node:events:390:28)
    at TLSSocket.emit (node:domain:475:12)
    at emitErrorNT (node:internal/streams/destroy:157:8)
    at emitErrorCloseNT (node:internal/streams/destroy:122:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)


```

**解決策**

ローカル環境でもAmplifyの認証をしていないのが原因なので `amplify configure` を実行する。
AWSコンソールがブラウザで起動するのでAWSのアカウントにログインしてやり、場合によってはIAMユーザーを作成してデフォルトで有効になっている必要なロール(AdministratorAdmin)をアタッチしてやる必要がある。
途中IAMユーザーの`accessKeyId`と`secretAccessKey`が聞かれるので作成されたクレデンシャルは保存しておくこと。
その後、CLIの回答にしたがって `Successfully set up the new user.`　が表示されたら完了。

`amplify pull --appId hogehoge --envName staging` が成功する。
Nuxt 3 で変わったところ

2021年12月に、匿名で気軽に悩みを相談できる Web アプリ「なやみん」をハッカソンで制作しました。

https://github.com/citrus-candy/nayamin

技術的な挑戦ということで Nuxt 3 を使ってみたので、開発の中で知った主な変更点をメモしてみました。

## Installation

### Nuxt 2

```
npx create-nuxt-app <project-name>
```

### Nuxt 3

```
npx nuxi init <project-name>
```

Nuxt 2 では対話形式で初期設定をしていたものが、Nuxt 3 ではなくなりました。
必要最低限の構成でインストールされるので、公式のドキュメントを見ながら必要に応じてディレクトリを作る感じです。

https://v3.nuxtjs.org/getting-started/installation

## TypeScript

Nuxt 3 ではデフォルトが JS ではなく TS になりました。
`yarn install` した後に `yarn build` もしくは `yarn dev` をすると、`.nuxt` ディレクトリが自動で作成されます。
型定義ファイルや `tsconfig.json` はここで生成されるので、一度生成しておかないと `useStore` とかで TS のエラーを吐いちゃいます。

https://v3.nuxtjs.org/concepts/typescript

## script

### Nuxt 2

```vue
<script>
export default {
  data: {
    return {
      count: 0
    }
  },
  computed: {
    hoge() {
      return 'fuga'
    }
  },
  mounted() {
    this.count = 1
  }
}
</script>
```

### Nuxt 3

```vue
<script setup>
const count = ref(0)

const hoge = computed(() => {
  return 'fuga'
})

onMounted(() => {
  count = 1
})
</script>
```

Vue 3 で採用されていた Composition API が Nuxt 3 で使えるようになりました。
また、`<script setup>` が使えるので、コンパクトに書くことができて見やすくなります。

こちらの記事がとても参考になりました。

https://zenn.dev/azukiazusa/articles/676d88675e4e74#%E9%80%9A%E5%B8%B8%E3%81%AE-%3Cscript%3E-%E3%81%A8%E4%BD%BF%E3%81%86

## plugins

### Nuxt 2

- `nuxt.config.js` に記述が必要

### Nuxt 3

- `nuxt.config.ts` に記述が不要
- `/plugins` にファイルを追加するだけで自動でインポートされる

https://v3.nuxtjs.org/docs/directory-structure/plugins

## pages

### Nuxt 2

```
-| pages/
---| _id.vue
```

```javascript
console.log(this.$route.params)
```

```javascript
action() {
  this.$router.push('/hoge')
}
```

### Nuxt 3

```
-| pages/
---| [id].vue
```

```javascript
const route = useRoute()
console.log(route.params)
```

```javascript
const router = useRouter()

action() {
  router.push('/hoge')
}
```

動的ルートのファイル名が変わりました。
フォルダ名にも使えるらしい。
また、`route` `router` が `useRoute()` `useRouter()` になりました。

https://v3.nuxtjs.org/docs/directory-structure/pages

## Vuex

### Nuxt 2

```javascript:store/index.js
export const state = () => ({
  foo: 'bar'
})

export const getters = {
  getFoo(state) {
    return state.foo
  }
}
```

```vue:pages/index.js
<template>
  <div>
    {{ foo }}
  </div>
</template>

<script>
export default {
  computed: {
    foo() {
      return this.$store.getters.getFoo
    }
  }
}
</script>
```

### Nuxt 3

```typescript:composables/index.ts
import { useState } from '#app'

export const useFoo = () => {
  return useState('foo', () => 'bar')
}
```

```vue:pages/index.js
<script setup>
const foo = useFoo()
</script>

<template>
  <div>
    {{ foo }}
  </div>
</template>

```

Nuxt 3 で Vuex が廃止されました。
その代わり、`/composables` にファイルを作り、上記のようにすることでグローバルな値として管理することができます。

便利すぎて感動した。

https://v3.nuxtjs.org/docs/usage/state