OmniAICreator/Qiita-1.07M huggingface dataset:
Unity ShaderGraphでY軸固定のビルボードを作る（簡易版）

## 目的
UnityのShaderGraphでY軸固定のシェーダーを作ります
今回は簡易版で、ちゃんと計算するものは次回書きます

## 作り方
内容はビルボードの回転に使う行列の成分を一部消すだけです。
しっかりとした作りになってないので3Dモデル等で扱うと意図しない変形をすると思いますが、
2DSpriteをビルボード表示する程度であれば問題ないはずです。

中段から下段のノードについては参考にしたサイトを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154377/15e5a4be-7637-9761-0516-d28fc83af91e.png)
![image.gif](https://i.gyazo.com/f7f667da714d0a0879a6196611d1a791.gif)

## 参考
参考にさせていただきました。ありがとうございます。
- ベース
    - https://www.matatabi-ux.com/entry/2022/03/03/100000
- Y軸固定部分
    - https://gam0022.net/blog/2019/07/23/unity-y-axis-billboard-shader/

もし何かもっといい方法があれば教えてください。
カスタムテンプレートを使ってgithub codespace上にansible実行環境を構築する

# はじめに
github codespace上にansible実行環境を作ることが分かったのはいいけど
毎回インストールのためのコマンドを実行するのは正直ツライ。

幸い、github codespaceにはカスタムテンプレートってのがあるようで
それを使えばイケるそうなので試してみた。

# 参考
ChatGPTに質問しつつ、最終的には少しリファレンスも参考にしました。

https://docs.github.com/ja/enterprise-cloud@latest/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers

# 手順

1. GitHubのリポジトリを作成し、テンプレートとして使用したいコンテンツを含める
今はお試しなのでとりあえず空っぽにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/20c13f31-0c75-ba74-9acb-5e2fb3eacf6d.png)

2.リポジトリ内に.devcontainerという名前のディレクトリを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/979865b0-5ff0-2926-3eae-64de6c8d588b.png)

3..devcontainerディレクトリ内に、Dockerfileという名前のファイルを作成します。

```dockerfile:Dockerfile
FROM ubuntu:20.04

RUN apt-get update && \
    apt-get install -y ansible

RUN ansible --version

CMD ["/bin/bash"]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/060afdfe-a1f6-c719-bc01-81bf73c26e29.png)

4.devcontainer.jsonを作成。さっき作ったDockerfileを指定する

```json:devcontainer.json
{
  "image": "mcr.microsoft.com/devcontainers/universal:2",
  "build": { "dockerfile": "Dockerfile" },
  "features": {
  }
}
```

最終的にはこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/2b46ad8a-7d0b-cd1b-b4ca-5590fdd48b87.png)

最後に作ったファイルはちゃんとコミットしておくことを忘れずに。

5.リポジトリ画面に戻って、普通にcodespaceを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/cf43ff71-fb26-62d6-8bbc-322a0943f578.png)

6.しばし待つ・・・
いつもの起動画面と違って何やら読み込んでるのがポイント。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/cc81fb73-7009-5c44-172d-3859434f320f.png)


6.ansibleが構築された状態になってるか確認
早速バージョンを確認してみる

```
ansible --version
```

動いてる！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/274867bd-3510-0e1a-c263-37d557dc26b5.png)

# おわりに
カスタムテンプレートっていうから色々不安だったけど
中身はDockerfileなのでそこまで心配になることは無かった。
これなら簡単にcodespace環境構築できますね！
Localhostに接続できない時

## はじめに
PHP（Laravel）を動画や書籍で勉強しています。
先日、エディタにMacの再起動を促されて今まで通りLocalhostに接続しようとしたら出来なかったので、個人的なメモを残そうと思いました。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- PHP・Laravelを勉強中の方

## Localhostとは
自分自身のコンピュータ内で動作するWebサーバーのこと。ネットに繋がっていなくてもWebページを見ることができます。

## エラー内容
- Dockerを起動したらDockerのコンテナ？の表示が緑になっているはずなのに自分のは黒。▶︎ボタンを押したら下記のエラーに遭遇。

```# sh:Error: (HTTP code 500) 
Error invoking remote method 'docker-start-container': Error: (HTTP code 500) server error - Ports are not available: exposing port TCP 0.0.0.0:80 -> 0.0.0.0:0: listen tcp 0.0.0.0:80: bind: address already in use
```
どうやら、:80ポートは使ってるよ！ってことらしいです。

：80ポート確認する
```# sh:ターミナルで
sudo lsof -i -P | grep ":80"
```
上記のコマンドを入力すると
![スクリーンショット 2023-04-23 23.51.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131382/c7c2225b-fa6e-5d61-b70f-27bb8b7a164d.png)

httpd → Appath が起動している。
なので、Appathのプロセスを止めます。

```# sh:再びターミナルで
sudo apachectl stop
```
無事にlocalhostに接続できました。

## おわりに
:80ポートエラーでlocalhostに接続できない時の対処法についてまとめてみました。

## 参考記事
[docker起動時にPort でエラー](https://tmlabo.hatenablog.com/entry/2021/07/03/201141)
AdbPad v1.1.0 をリリースしました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/20011fd7-7394-b02b-49ee-e87b701277ad.png)

# はじめに

AdbPadはAndroidアプリケーションの開発・テストをサポートするGUIアプリケーションです。AdbPadは以下のGitHubリポジトリで絶賛開発中です。よろしければコントリビュート＆スター登録お願いします。

https://github.com/kaleidot725/AdbPad


# AdbPadでできること

AdbPadでは以下の機能をサポートしています。機能の詳しい解説は[AdbPad v1.0.0 をリリースしました](https://qiita.com/kaleidot725/items/0128d876df5eb53f5a8d)でしていますので確認していただければと思います。

- Windows10/11, macOS対応
- ライトテーマ・ダークテーマ切り替え
- コマンド送信
- テキスト送信
- 各テーマのスクリーンショット撮影

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/a09903bd-af81-666a-a0f8-583e8039e8f1.png)

# v1.1.0の変更点

AdpPadのv1.1.0では変更差分が少ないのですが以下の機能の追加を実施しました。

## アイコンを変えました

以前のアイコンは仮のものだったのと、少し見栄えが良くなるようにしたいと思いアイコンを変更しました。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/7818060b-8a63-5ac0-8f44-882a7c783c97.png width=256>

アイコンはDockに並べたときに見やすいかがポイントかなと思っています。なのでDockに並べたときのアイコンの見やすさ重視でFigmaで自作しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/e18bf0c6-e9de-c467-f98e-61380c318073.png)

## ピン留め解除のコマンドの追加

キオスク端末などを作るときにはAndroidアプリで画面のピン留めを利用することがあります。ピン留めの解除をするのは、特定のボタンを同時押しする必要があり面倒なので、コマンドとして「画面ピン留め：OFF」を新たに追加しました。

![Screenshot 2023-04-25 at 21.39.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/943ba481-0df6-1fea-4743-e1cbf735dc51.png)

## スクリーンショットのコピー＆削除

撮影したスクリーンショットをコピーできるようにしました。以下のような感じでGitHubに撮影したスクリーンショットを直接貼り付けられるようになりました。

![Screen Recording 2023-04-25 at 21.29.57.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/9e2282dc-0388-21f2-572d-0debdddbd217.gif)

また撮影したスクリーンショットを削除できるようにしました。機能面から見ると削除できなくても良いかなとは感じていたのですがやはり必要ないものが残っている気持ち悪さはありそうと思ったので今回追加しました。

![Screen Recording 2023-04-25 at 21.29.43.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/1ab7535f-b308-df5d-adfc-21f7f5e627bb.gif)

# おわりに

v1.1.0は小さめの機能追加になりましたが、継続して少しつづ機能を増やしていこうと考えています。最新版のAdbPadのv1.1.0はこちらからダウンロードできますのでお試しください。

https://github.com/kaleidot725/AdbPad/releases/tag/v1.1.0
ubuntu22.10あたりからサウンドサーバーがpipewireになったので、bluetoothのスピーカーがおかしくなるのを止めた

# 前提
bluetooth機能のついてるスピーカーやヘッドセットをlinuxで使ってると、モノによってはちょっとの間再生止めてると、次に再生するときに音がぶつぶつこま切れになるよね。

# 対象BTスピーカー例
iLoud Micro Monitor

# 解決法
`sudo systemctl restart bluetooth.service`

# 根本的な解決法（昔）
## PulseAudioの場合

https://wiki.archlinux.org/title/bluetooth_headset#Connecting_works,_sound_plays_fine_until_headphones_become_idle,_then_stutters

# 根本的な解決法（いま）
## pipewireの場合
- wireplumberがない！ => いれる
`sudo apt install wireplumber`

- /etc/wireplumber/が空っぽ => いれる
`sudo cp -a /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua /etc/wireplumber/bluetooth.lua.d/`

- 50-bluez-config.luaをどうするの？ => いじる
luaスクリプトの最後の数行から["session.suspend-timeout-seconds"]を探して=0する。
```
apply_properties = {
    ...
    ["session.suspend-timeout-seconds"] = 0,
},
```
- そんで？ => サービス再起動
`sudo systemctl --user restart wireplumber`

## 何が問題だったの？
- サウンドサーバーが一度サスペンド状態になって次にアクティブになるときに、bluetooth機器も同様にアイドル状態からアクティブになるんだけど、そのタイミングで同期がずれちゃうみたい。pulseaudioの頃から起こってた。
- 解決方法をネットを探すと色々出てくるんだけど、微妙に違うトピックでこんな感じだった。
    - サウンドカードがスリープしちゃって起きない件 => bluetooth関係なかった。
    - bluetoothの再生がおかしいけど、レイテンシーの問題じゃね？ => レイテンシー色々変えたけど大勢に影響なしだった。https://askubuntu.com/questions/475987/a2dp-on-pulseaudio-terrible-choppy-skipping-audio
- 結局ネット上では求めてた答えがみつけられず、なんとなく調べたことからの類推でサウンドカードへの対策方法をbluetoothにそのまま当てはめられないかと設定ファイルを全部見て、一番それっぽいbluetooth.lua.d/50-bluez-config.luaを同様に書き換えてみたらうまくいった。なのでこれが正当な正解ではないと思う。やってることは単にbluetoothスピーカーをアイドル状態にしないってだけだから。
- iOSとかMacOSだとちゃんと再生が止まるとbluetoothがアイドル状態になるんだけど、次の再生でコケないんだよね。一歩踏み込もうとすると急激に難しくなるのがbluetoothってイメージ、ある。

## 閑話
- ubuntu23.04にしたらgnomeのbluetooth設定にiLoudMicroMonitorが出てこなくて泣いた。bluetoothctlで探したらあっさり発見、登録できた。なにかしら、これ。
- bluez周りはあまりドキュメントない。最初はbluezが悪いと思ってた。（これは間違ってないのかもしれない）
- iLoudMicroMonitorは小さくても低音までかなりキレイに出るので、かわいい。でも最近、右チャンの3.5KHzあたりが元気がなくて、悲しい。ツイーターが死んだかと思ったけど生きてる。原因は謎。もしくは自分の耳かも。
- linux系列のサウンドシステムを解説したドキュメントの決定版ほしいなあ。一番デバイスに近い最後端がalsa程度しか理解できてない。pipewireとPulseAudioの立ち位置の違いなんかを知りたいけど、なかなかないなと思った。もしかして共存してる環境とかもありえるんかな。
ロボティクス

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiixta.com/7_inai_)


# ロボティクスとは
ロボティクスは、`自律的に動くロボットの開発・設計・運用を行う「ロボット工学」`を指す言葉です。近年では、特にAIやIoTを使用した自動化を指して「ロボティクス」という人もいます。

# ロボティクスが注目される背景
近年非常に注目されているロボティクスですが、ロボティクスが注目される理由は「技術的側面」と「環境的側面」で説明できます。
### 技術的側面
- AIの発展によって、応用が必要で複雑なタスクも実行できるようになった。
- 半導体等の電子機器の需要増加により、全体的なコストが下がった。
- 作業内容によっては人が実行するよりも、短時間・高精度・高効率で実行できる。

### 環境的側面
- 労働人口の減少によって、人が必要な作業を減らす必要性が出てきた。

# ロボティクスを支える技術
ロボティクスを支えるために重要な技術を紹介します。
- 人工知能
前述した通り、プログラミングではカバーしきれない臨機応変で複雑な作業を行うためには、機械学習や強化学習といった技術が必要となります。
- センサー
センサーは、カウントや機械同士の同期タイミングの取得以外にも、カメラや重量計を用いた不良品の検査にも使用されます。
- モーター
ロボティクスでは、物を自動で運ぶ必要があるため、モーターは必須の技術です。ロボットアームやコンベア、その他の駆動装置等多くの場所でモーターは使用されています。

# ロボティクスが活躍する場面
工場ではもちろんですが、工場以外でも多くの場面でロボティクスは活躍します。
- 医療分野
ロボットを用いて手術をすることで、手ブレをなくした高精度な手術のみならず、遠隔での手術も可能にします。
- 家庭用ロボット
一般の消費者に馴染みのある、家庭用の自動掃除ロボットもロボティクスを生かした製品の一つです。

# 終わりに
ロボティクスについてまとめましたが、ロボティクスでは実現できないこともまだまだ存在します。
例えば、道徳的な判断が求められる場面や、ロボットが稼働できない環境(超高温、水中)では使用できません。また、工場においてもロボットを使用するよりも人の方が不良の検知率が高かったり、ロボットでは繊細な技術が求められることはできなかったりします。
今挙げたような課題を解決していくことができれば、ますますロボティクス分野は発展するでしょう。

最後までお付き合いくださりありがとうございました。
【UiPath】いまさらですが、タグの使い方学びました

# UiPath でタグって使ったことありますか？

21.X系から使えるようになった記憶ですが、個人利用では使ったことがありませんでした。
バージョンアップ関連の[***記事***](https://qiita.com/Kajiita/items/1dd4a3d9ccb4eed70935)を書く中で多少かじりましたのでシェアします↓↓

## タグの使い方

- タグ付けはリソースを分類するのに役立ちます。
- 特定の機能課題や仕様変更の影響範囲を確認するために、開発バージョンや、導入対象システム向けの略称（SAP、D365など）を入れておくことで、一般的には管理表やログ分析などでおこなうリソースの把握・特定作業を簡単に実現できます。
- 導入ステップ：
    1. タグ（ 「ラベル」と「プロパティ」）の定義
    1. Automation Cloud の「管理」＞対象テナント＞「タグ」より、『ラベル』と『プロパティ』を追加
    1. タグの付与ルールの周知・展開
    1. タグ付けできるオブジェクト（※）へのタグ付け
※：![image (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/6a4f5e8a-28f7-484c-391e-63d0060e4fe0.png)

## 「ラベル」と「プロパティ」の定義

- 「ラベル」と「プロパティ」はいずれもタグです。検索する際、検索タグを指定する欄が別になります。
- サンプルイメージ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/41ae1a74-7562-008a-2fd6-ca5959f37adb.png)

- プロパティ（キーと値のペア）の値に指定できるデータ型：文字　／　整数　／　真偽　／　カスタム（正規表現）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/80dedd04-0730-baa6-4963-9aac6393ae3d.png)

## 「ラベル」と「プロパティ」の登録

Automation Cloud の「管理」＞対象テナント＞「タグ」より、『ラベル』と『プロパティ』を追加できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/8cc82f09-bb24-a7b6-85ba-03e4a542b694.png)

（ラベルの登録ダイアログ例）
![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/b1280a59-a18b-ff41-ec48-b6658ed2a182.png)
（プロパティの登録ダイアログ例）
![image (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/6c3f69ec-f24b-cc2a-81cc-13e5827a6e21.png)

## タグ付け - アセットの例

対象フォルダ ＞アセット ＞ 「アセットを追加 」より、タグセクションのラベルとプロパティを指定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/8ee6c756-e3a3-360f-1bc5-dbd1793b1d19.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/d1bdf784-d9b8-06e3-6b0a-1ea7c537808b.png)

## タグ付け - パブリッシュ時の例

「パブリッシュ」ボタン押下 ＞ パッケージのプロパティ ＞ 「プロジェクト タグ」の入力欄よりタグを検索・指定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/06aab729-282a-4398-fc2e-cb5623fe1783.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/59a8ff76-1846-9551-bac3-d315bc554992.png)

## リソース検索の例 

Orchestrator のテナント内のリソース検索ボタン（赤枠）を押下 ＞ ラベルまたはプロパティ（青枠）よりタグを指定・検索実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/498d02da-9848-a477-9e40-ed9aeb795051.png)
（ラベルでの検索例）
![image (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/e96ec58e-26d6-c912-56d2-5947731b09e5.png)
（プロパティでの検索例）
![image (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301444/adf998e1-6d73-319d-32a2-3b396d10c3c6.png)

# 参考

https://docs.uipath.com/ja/orchestrator/automation-cloud/latest/user-guide/organizing-resources-with-tags

以上 お読みいただきありがとうございました_(._.)_
アドレス変換、DHCPリレー、 アクセス制御の基本

NAPTの手順

①変換後のグロアドは何を使うか & グロアドを入れとくプールの名前設定
　　(config)#ip nat pool "プール名" start-ip end ip netmask "ネットマスク"
②変換前のプライベートアドレスの範囲を定義する
　　(config)#ip access list 1 permit "プライベートアドレス" "ワイルドカードマスク"
     　　　＜注意1＞プライベートアドレスはネットワークアドレスを指定。x.x.x.0のこと
       　　　＜注意2＞ワイルドカードマスクは00000000|00000000|00000000|00001111 等と
　　　チェックしない箇所には0を立て、チェックしてほしいところには1を立てる。
③グロアド、プラアド双方を紐づけてあげる
　　(config)#ip nat inside source list "アクセス制御番号 今回は1" pool "プール名" overload
個人開発が売れない理由

Qiitaを読んでいると **「個人開発で一発勝負したい！」** と思う小野です。
WEBアプリを作って、放置していても1ヶ月で10万円収益化ができるようになると色々と人生に余裕が出てくるものです。
そういう収入源を増やすのもいいですよねー。

しかし、**個人開発はやればやるほど痛感しますが、なかなか売れません。**
売れない理由は色々あります。

というわけで、今回は個人開発のアプリが売れない理由について説明していきます。

## 個人開発が売れない3つの理由

これ！という理由は一つに絞れないです。
だいたい、3〜5つありますね。
今回は、その中でもよくある3パターンについて書いています。

### マーケティング不足

今は誰でも開発ができる時代で、類似アプリは毎日のように出ています。
となると、あなたのアプリは本当に顧客が求めているものを捉えているかどうかが大事になってきます。

本当にユーザーのニーズを理解していれば、作ったものをストアに置いているだけで売れていくでしょう。
しかし、「他のアプリもたくさんある」「そこまでユーザーのニーズを押さえていない」
そういうアプリではなかなかダウンロードまで行かないでしょう。

**また、認知を獲得するためにも、SNSやブログなどで発信することになると思います。**
このような宣伝の部分も、他社と差別化してユーザーが欲しいものだと伝えるには、なかなかハードです。
さらに、自分が専門的な知識やノウハウを習得している必要がありますし。
（実際、マッチングアプリとかはSNSやTV、街中の広告にお金をかけて告知していますしね）

### 機能不足

そもそもニーズをしっかりと押さえていますか？

**それはメインの機能だけでなく、サブスクなら更新の手続きや決済方法なども含めて**です。
個人で開発していると、どうしてもメインの機能以外は後回しになりがちです。。
しかも、一人だと気付かないままの時もありますねー。
（人それぞれ認知バイアスが異なるので）

### 開発のスピード感不足

個人の開発速度より、組織の開発速度のほうが圧倒的に速いです。
かけられる人数が変わりますからね。

1人だと毎日24時間が最大ですが、10人でやれば毎日240時間使えます。（MAXなので睡眠時間や他の時間を考えたら、開発に使える時間はもっと減りますし）

その中で、どうやって良いアプリを一人で開発するか？

**最近だと、chatGPTを使ったアプリが多数出てますが、先に出しているアプリのほうがダウンロードされていますしね。**
個人だと、なかなかこのスピード感で開発ができません。。

### さいごに

個人開発が売れない理由でした。
技術が進むにつれて、個人開発でヒット作を出すのがなかなか難しい時代になりました。
github codespaceでansible環境を作る

# はじめに
github codespaceを使ってansible playbookの動作検証ができないものかと思い
ansibleの実行環境を作ったときの手順を残す。

当初はテンプレート選択したらすぐに作れるかと思ったら、そんなテンプレートなかったのでやむなくイチから作ることにした。

# 手順
端的にまとめておきます

1. Codespaceを起動し、ターミナルを開く。
2. Ansibleをインストールするために、以下のコマンドを入力する。

```
sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
```

3. バージョンを確認する

```
ansible --version
```

結果がこちら。簡単！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/3091a5d3-aedb-ed80-9af7-e678a748db18.png)

ちなみにバージョンを指定したい場合はこんな感じでコマンド入力

```
sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible-2.9
sudo apt install ansible=2.9.*
```

# ansible playbookを使用する
テスト用のプレイブックはこんな感じで作りました。

```yml:playbook.yml
- name: Install and configure Apache
  hosts: your_server_hostname
  become: true

  tasks:
    - name: Install Apache
      package:
        name: apache2
        state: present

    - name: Configure Apache
      lineinfile:
        path: /etc/apache2/ports.conf
        regexp: '^Listen'
        line: 'Listen 80'

    - name: Restart Apache
      service:
        name: apache2
        state: restarted
```

github codespaceは複数サーバ作れなさそうなのでlocalhostで実行できるように
inventory.ymlを作成。
”ansible_connection: local”使ったらlocalhostに対しての指示出しができる。便利。

```yml:inventory.yml
all:
  hosts:
    localhost:
  vars:
    ansible_connection: local
```


実行する。以下のコマンドを入力

```
ansible-playbook playbook.yml -i inventory.yml
```

結果がこちら。動いた！
ばっちりapache2も動いてるし、curlで応答とれるし、いいですね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/a85a008a-5e6b-4746-0b49-3765ec7e70e6.png)

# おわりに
以上の手順はすべてChatGPTに教わりながら実施。
今までなら何時間も七転八倒しながらたどりつくのに今回はほぼ一直線にやりたいことができた。
トータル30分くらい？ChatGPTはマジで神ですね。
GmailでLaravelから爆速メール送信

# 2段階認証を有効

**アプリ パスワードは 2 段階認証プロセスを有効にしているアカウントでのみ使用できます。**
https://support.google.com/accounts/answer/185833?hl=ja
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/dde30c56-3b85-52f7-39f1-d3faa020572b.png)

2段階認証を有効にしてください
https://myaccount.google.com/security

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/7954fc54-a285-dbb3-44dd-09f2184aebd8.png)


# アプリパスワードを作成
アプリパスワードを作りましょう
https://myaccount.google.com/apppasswords

![Screenshot from 2023-04-25 20-27-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/c381279e-c247-5840-a119-2b96772153da.png)
![Screenshot from 2023-04-25 20-27-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/3e3c0f45-2d4a-cf62-5556-e9b6e3a173b5.png)
![Screenshot from 2023-04-25 20-27-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/d2496c52-d006-b0d8-88ac-1806f8541bfb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/ed2ce50f-087b-7f4d-5e71-c7b43459899c.png)

![Screenshot from 2023-04-25 20-28-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/9e05b298-4d1c-9762-e89c-3f955e7ee6d5.png)


# `.env`を修正

`MAIL_USERNAME`と`MAIL_PASSWORD`は書き換えてや

```ini:.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=hoge@gmail.com
MAIL_PASSWORD=16文字のパスワード
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="${MAIL_USERNAME}"
```

# メール送信 動作確認

```bash
php artisan tinker

Mail::send([], [], function ($message) {
    $message->to('fuga@gmail.com');
    $message->subject('Sample test');
    $message->setBody('<h1>It works!</h1>', 'text/html');
});
```

2段階認証をオフにするとメール送信できなくなりますのでご注意願う
Docker コンテナ内でゾンビプロセスが発生してしまう問題への対処

# この記事は何？
Dockerコンテナを動かしていてゾンビプロセスが大量に発生してしまう問題に対応したときのメモです。

# 現象

- Docker内で動作しているスクリプトを kill して別のスクリプトを動作させるような処理を書いていたが、コンテナを実行し続けると、killしたプロセスがゾンビプロセスとして残り続けてしまいました。（topコマンドで見ると以下のように STAT Z のプロセスが大量に存在する状態に。。。）

```
Mem: 6740044K used, 1407404K free, 108340K shrd, 243896K buff, 879356K cached
CPU:   0% usr   0% sys   0% nic 100% idle   0% io   0% irq   0% sirq
Load average: 0.07 0.19 0.59 2/1306 252
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
  249     1 root     S    18188   0%   0% /root/.cache/pypoetry/virtualenvs/app-9TtSrW0h-py3.9/bin/python app.py
    7     0 root     S     5748   0%   0% /bin/bash
    1     0 root     S     2208   0%   0% busybox crond -f -L /dev/stderr
  252     7 root     R     2208   0%   0% busybox top
   71     1 root     Z        0   0%   0% [python]
   50     1 root     Z        0   0%   0% [python]
  127     1 root     Z        0   0%   0% [python]
  218     1 root     Z        0   0%   0% [python]
  163     1 root     Z        0   0%   0% [python]
  123     1 root     Z        0   0%   0% [python]
  183     1 root     Z        0   0%   0% [python]
  119     1 root     Z        0   0%   0% [python]
  132     1 root     Z        0   0%   0% [python]
  171     1 root     Z        0   0%   0% [python]
  150     1 root     Z        0   0%   0% [python]
  144     1 root     Z        0   0%   0% [python]
  115     1 root     Z        0   0%   0% [python]
```


# 結論

コンテナ起動時に init オプションを指定する。docker run なら **--init** オプションをつける。docker-composeなら **init:true** を指定する。

```yml
version: '3.8'

services:
  batch:
    container_name: batch
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - ./app:/app
    init : true
```
# 原因
docker コンテナ内でPID=1のプロセスが init プロセスでなかったため、シグナルを扱えず正常にプロセスを終了できなかったのが原因のようです。

## initプロセスについて
chatGPTに聞いたところ、以下の答えが返ってきました。参考までに。

1. initプロセスは、システムの起動からシャットダウンまでのライフサイクルを管理する役割を担っている。Linuxシステムにおいて特別な役割を持ち、PID=1のプロセスとなっている。
2. Dockerコンテナ内において、PID=1のプロセスは、initプロセスにならないようにすることが推奨されている。これは、Dockerコンテナが軽量かつ独立した環境であるため。Dockerfile 内に CMD や ENTRYPOINT を指定するとPID=1のプロセスがここで指定したコマンドになる。
3. Dockerコンテナ内でPID=1がinitプロセスでない場合、シグナルの扱い、デーモンの管理、コンテナの終了処理などに問題が生じる可能性がある。
4. これらの問題を回避するために、Dockerでは、軽量なinitシステムであるtiniなどを使用することが推奨されている。tiniは、PID=1を実行し、シグナルの受信やプロセスの管理などの必要な機能を提供することができる。
5. Docker Composeの`init`オプションや docker run の `--init` オプションは、Dockerコンテナ内でtiniを使用するためのオプション。tiniを使用することで、Dockerコンテナ内でPID=1のプロセスを管理し、シグナルの受信やプロセスの管理などの必要な機能を提供することができる。


# 参考
以下の記事を参考にさせていただきました。

[https://qiita.com/t_katsumura/items/ed105f1c139b24f7fe4f](https://qiita.com/t_katsumura/items/ed105f1c139b24f7fe4f)
【Vim】複数行に一括でコメントアウト


# Introduction

`Vim`で複数行をコメントアウトする際に、挿入モードで 1 行ずつ行っていた方がいたので共有します。

以前作成した fizzbuzz のコードを例にしていきます。

```python: fizzbuzz.py
import argparse


def fizzbuzz(start, end):
    for num in range(start, end + 1):
        if num % 3 == 0 and num % 5 == 0:
            print("FizzBuzz")
        elif num % 3 == 0:
            print("Fizz")
        elif num % 5 == 0:
            print("Buzz")
        else:
            print(num)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="FizzBuzz")
    parser.add_argument(
        "--start",
        "-s",
        type=int,
        default=1,
        help="Starting number(default:1)",
    )
    parser.add_argument(
        "--end",
        "-e",
        type=int,
        default=15,
        help="Ending number(default:15)",
    )
    args = parser.parse_args()

    fizzbuzz(args.start, args.end)
```

**本記事が少しでも読者様の学びに繋がれば幸いです！**
**「いいね」をしていただけると今後の励みになるので、是非お願いします！**

## 環境

Ubuntu22.04

## お忙しい方へ

1. `Ctrl` + `v`。
1. `k`キーでコメントアウト範囲を選択。
1. `Shift` + `i`
1. `#`等を入力。
1. `Esc`キーで抜ける。

## 1 行のコメントアウト

1 行の場合は`i`キーで挿入モードにし、コメントアウトしたい行の頭で`#`等を入力します。
削除する場合は通常モードで`x`を入力します。
ちなみに`Vim`では`0`キーで行の頭に移動できます。

![Screenshot from 2023-04-25 20-25-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292052/84545765-c46a-8c46-8a23-5c578697f3b0.png)

## 複数行のコメントアウト

複数行のコメントアウトは以下の手順を行います。

1. `0`キーで行の頭に移動します。
1. `Ctrl` + `v`で矩形ビジュアルモードにします。
   ![Screenshot from 2023-04-25 20-47-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292052/c460ea2f-c79e-069d-e014-eda06bddfd50.png)
1. `k`キーで下に移動し、コメントアウトしたい行の範囲まで選択します。
   ![Screenshot from 2023-04-25 20-49-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292052/b3a246cb-1413-eee2-18d5-f241fe96e025.png)
1. `Shift` + `i`で挿入モードにすると選択範囲の 1 行目に遷移するので、`#`等を入力します。
   入力は 1 行だけで大丈夫です。
   ![Screenshot from 2023-04-25 20-50-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292052/61a7a60f-bd3b-1b52-1ce6-3bac10a3853f.png)
1. `Esc`キーで抜けると、選択範囲すべてに`#`等の入力した文字が反映されます。
   ちなみに`Ctrl` + `[`キーでも`Esc`同様の処理になります。
   `Esc`キーで小指を痛めている方は試してみてください。
   ![Screenshot from 2023-04-25 20-51-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292052/8fd92148-a52c-528e-5ea0-4239b93876b4.png)
   以上で一括コメントアウトは完了です。

## 複数行のコメントアウトを削除

一括削除する場合、複数行のコメントアウトの 3. の範囲選択までは同じです。

1. 範囲選択をしたら、`d`キーで一括削除できます。
   ![Screenshot from 2023-04-25 20-44-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292052/bfbe8b9d-65bb-fc9c-7421-03bc75ffad70.png)

## 最後に

閲覧頂きありがとうございました。
今回は頻度が多いであろう一括コメントアウトとして記事にしましたが、`#`を別の文字列にすれば複数行に同じ文字を入力する手法として応用可能です。
是非参考にしてみてください。
本記事がお役に立てば幸いです！
「print」「puts」「p」メソッドについて

### 「print」「puts」「p」3つのメソッドについてまとめてみる

#### 主な違い

- 改行するかしないか
- オブジェクトの情報も出力するか
- 「puts」と「p」は出力した後に改行するのですが、「print」は改行しない。

- 「puts」と「p」はいずれも改行するが、「p」メソッドはオブジェクトの情報も出力する。

#### printメソッド
- 引数を順番に出力する
-  改行をしない
- 文字列以外のオブジェクトは、to_s メソッドによって文字列に変換される
- 改行を入れる場合は改行文字（\n）を付ける
- 戻り値はnil

#### putsメソッド

- 引数を順番に出力する
- 改行をする
- 文字列以外のオブジェクトは、to_s メソッドによって文字列に変換される
-  配列の場合は要素を順番に出力する
- 戻り値はnil

#### pメソッド
- 引数を順番に出力する
- 改行をする
- オブジェクトを見やすいように出力する
- \nや\tなどのエスケープ文字もそのまま出力する
- 戻り値は引数で配列で返す
- 主にデバッグで使用される

#### まとめ

- 「print」は、引数を文字列にして出力し、改行をいれない
- 「puts」は、引数を文字列にして出力し、改行をいれる
- 「p」は、改行をいれる。デバッグでよく使用する。
CDKでインフラを構築してみた

# 概要
近年のWebアプリに必要そうなインフラをCDKを用いて構築
- コンテナオーケストレーション
- CI/CD
- SPA構成のWebアプリ
![インフラ構成図.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2823004/f4275319-69c8-8e94-161f-bb730258cef3.jpeg)

リポジトリ
https://github.com/salt0000/portfolio/tree/main/infra
※これからもアップデート予定

# 環境
- Docker
- CDK(2.75.1)

# 詳細
全てCDKで構築しているわけではなく、一部マネコンを使っている
マネコンでの作業
- ドメイン取得
- ACMを使ってSSL/TSL証明書を取得
- GitHubアカウントの認証連携
- ParameterStoreでアプリの環境変数などを設定
- EC2のPemファイル作成

CDKで行っている事
- Route53
    - ALBのレコード追加
    - CloudFrontのレコード追加
- CodePipeline
    - CodeStarを使ってGitHubとの連携
    - CodeBuild
        - Clientアプリのビルドとデプロイ
        - APIのDocker BuildなどECSにデプロイするための準備
    - CodePipelineのデプロイ
        - ECSのサービスとタスクを更新
- ECS
    - クラスター、タスク定義書、サービスの作成
- VPC
    - 自動でパブリックサブネットが二つ作成されるようにしている(ALBを作成する都合上二つ必要)
- ALB
    - CodePipelineでCI/CDするために必要
    - EC2に新しいコンテナをデプロイするときにホストのポートが衝突してしまう
    - それを防ぐためにALBの動的ポートマッピングを使っている
    - ホスト側のランダムなポートとコンテナのポートを繋げて、ALBのTGでホストのポートを設定、更新する事でポートが衝突しない
- S3・CloudFront
    - S3へのアクセスはCloudFrontに制限している


# 感想
僕が作ったようなCDKのサンプルってないなーと思って作成しました。
コードに直接AWSのパラメータを埋め込むからそれを公開はしな方がいいからサンプルリポジトリが少ないのかと、作ってる途中に思いました。
僕の場合は、ARNとか一部情報を伏せてGitHubにPushしています。(ローカルと差異があって、めっちゃやりづらい。。。)
かなり勢いで作成したので、たくさんメンテナンスが必要そう。。。
これからも随時更新していこうと思っています。
Node.jsでHelloWorldを実装してみた

# 概要
今日はNode.jsのお勉強ということで、HelloWorldプログラムを実装してみました。
以下のページを参考にしました。
https://jsprimer.net/use-case/nodecli/helloworld/

# ソースコード
上記のページのものをそのまま利用させていただきました。
```main.js
console.log("Hello World!");
```

# 実行結果
以下の通りプログラムを実行しました。無事動いているようです。
```
$ node main.js 
Hello World!
```

何かの役に立てばと。
Salesforceの無料アプリRecord Hunterを使ってみよう

Salesforceで無料で使えるApp Exchange Record Hunter
(通称レコハン)
について解説しました

https://appexchangejp.salesforce.com/appxListingDetail?listingId=a0N3A00000FeGdYUAV


このRecord Hunterを使用すれば、レコードの検索を容易にすることが可能です



今回の内容は動画でも公開しています

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

<iframe width="560" height="315" src="https://www.youtube.com/embed/gc5v4NwfE7w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>




※注意１※　本番環境でいきなりインストールするのではなく、
まずはSandboxやplaygroundで試しにインストールして仕様をご確認ください

※注意２※　今回はplaygroundにインストールします。AppExchangeの
Playgroundのインストール方法は割愛しますので下記Trailheadをご参照ください
https://trailhead.salesforce.com/content/learn/modules/trailhead_playground_management

ここではRecord Hunterの設定を確認しましょう


１　パッケージをインストールする

まずはRecord Hunterのパッケージをインストールします

２編集ページから「Data Table」「Search Box」を追加する
![レコードハンター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a54e0d25-8ac4-8487-b16c-db18a51048cf.png)


これで設定は完了です
あとは
Target Objectには検索したいオブジェクト
Column　Fieldsには検索したい項目のAPI参照名を設定します
![オブジェクト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/404a79c3-9f69-4f79-72a8-199cba33dded.png)


これで完成です

こうすれば複数の項目でレコードの検索をすることが可能です

![レコードハンター０１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/96fae22e-31b3-7dda-0730-fe5dbd4f5992.png)
【UltraLeap × Unity】 UnityでUltraLeapを操作できるようにするまでの手順

## 概要
今回は、UnityでUltraLeapを使用するための導入方法をまとめてみました。
また、TOUCHFREE TOOLINGについても少し紹介していますので、よければ導入の際に参考にしてみてください！

## 参考記事
- [UltraLeap公式サイト](https://www.ultraleap.com/)
- [開発者向け公式ドキュメント](https://developer.leapmotion.com/)

## 開発環境・使用したプラグインなど
- Windows
- Unity バージョン : **2021.3.20 LTS**
- TRACKING ソフトウェア - Gemini
    - このUnityプラグインは、Unity **2020.3 LTS** または **2021.3 LT**S で開くことを想定されているとのことです。
- [Ultraleap Unity Plugin](https://github.com/ultraleap/UnityPlugin)

## 作業内容
### 1. Ultraleap Gemini の最新版をダウンロードする
- [こちら](https://developer.leapmotion.com/tracking-software-download)のサイトから最新版のソフトウェアをダウンロードし、表示された内容に沿ってインストールする。
 ※ 今回はWindowsで作業するため、Windows用のソフトウェアをインストールしています。
 ![スクリーンショット 2023-04-25 19.10.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669177/df582fc3-ba86-8a4f-9052-48090c4cceb9.png)

### 2. UltraLeap Plugin for Unity の最新版をダウンロードする
ダウンロードする手順として、いくつか方法があるとのことです。
- OpenUPM経由のUPMパッケージでダウンロードする場合 (※今回はこちら)
    - 詳しい方法は[サイト](https://github.com/ultraleap/UnityPlugin)内のREADME.mdを見ながらインポートする。
- 配布されてる.unityPackageダウンロードする場合
    - [こちら](https://github.com/ultraleap/UnityPlugin/releases/)から.unityPackageをダウンロードする。

### 3. パッケージが追加できているかの確認
- パッケージをインポートすると、`Package/UltraLeap Tracking`と`Package/UltraLeap Tracking Preview`が追加されます。
 また、それぞれのサンプルが下記に入っているので、そこからSceneなどを実行して確認することができます。
    - `Assets/Samples/UltraLeap Tracking/6.6.0/Example`
    - `Assets/Samples/UltraLeap Tracking Preview/6.6.0/Example`

### 4. おまけ (UltraLeapのドキュメントについて)
- UltraLeapのドキュメントは[こちら](https://docs.ultraleap.com/unity-api/)にあるので、必要な時に見てみると良いかと思います。


## TOUCHFREE TOOLINGについて

### TOUCHFREE TOOLING とは？
TouchFree Tooling を使用すると、開発者は TouchFree のタッチレス テクノロジをターゲット アプリケーションにネイティブ機能として統合できます。
(一度試しに使ってみましたが簡単に導入できる上に操作もしやすく、とても便利でした！)

### ダウンロード方法
[こちら](https://developer.leapmotion.com/touchfree-tooling-unity)のサイトから、Unityで使用するためのTOUCHFREE TOOLINGプラグインをダウンロードしてくることができます。

### 使用方法
- サンプルシーンを使って確認する
    - ダウンロードした.unitypackageをUnityプロジェクトにインポートすると、Assets ディレクトリのTouchFree/Tooling/Examplesにサンプル用のSceneが追加される。
- 自身で作成した既存のSceneに統合して確認する
    - パッケージがインポートされると、TouchFree/Tooling/Prefabsの下にTouchFree Client Prefabがあるので、それをSceneに追加する。
HTMLの要素から、cssパスを取得したいとき

スクレイピングをしていて、HTMLにバリエーションが様々あった場合に、HTMLの要素からCSSパスを取得したいことがある。
この場合、下記のようにして、要素からCSSパスを取得することができる。

```python
from bs4 import BeautifulSoup
import cssselect

def get_css_path(element):
    path = []
    while element is not None and element.name is not None:
        siblings = [sibling for sibling in element.find_previous_siblings() if sibling.name == element.name]
        index = len(siblings) + 1
        if index > 1:
            path.insert(0, f'{element.name}:nth-of-type({index})')
        else:
            path.insert(0, element.name)
        element = element.parent
    return ' > '.join(path)

html_doc = '''
<!DOCTYPE html>
<html>
<head>
    <title>Page Title</title>
</head>
<body>
    <div class="container">
        <h1>My Heading</h1>
        <p>My first paragraph.</p>
        <p>My second paragraph.</p>
    </div>
</body>
</html>
'''

soup = BeautifulSoup(html_doc, 'html.parser')
element = soup.select_one('p')  # You can replace this with your desired element
css_path = get_css_path(element)
print(css_path)
```
Machine Learning Development

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236380/b61d26b6-621a-b575-b2a7-33455e5a3164.png)

As a Machine learning development company, our machine learning solutions and services are aimed at giving businesses data-driven, tech-enabled capabilities to stay ahead. From small businesses to medium enterprises to large companies, our services are designed to suit all.
https://www.orangemantra.com/services/machine-learning/
[ServiceNow]リスト編集の設定方法集

## はじめに
リスト編集の制御についてリストコントロールとACL（list_edit）は知っていたのですが
UIプロパティからも制御できること知らなかったので各制御の設定方法を記載する。

## 動作環境
Tokyo

## それぞれの利用用途

|設定|説明|
|:---|:---|
|UIプロパティ|システム全体でリスト編集を制御したい場合に利用|
|リストコントロール|テーブル単位でリスト編集を制御したい場合に利用|
|ACL（list_edit）|テーブルの項目単位やロールによって編集を制御したい場合に利用|

下記順に処理され上位のもので編集制限がかかった場合、
下位のもので制限がかけられていなくてもリスト編集ができなくなる
UIプロパティ > リストコントロール > ACL（list_edit）

## 設定方法
### UIプロパティ
1.System Properties > UI Propertiesを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/5016881d-5322-10dd-a7d1-197f13f52ec6.png)


2.Enable list editing.のチェックを外し「Save」を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/4edda1a3-2d1a-2994-8a47-5f1d16245ba1.png)

項目をダブルクリックしても項目の編集ができなくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/e3347882-d486-d356-ce71-62398aa7c004.png)

### リストコントロール
1.制御を行いたいテーブルのリストを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/2dab3649-5fad-be80-2859-25e69720a2f7.png)

2.Configure > List Controlを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/348fad92-de90-1810-06c6-06919f2ccc1f.png)


3.List edit typeをDisable list editingに変更し「Update」を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/822559a7-a1f4-88b8-7bb2-892c48cf1bff.png)

項目をダブルクリックしても項目の編集ができなくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/5ef1eb51-0244-85cc-ead4-e97bed2a3fc4.png)

### ACL（list_edit）
1.ACLを追加するためsecurity_adminにElevate roleする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/83647825-7883-e8c2-c53a-dd958357f729.png)

2.制御を行いたいテーブルの構成画面を開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/ffee89c4-d6bc-39c7-1ac4-3e96a79483ea.png)

3.ページ下部にあるAccess Controlsタブの「New」を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/23930283-e39b-cfa4-ec56-609c65c9335c.png)

4.Operationをlist_editにしNameとRequires roleを設定し「Submit」を押下する。
今回はadminロールを持っている場合、Short descriptionが編集できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/fdf9bd7a-1e06-b06d-334c-ef0d3e6748c7.png)

admin権限を持つユーザだと編集できるが、権限がないユーザは編集できなくなっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/2f731607-6df7-b787-4e63-025c6b10f14f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/4bc59d3a-63fd-606c-799a-c8cd84c56be0.png)
素数かどうかを調べる方法

# rubyで素数かどうかを調べる方法
## 背景
とある練習問題で、ある自然数nが素数かどうかを調べる方法を求めなさいという問題があり、自分なりに解いてみた方法です。

### そもそも素数とは？
素数（そすう、英: primeあるいはprime number）とは、2 以上の自然数で、正の約数が 1 と自分自身のみであるもののことである。正の約数の個数が 2 である自然数と言い換えることもできる。(引用:ウィキペディア（Wikipedia）)

つまり1以外の自然数で自然数nを1と自然数nでしか割り切れない自然数が素数となるということです。

### 考え方
ではnが素数かどうかを調べるにはどうすればいいのか？
考え方としては、1とn以外にもnを割り切れる数があればnは素数ではなく、割り切れる数が他にない場合はnは素数であると言えると思います。
なのでnを2からnより小さい最大数まで一つずつ割っていき、割り切れる数、つまり余り0の数があった場合は素数ではなく、どの数でも割り切れなかった場合は素数となります。
※1は素数であってもnを割り切れる数なので、2から割り切れるか検証します
※nより大きい数は素数であってもなくてもnを割り切れないので検証対象ではありません
※n自身は素数であってもnを割り切れる数なので検証対象ではありません

### 実際のコード
言葉にするとややこしいので実際にコードにしてみます
```ruby
puts "素数かどうか調べます。調べたい自然数を入力してください"
# 変数nが調べたい数字となります
n = gets.to_i

# 自然数でない値が入力された場合、再入力させます
if n == 0
  while n == 0
    puts "自然数を入力してください"
    n = gets.to_i
  end
end

# 素数の定義として「2以上の自然数で、正の約数が1と自分自身のみであるもの」とあるので、1が入力された場合は素数ではないというメッセージを表示します
if n == 1
  puts "1は素数ではありません"
  return
end

# 2からnより小さい最大数まで調べたいのでいったん2を変数iに代入します
i = 2

# iがnより小さい最大数になるまでnをiで割っていきます
while i < n
  # nがiで割り切れるかを検証します
  if n % i == 0
    #割り切れた場合は素数ではないというメッセージが表示されその時点で処理が停止されます
    puts "#{n}は素数ではありません"
    return
  end
  #iに1を足します
  i += 1
end

#returnで処理が終了しなかった場合素数であるというメッセージが表示されます
puts "#{n}は素数です"

```
これでnが素数かどうか調べることができました。

### 終わりに
とりあえずQiitaにアカウント登録してから初めての投稿なので、テストと思いつつの投稿です。
内容としては、自分が解いた練習問題の模範回答があまりしっくり来なかったので自分なりの解き方を提示してみました。
基本これまでrubyしか学んできていないのですが、アルゴリズムの問題は言語が変わっても活かせるものかなと思うので引き続き取り組んでいきたいと思います。
AWS公式のサーバーレスハンズオンやってみた

## **はじめに**

AWSのサーバーレスアーキテクチャの公式ハンズオンをやってみました。詳細な手順は以下のリンクをご確認ください。

**[https://aws.amazon.com/jp/getting-started/hands-on/build-web-app-s3-lambda-api-gateway-dynamodb/?trk=gs_card](https://aws.amazon.com/jp/getting-started/hands-on/build-web-app-s3-lambda-api-gateway-dynamodb/?trk=gs_card)**

このハンズオンは、大体30分～40分程度で完了します。

### **概要**

使用したサービス:

- AWS Amplify
- AWS IAM
- Amazon API Gateway
- AWS Lambda
- Amazon DynamoDB

### **記事の目的**

この記事の目的は、ハンズオンを通してサーバーレスアーキテクチャの基礎を理解し、各サービスの基本設定を学ぶことです。
※細かい手順等は記載していません。あくまでも全体的な流れのみです。

## **手順**

### **フロントエンドの作成**

AWS Amplifyというサービスを使用して、「Hello World」のみを表示するindex.htmlをデプロイします。Amplifyはフロントエンドの開発を簡単にしてくれるサービスで、今回初めて使用しましたが、作成したhtmlファイルを数クリックでデプロイできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/4f985d61-9a72-5055-c806-0134d310ecfc.png)

### **関数の作成**

次に、AWS Lambdaを使って関数を作成します。Lambdaは、AWSが提供するサーバーレスコンピューティングサービスで、プログラミングの関数やコードをAWSに保管し、サーバーを用意せずに関数をいつでも使用できます。

このステップでは、Pythonで名前と苗字をJSONで受け取り、レスポンスを返す関数を作成しています。このハンズオンでは、Python以外にもJavaScriptとJavaのサンプルコードが用意されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/123be619-49ff-2a96-deee-ffbc660a78d2.png)

### **APIの作成**

次に、Amazon API Gatewayを使ってAPIを作成します。API Gatewayは、先ほど作成したAmplifyのフロントエンドとLambda関数をつなげるためのサービスです。ここでは、APIを作成し、POSTメソッドを使ってLambdaに値を渡します。これでAPI Gatewayを使ってLambdaを呼び出すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/6bedbe95-0dcc-5027-856b-f1e6c1df5c1f.png)

### **データベースの作成**

次に、Amazon DynamoDBを使ってデータベースを作成します。DynamoDBはNoSQL型のデータベースで、読み書きが高速であり、サーバーレスで自動的にスケーリングすることが特徴です。

ここでは、DynamoDBを作成し、先ほど作成したLambdaからアクセスできるようにIAMポリシーを作成してLambdaに割り当てます。LambdaにIAMポリシーが割り当てられたら、Lambdaのコードを書き換えてDynamoDBにデータを書き込みます。DynamoDBのコンソール画面からテストデータが登録されていれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/a0cd8b68-8236-b10b-8b80-e53a3713ef9d.png)

### **WebページからLambdaの呼び出し**

最後に、これまで構築してきたものを連携させて、WebページからLambdaを呼び出し、DynamoDBにデータを登録します。

index.htmlを書き換えて、API Gatewayにリクエストを送るように設定します。この際、index.htmlにAPI Gatewayの呼び出しURLを記載する必要があります。ARNではないので注意してください。

Webページで入力した名前と苗字が画面上に表示されることを確認したら、マネジメントコンソールからDynamoDBを確認してみましょう。先ほど入力した名前が登録されているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880800/12feb13f-94bf-dcee-9993-8509d5fd3664.png)

### **クリーンアップ**

ハンズオンが終わったら、構築した環境を削除して、課金が発生しないようにしましょう。

## **まとめ**

サーバーレスのサービスは、自動的にスケーリングが行われ、管理する部分も少ないため、手軽に始められると感じました。次のステップとして、フロントエンドの静的ファイルをAmazon S3から配信したり、DynamoDBの代わりにAmazon RDSを使用してみるなど、様々なアプローチが可能です。このハンズオンを通じて、AWSのサーバーレスアーキテクチャの基本を理解し、各サービスの設定方法を学ぶことができました。
GlassFish4:SSL暗号化通信を有効後javax.net.ssl.SSLHandshakeExceptionが発生した

### 事象
GlassFish4をSSL暗合化通信を有効化で、以下のコマンドを実行後、GlassFish4のドメインの起動、終了が行えなくなりました。

```shell
./asadmin enable-secure-admin
```

ログには、javax.net.ssl.SSLHandshakeExceptionエラーが出力。
```
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
        at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:106)
        at sun.security.ssl.TransportContext.kickstart(TransportContext.java:238)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:410)
```

### 環境

* CentOS7.9
* jdk 1.8.0_361
* GlassFish4.1.2

### 対応
古いバージョンのJavaで動いたため、Javaのバージョンアップに伴い弱い暗号が許可されなくなったためのようです。いい対応策とは思っていないもののjava.securityファイルのjdk.tls.disabledAlgorithmsから「TLSv1」を削除して動作させています。

変更前
```
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
```

変更後
```
jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, RC4, DES, MD5withRSA, \
```
アメリカの大学院生活ガイド

【イントロダクション】
皆さん、こんにちは！私は先日[アメリカの大学院](https://www.pacific-edu.com/tw/html/news/show.php?kid=118&kid2=&nid=172)に留学してきた日本人留学生です。アメリカの大学院生活は、新しい文化や習慣に触れながら、勉強や研究に励むとてもエキサイティングな経験です。しかし、初めての[出国留学](https://www.pacific-edu.com/tw/html/news/show.php?kid=118&kid2=&nid=170)は不安もたくさんありますよね。そこで、私が体験したアメリカの研究所生活を通して、留学生活を楽しむためのガイドをお届けします！さあ、一緒にアメリカの研究所生活を満喫しましょう！

【本文】
１. 「言語の壁」を乗り越えよう！
アメリカの研究所では、英語が主要なコミュニケーション言語となります。初めてのアメリカ留学で英語に自信がなくても心配ありません！私も最初は英語の勉強を急ぐあまり、間違った表現を使って笑われることもありました。しかし、笑い話にできる程度になるまでの日々もまた思い出になりました。英語に自信がなくても、自分の意見を伝える勇気を持ちましょう！また、アメリカの大学では、自由な意見交換やディスカッションが重要な学習方法となっていますので、自分の意見をしっかり主張してみましょう！自分の考えを伝えることで、新しい発見や交流が待っているかもしれません。

２. [アメリカ留学](https://www.pacific-edu.com/tw/html/news/show.php?kid=118&kid2=&nid=171)ならではのカルチャーショック
アメリカは多民族・多文化が共存する国であり、留学生にとっては新しい文化や習慣に触れるチャンスです。しかし、初めてのアメリカ留学ではカルチャーショックを受けることもあるかもしれません。私も最初は日本とは異なる食事や服装、言葉遣いに戸惑いました。例えば、アメリカのレストランではチップを支払う習慣がありますが、最初は「何でこんなに高いの！？」と驚いたものです。また、アメリカ人のコミュニケーショションスタイルも日本とは異なり、ダイレクトでフレンドリーな傾向があります。最初は戸惑うかもしれませんが、慣れてくると楽しい交流が待っています。私はアメリカの友人たちと一緒にクッキングパーティーをしたり、文化の違いについて語り合ったりと、新しい経験を通じて充実した留学生活を送りました。

３. スリリングなアメリカ生活を満喫しよう！
アメリカの研究所生活は、勉強や研究だけでなく、様々な経験をすることができます。アメリカは自然も文化も豊かで、週末や休暇を利用して旅行やアクティビティを楽しむことができます。私は友人たちと一緒に国立公園を訪れたり、ビーチでサーフィンをしたり、地元のイベントに参加したりと、アメリカならではのスリリングな経験をたくさんしました。また、大学のクラブやサークルに参加することで、趣味や興味を共有する仲間を見つけることもできます。私はダンスのクラブに参加して、新しい友人を作ったり、アメリカのダンス文化に触れたりしました。留学生活を充実させるために、自分自身を新しい経験にチャレンジさせてみましょう！

４. 生活費を節約しよう！
アメリカの留学生活には、生活費がかかることも忘れてはいけません。特に大学院生は研究や学業に忙しく、アルバイトが難しい場合もあります。そこで、生活費を節約するための秘訣をご紹介します！まずは、予算を立てて自分の収入や支出を管理しましょう。食費は自炊をすることで節約できますし、授業の教科書は中古を購入するか、図書館で借りることもできます。また、学生向けの割引やクーポンを利用することもおすすめです。私は学生向けの割引を使って映画やレストランを楽しんでいました。さらに、ルームシェアリングをシェアすることで家賃を削減する方法もあります。私はルームメイトと一緒に住んで、家賃や光熱費を分担することで経済的な負担を軽減しました。また、無駄遣いを減らすために、自分の必要なものをリストアップしてから購入することもお勧めです。アメリカには誘惑がたくさんありますが、無駄遣いをせずに賢く節約することで、留学生活をより充実させることができます。
【SwiftUI】ColorPickerを使ってみた

# はじめに
ColorPickerというUIコンポーネントの存在は知っていたのですが、
今まで使う機会がなかったので試しに使ってみます。

# iOSのでの見た目
![Simulator Screen Shot - iPhone 14 - 2023-04-25 at 17.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/97e5ca2a-24a4-190f-54ba-603ab6646e9d.png)

# macOSでの見た目
![スクリーンショット 2023-04-25 17.35.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/6463727b-accf-4376-27ba-fce07750755c.png)

# 基本的な使い方
```swift
import SwiftUI

struct ContentView: View {
    @State var color: Color = .red
    var body: some View {
        ColorPicker(selection: $color) {
            Text("ColorPicker")
        }
    }
}
```

# カスタマイズ
### ラベルを消す
```diff_swift
import SwiftUI

struct ContentView: View {
    @State var color: Color = .red
    var body: some View {
        ColorPicker(selection: $color) {
            Text("ColorPicker")
        }
+       .labelsHidden()
    }
}
```

### 透明度を指定できなくする
```diff_swift
import SwiftUI

struct ContentView: View {
    @State var color: Color = .red
    var body: some View {
+       ColorPicker(selection: $color, supportsOpacity: false) {
            Text("ColorPicker")
        }
    }
}
```

# おわり
信じられないほど簡単ですねー
ただカスタマイズ性は低そうですね
アンカーリンクの移動先の位置がずれる原因

## 1. imgにloading="lazy"を指定し、smooth-scrollを使っている
smooth-scrollは、CSSでもjsでもこの組み合わせは不具合が出やすい。
画像の遅延読み込みによって画像の高さが認識されないため。なお、htmlに高さをwidth="100"など指定しても改善されなかったため、lazyloadを使うときはsmooth-scrollの使用を控えるか、loadingアニメの読み込み対象をサイト全体（main）に指定する。
サイトの表示速度を考えると前者が無難。

##  2. jsのsmooth-scrollを使っている
imgにlazyloadを使っていない場合、jsのsmooth-scrollを使っていると、cssのsmooth-scrollに変更すると直ることが多い。
（wordpress等）
Podman Desktop のインストール(for Windows)

# はじめに
このページではWindows版のPodman Desktopのインストール手順について記載しています。
Mac版は[こちら](https://qiita.com/LgmQue/items/a01367a49b973ee31a2f)を参照ください。
# インストーラーのダウンロード
下記リンク先を開き、中央にある **Download Now** をクリックします。

https://podman-desktop.io/

![001_Open_the_podman_desktop_TopPage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/777f5dde-22da-c696-0ee1-17d63552d749.jpeg)
Windows用のページが表示されたら再度 **Download Now** をクリックします。
![001_Download_the_Installer.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/54722c09-82f9-9af7-4a06-6bf8fc63ae3b.jpeg)
ダウンロードが完了したら、podman-desktop-{バージョン}-setup.exe を実行します。

> 記事執筆時点は podman-desktop-0.14.1-setup.exe でした。

プログレスバーが表示され、インストールが完了すると以下のような画面が表示されます。
![002_PodmanDesktop_TopPage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/84dd1b80-5fd4-4a77-41d5-36a591944bdd.jpeg)
右下にある **Go to Podman Desktop** をクリックすると、Podman Desktopを起動できます。
# Podman Desktop起動
それではインストールしたPodman Desktopを起動してみましょう。
ご利用の端末にPodmanの環境がある場合は、`Podman is running`と表示されます。
まだPodmanの環境がない場合は、`Podman Desktop was not able to find an installation of Podman`と表示されるので、右側にある **Install** をクリックします。
![003_Podman_Desktop_TopPage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/553550a1-2aa4-b642-068b-513bd1aa1937.png)
**Yes** をクリックします。
![XXX_Confirm_the_Podman_Install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/1e492b30-3c96-0b05-bc0f-849f8becf6ab.png)
指示に従い進めます。
![スクリーンショット 2023-04-25 170825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/191d3db9-4fd9-8ae8-2f81-746da2f5609d.png)
![スクリーンショット 2023-04-25 170841.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/a0397aa0-a63f-9ac1-cff3-a6d73c8973c3.png)
インストールが完了すると、先ほどのDashboard画面で **Podman is running** と表示されました。
![スクリーンショット 2023-04-25 172100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715466/1936ddb6-adda-7f6c-8de1-d6138f4d9129.png)

## 触ってみよう

こちらのGitHubにて操作方法を公開しています。

https://github.com/IBMDeveloperTokyo/podman_desktop
【AWS】"The specified rule does not exist in this security group."エラーでセキュリティグループからルールを削除出来ない場合の対処法

# 概要
セキュリティグループに設定されているインバウンドルール（アウトバウンドルール）を削除しようとすると`The specified rule does not exist in this security group.`と言われて削除出来ない。

# 再現方法
1. 新たなセキュリティグループのルール追加時に「説明」を設定してから適用する。
1. 再度セキュリティグループの編集を行い、追加したルールの「削除」を行う。
1. （ごく稀なケースで）適用を押すと上記エラーが発生する。

# 解決方法
「説明」を消して適用し、再度ルール削除を行ってから適用するとルールを消せる。
1. セキュリティグループの「インバウンドルールの編集」あるいは「アウトバウンドルールの編集」を選択する。
1. 消せないルールの「説明」を空文字にして適用する。
1. 再度、セキュリティグループの「インバウンドルールの編集」あるいは「アウトバウンドルールの編集」を選択する。
1. 消せないルールの「削除」を選択して適用する。
1. 削除出来ていることを確認する。

# 発生原因
恐らくセキュリティグループのルール追加時、AWS内部でデータ整合性が取れなくなってしまったために起きていた。そのため、ルールの説明を再適用してデータを同期させて削除出来る状態にする必要があった。

### 補足
上記の解決方法が無理なら、AWS CLIから色々なパラメータの組み合わせを試して削除する。
[AWS CLI Command Reference - revoke-security-group-ingress](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/revoke-security-group-ingress.html)

# 参考文献
https://stackoverflow.com/questions/52333418/aws-serverless-invalidpermission-notfound-the-specified-rule-does-not-exis
Armadillo-IoTゲートウェイ G4 LANモデル(AGX4500-C00D0)でNode-REDを動かすメモ

# 起動

LAN(Ethernet)ケーブル、USBキーボード・マウス、HDMI(micro HDMI)、ACアダプタを接続して起動します。

![IMG_0339.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/7f186811-114a-7c87-21c5-c68ba9275b3c.jpeg)

# rootアカウントでログイン

最初にログインする時にパスワードを設定します。

# パスワードの保存(永続化)

Armadillo BaseOS ではルートファイルシステムに overlayfs を採用しており、そのままではシステムが OFF すると内容は消えてしまいます。そのため persist_file コマンドが用意されています。このコマンドを利用することでファイル単位で変更を反映することができます。パスワードを設定した後には以下のコマンドを実行します。

```bash
# persist_file /etc/shadow
```

# リモート接続(SSH)を有効にする

```bash
# rc-update add sshd
# persist_file /etc/runlevels/default/sshd
```

リモートからrootでログインできるようにするため、/etc/ssh/sshd_configを変更する。

```bash
PermitRootLogin yes　　　　← 追記
PasswordAuthentication yes　← コメントイン
```

```bash
# persist_file /etc/ssh/sshd_config
```

再起動する。
再起動後、SSHキーを保存する。

```bash
# persist_file /etc/ssh/ssh_host_ecdsa_key
# persist_file /etc/ssh/ssh_host_ecdsa_key.pub
```

# Podmanのデータを永続化させる

```bash
# abos-ctrl podman-storage --disk
```

# Podmanを使ってNode-REDを起動する

(対話式で動かす)

```bash
# podman run -it -p 1880:1880 -v node_red_data:/data --name mynode-red docker.io/nodered/node-red
```

(バックグラウンドで動かす)

```bash
# podman run -d -p 1880:1880 -v node_red_data:/data --name mynode-red docker.io/nodered/node-red
```

以下のディレクトリにデータが保存(永続化)されます。

```bash
/var/lib/containers/storage/volumes/node_red_data
```

コンテナの一覧を表示します。

```bash
# podman container ls -a
CONTAINER ID  IMAGE                              COMMAND     CREATED        STATUS                        PORTS                   NAMES
959de778cf65  docker.io/nodered/node-red:latest              7 minutes ago  Up 43 seconds ago (starting)  0.0.0.0:1880->1880/tcp  mynode-red
```

コンテナを起動・停止します。

```bash
# podman container start <CONTAINER ID>
# podman container stop <CONTAINER ID>
```

![スクリーンショット 2023-04-25 17.23.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/71c91c1f-3219-9914-4421-5e430558b9ee.png)

![スクリーンショット 2023-04-25 17.24.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/e4373b24-3453-ea03-6164-da54175a9b2d.png)
Fullcalendarでイベントを長押しした時の動作を追加する

Fullcalendar ver.5にて

- long-press-eventを導入する
https://github.com/john-doherty/long-press-event
    - calendar.jsにlong-press-event.min.jsを転記することを忘れずに
    - https://github.com/john-doherty/long-press-event/blob/master/dist/long-press-event.min.js

- eventDidMountに以下を追加する
```calendar.js
eventDidMount: (e) => {
            e.el.addEventListener('long-press', function () {
                alert("長押し！")
            });
        },
```