OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.jsのUIコンポーネントならBuefyがおすすめ！

Buefy の良さを多くの人に体感して欲しいので  なるべく簡単に紹介します
何回かに分けて構成する予定

[公式ドキュメント](https://buefy.org/)

## 対象

-   Vue.js エンジニアでデザインを考えるのがめんどくさい人
-   Bootstrap に飽きた人
-   UI コンポーネント多くてどれがいいかわからない人

## Buefy とは

Bulma という CSS フレームワークを Vue.js で使えるようにしたもの
似たような物に Vuetify や Bootstrap-vue、Vue Material 等がある

↓ 参考にさせていただきました
[なんとなく Vue.js の UI フレームワークを紹介する][link-1]

## 何故 Buefy にしたの？

### インストールが簡単

npm/yarn でインストールして app.js で Vue.use するだけで OK！
超簡単なインストール方法に感動した

### 軽い！（気がする）

[公式 docs][buefy]でも

> Lightweight UI components for Vue.js based on Bulma

と書かれてるように、とても軽量

### ドキュメントが読みやすい

個人的にサイドメニューの子メニュー？が常に表示されている方が便利と感じるからそれが好き
後述のコンポーネントの少なさも相まって欲しいものが見つけやすい
ただ、[Bulma]が元になっているのもあり、Buefy のドキュメントからリンクが貼られて、「詳しくはこちら」と Bulma ドキュメントに飛ばされることがあるのは少しめんどくさい・・・

### コンポーネント数が少ない

少数精鋭で（個人的に）よく使うが揃えられているため、ドキュメントもみやすいし使い方も覚えやすかった
もちろんこれは、細かいところに手が届かないデメリットにもなりうる
その場合は他の UI コンポーネントや、個別のコンポーネントを採用するべき
例えば Buefy のカレンダーコンポーネントで実装が難しかったので、[v-calendar](https://vcalendar.io/)を使ったりした

### スタイルを簡単に変更できる

Buefy コンポーネントのデフォルトスタイルを scss でインポートすることで自由にスタイルを変えることができるのも魅力の一つだと思う
html タグに type 要素で指定できるコンポーネントの色合いを統一できるのが素晴らしい
詳しくは別の記事で（鋭意執筆中）

### 英語が結構簡単

残念ながらドキュメントは日本語には対応していない
でも英語がそこそこ簡単なので頑張れば読めると思う
なお翻訳は・・・・ぴえん
公式ドキュメント以外でも日本語の文献が少ないのは難点

## つまり・・・

-   ラーニングコストが低い
-   ドキュメントが読みやすいためストレス少なめ
-   少数精鋭で欲しいものが揃っている
-   自分の好きなスタイルを適用しやすい

**_<font color="#8c67ef">つまり Buefy はとてもいい！！</font>_**

## 後書き

個人的な見解なので、ここはメリットじゃないとか、もっとこういうところが良いんだよ！とか
あればコメントで指摘してもらえると助かります

Vue.js を勉強して、とりあえず何か作ろう！と思ったけどデザインを考えるのが大変・・・
という時にとりあえずお試しで使って、UI コンポーネントってなんなのかを知るにはとてもいいものだと思います
Buefy の使い方とかコツとか、実際に使ってみてハマったことを記事にしていこうと思ってるので興味があったら見てください

## 余談

[Buefy] に行き着くまでの流れをまとめました
興味のある方もない方もおまけ程度に読んでください
なお全て個人的な感想なので悪しからず

### 初めての UI コンポーネント

Vue.js を使い始めてしばらくしてから Vuetify を使ってみた 
[当時のドキュメント][vuetify]

> 今はドキュメントが変わっているみたい
> [新ドキュメント](https://next.vuetifyjs.com/en/)

ロゴがかっこいいからとりあえず使ってみた

~~活字嫌い~~ドキュメントとかちゃんと読むのが苦手・・・
そんな僕には Vuetify の公式ドキュメントが読みづらくてしょうがなかった
あとインストール（`vue add vuetify`）すると毎回何かしらエラーが起きてめんどくさかった
これは環境のせいもあるけど・・・

### 迷走期

会社で作っているシステムを Vue.js で今風の画面にリプレースする時にデザイン面をどう実装しようか考えていた
デザイン自体は決まっていたので折角だし新しい UI コンポーネントを探そうかと思い
[なんとなく Vue.js の UI フレームワークを紹介する][link-1]
ここを見ながら色々試していた

-   Bootstrap-vue

    Bootstrap がそもそも~~生理的に~~好きじゃないためパス

-   Quasar Framework

    やれること多すぎてドキュメントは読みやすいけど理解が大変だったのでパス

-   Vue Material

    上記リンクにはないけど気になったので使ってみた
    見た目かっちょいいけど [Buefy] と比べて導入がめんどくさかったのでパス

と色々試した結果 Buefy に行き着いた

## リンク集

### 参考記事

[なんとなく Vue.js の UI フレームワークを紹介する][link-1]

### 公式 Docs

[Buefy][]
[Bulma][]
[Vuetify][]
[Bootstrap-vue][]
[Quasar Framework][]
[Vue Material][]

[link-1]: https://qiita.com/yusuke_ten/items/4103f032dd0c6fbe5607
[vuetify]: https://vuetifyjs.com/ja/
[bootstrap-vue]: https://bootstrap-vue.org/
[quasar framework]: https://quasar.dev/
[vue material]: https://vuematerial.io/
[buefy]: https://buefy.org/
[bulma]: https://bulma.io/
Macのストレージ回復用コマンド一覧(自分メモ)

## 5GB以上のフォルダを羅列
```
$ sudo du -g -x -d 6 / | awk '$1 >= 5{print}'
```

## 一旦docker系のimageやcontainerを全部消し飛ばす。
`Users/{username}/Library/Containers/com.docker.docker/Data`が重かった時は…
#### 全コンテナさよなら
```
$ docker rm $(docker ps -aq)
```

#### 全イメージさよなら
```
$ docker rmi $(docker images -q)
```

##
Logic Apps Tips - Azure Key Vaultを使う①

#概要
証明書やパスワードの管理に使用できるAzure Key Vault。
これをAzure Logic Appsで使う方法の備忘録。

2回に分けて書いていきます。
今回は、シークレットの取得まで。

#経緯
当社では電子ロック「Akerun」を使用していて、
APIを使用して使用状況を取得しています。
⇒最初の入室者と最終の退出者を確認したり。

それを自動化するのにLogic Appsを使用しています。

Akerun APIのトークンを、Azure Key Vaultで管理しています。

#Key Vaultでトークンを管理する
Azureポータルにログインし、Market PlaceでAzure Key Vaultを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/31700c73-8025-cee0-5251-dee4f02afdf9.png)

作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/805d0329-46b0-b041-ab36-88cef29ebe5b.png)

続いてキーコンテナを作成します。
Key Vault名など必要な情報を入力してください。
確認および作成ボタンをクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/702bf124-3fba-f2b0-2aa1-4ba02d5d2a5e.png)

確認画面が表示されるので、作成ボタンをクリックしてください。
デプロイが始まります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/6610628a-f8e1-bf8c-b7a7-acd7db3f7388.png)

デプロイが終わったら、続いてシークレットを作成し、そこにトークンを保存します。
作成したKey Vault（ここではQiitaTestKeyVault）のブレードから、「シークレット」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/4defc4d2-d7a6-e82c-0e15-1f41303617bc.png)

「生成/インポート」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/070cb18c-8b2f-3723-eb40-30fb958db8e3.png)

以下のような画面が表示されるので、名前と値を入力します。
⇒値の欄にトークンなどのKey Vaultで管理したいデータを入力します。
最後に「作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/46a86334-4e14-14d4-f389-6d2755717dcf.png)


#Logic Appsでシークレットを取得する
Logic Appsでシークレットを取得するのは簡単です。
コネクタにKey Vaultがあるので、それを利用するだけ。

アクションの検索窓でKey Vaultを入力すると、コネクタに「Azure Key Vault」が出てくるので、クリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/d5f7ac3d-c9bf-64ff-92e4-db31062a0a17.png)

アクションの一覧が出てきます。
スクロールしていくと、一番下に「シークレットの取得」があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/4b6c5eb3-0c8e-e39d-a4bf-af6d2db1895d.png)

以下のような画面が表示されるので、
資格情報コンテナー名に作成したKey Vaultの名前（ここではQiitaTestKeyVault）を入力し、
サインインをクリックします。
**※資格情報コンテナー名を入力せずにサインインすると、その後のシークレットの選択ができないので注意！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/d77855cb-be83-c0bf-e471-ea73d0ef8d41.png)

Microsoftアカウントのログイン画面が出てきます。
Key Vaultを生成したアカウント（通常はLogic Appsを作成しているアカウント）でログインしてください。

以下のような画面になるので、プルダウンから取得したいシークレットの名前を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/ba8874fc-11f7-6f47-778b-a56d102c717f.png)


今回はLogic AppでAzure Key Vaultのシークレットを取得するところまで書いてみました。
次回はLogic Appでシークレットを更新する手順を書きます。
Amazon Personalizeの概要

#Amazon Personalize とは
Amazon Personalize とはAmazon.com と同様のテクノロジーを利用し、
機械学習の知識がなくても、個々のユーザー向けにリコメンデーションをリアルタイムで提供できるサービスです。
#Amazon Personalize の機能一覧

- ユーザー属性を基にパーソナライズされたレコメンデーションリストを作成
- 特定のアイテムをチェックした際に、類似アイテムリストを提供
- 特定のアイテムリストをユーザーの嗜好に合わせて並び替える

#Amazon Personalize のワークフロー
1.入力データをフォーマットしてAmazon S3にアップロードするか、リアルタイムのイベントデータを送信する。
2.データに適用するトレーニングレシピ (アルゴリズム) を選択する。
3.レシピを使用してソリューションバージョン(レコメンデーションモデル)をトレーニングする。
4.ソリューションバージョンをデプロイする。
5.レコメンデーションAPIのいずれかを呼び出して、レコメンデーションを提供する。
#データセットの種類
Amazon Personalizeでは、以下の3種類のデータセットを使用します。
データセット型の Users や Items はメタデータ型と呼ばれ、特定のレシピでのみ使用されます。

データセットの種類 | 用途 | 説明 |
|:-----------|------------:|:------------:|
| Interactions       | 全てのレシピで使用        | ユーザーとアイテム間の過去のインタラクションデータ<br>例：購買履歴、視聴履歴         |
| Users     | メタデータを利用するレシピで利用      | ユーザーに関するメタデータ<br>例：年齢、性別など      |
| Items       | メタデータを利用するレシピで利用        | アイテムに関するメタデータ<br> 例：価格、ジャンルなど        |
#レシピの種類
レシピ（アルゴリズム）は大きく分けて3つあります。これらをケースごとに使い分けてください。

- USER_PERSONALIZATION →　特定ユーザー向けのアイテムリストを取得
- PERSONALIZED_RANKING →　渡したアイテムリストをユーザー向けに並び替え
- RELATED_ITEMS →　特定アイテムの類似アイテムリストの取得

| レシピタイプ | API | 要件 |
|:-----------|------------:|:------------:|
| USER_PERSONALIZATION       | GetRecommendations        | userId: 必須<br>itemId:オプション <br>inputList: 該当なし         |
| PERSONALIZED_RANKING     | GetPersonalizedRanking      | userId: 必須<br>itemId: 該当なし<br>inputList: itemId のリスト       |
| RELATED_ITEMS       | GetRecommendations        | userId: 使用されない<br>itemId: 必須<br>inputList: 該当なし         |
#使用料金
データ取り込み→0.05USD/GB
トレーニング→0.24USD/トレーニング時間
レコメンデーション：
1か月あたり最初の2万TPS時間まで→ 1TPS時間につき0.20USD
1 か月あたり次の18万TPS時間まで→1TPS時間につき0.10USD
1 か月あたり20万TPS時間以降→1TPS時間につき0.05USD
#料金例
**データ取り込み：**
月間200GBの場合
→200GB ×　0.05USD/1GB = 10USD
**トレーニング：**
1日10トレーニング時間かかるトレーニングを実施した場合
→10トレーニング時間 × 30 × 0.24USD/1トレーニング時間 = 72USD
**レコメンデーション：**
10TPSのスループットを利用
→10TPS x 24時間 x 30日 x 0.20USD/TPS-時間 = 1,440 USD

**合計コスト = 10USD + 72USD + 1,440USD = 1,522USD**
#おわりに
次回はAmazon Personalizeの実装方法を解説いたします。
お楽しみに！
PHPの配列、オブジェクトの参照渡しを検証する

# やりたこと
foreachでオブジェクトを含む配列をコピーしたりすると思わぬバグにはまることがある。（あった）
配列、二次元配列、オブジェクト、オブジェクトを含むオブジェクトをコピーするとどのような動作をし、どうすれば期待する動作になるかサンプルコードで検証する。

# 環境
* PHP7.4

# 実装

## 配列
配列は値渡しなので別の変数に代入した場合、別変数の値を書き換えても元々の変数には影響しない。

```test.php
$test = ['a'=>1,'b'=>2];
$test2 = $test;
$test2['a'] = 3;
var_dump($test);
exit;

/*
array (size=2)
  'a' => int 1←変更されない
  'b' => int 2
*/
```

## 二次元配列
通常の配列と同様。

```test.php
$test = ['a'=>['c'=>1],'b'=>['d'=>2]];
$test2 = $test;
$test2['a']['c'] = 3;
var_dump($test);
exit;

/*
array (size=2)
  'a' => 
    array (size=1)
      'c' => int 1←変更されない
  'b' => 
    array (size=1)
      'd' => int 2
*/
```

## オブジェクト(単純に代入)←ハマりポイント1
オブジェクトは参照渡し（正確にはオブジェクトのID渡し？[マニュアル](https://www.php.net/manual/ja/language.oop5.references.php)）なので、代入した別の変数の値を変更すると、元々の変数にも影響する。

```test.php
$test = (object)['a'=>1,'b'=>2];
$test2 = $test;
$test2->a = 3;
var_dump($test);
exit;

/*
object(stdClass)[161]
  public 'a' => int 3←変更される
  public 'b' => int 2
*/
```

## オブジェクト(cloneして代入)
別オブジェクトとして扱いたい場合は`clone`を利用する。

```test.php
$test = (object)['a'=>1,'b'=>2];
$test2 = clone $test;
$test2->a = 3;
var_dump($test);
exit;

/*
object(stdClass)[161]
  public 'a' => int 1←変更されない
  public 'b' => int 2
*/
```

## オブジェクトを含むオブジェクト(cloneして代入)←ハマりポイント２
cloneしても、オブジェクトの中のオブジェクトは~~参照渡しとなる~~同じ参照先（リファレンス）を保持する。（←コメント参照）
これはPHPのcloneはシャローコピーだから。（[マニュアル](https://www.php.net/manual/ja/language.oop5.cloning.php)）

```test.php
$test = (object)['a'=>(object)['c'=>1],'b'=>(object)['d'=>2]];
$test2 = clone $test;
$test2->a->c = 3;
var_dump($test);
exit;

/*
object(stdClass)[210]
  public 'a' => 
    object(stdClass)[161]
      public 'c' => int 3←変更される
  public 'b' => 
    object(stdClass)[171]
      public 'd' => int 2
*/
```

## オブジェクトを含むオブジェクト(シリアライズ&デシリアライズして代入)
[マニュアル](https://www.php.net/manual/ja/language.oop5.cloning.php)には`__clone`を実装するように記載されているが、常にできるわけではない。
一番簡単なのはシリアライズしてからデシリアイズする方法。

```test.php
$test = (object)['a'=>(object)['c'=>1],'b'=>(object)['d'=>2]];
$test2 = unserialize(serialize($test));
$test2->a->c = 3;
var_dump($test);
exit;

/*
object(stdClass)[211]
  public 'a' => 
    object(stdClass)[161]
      public 'c' => int 1←変更されない
  public 'b' => 
    object(stdClass)[175]
      public 'd' => int 2
*/
```

# 参考
ありがとうございます。
https://qiita.com/A-Kira/items/749de2c83dfd07feb3b3
https://qiita.com/horikeso/items/29c8d412e57f2097855b
PiterestのカスタムSNSアイコンの設置

bodyの終了タグの前にpinit.jsを記述。

```
<script async defer src="//assets.pinterest.com/js/pinit.js"></script>
</body>​
```


aタグ内にdata-pin-custom="true" を入れたら出力されるアイコンをoverrideできる。

```
<a href="https://www.pinterest.com/pin/create/button/"
 data-pin-do="buttonBookmark"
 data-pin-custom="true" title="Pinterestに保存">ここにカスタムアイコン</a>
```

▼参照ページ
https://developers.pinterest.com/docs/widgets/save/
Rails あいまい検索機能実装

##WHY
私は、LIKE句とWhereメソッドを使った検索機能実装方法を調べていました。。。
のだが、サイトで実際に動かせるレベルの解説はナッシング。多分、自分の応用力が足りないのだと思いますが、今回実装までなんとか漕ぎ着けたので、ここにステップを書き記します！

##STEP
①searchアクションを作り、対応するhtmlにform_tagを追加。
　ここで、極めて大事なことがtext_fieldに値を設定すること（値はparamsに格納される)

②indexアクションにLIKE句とwhereメソッドを用いたコードを書く。(キーワードはtext_fieldで定めた値）
　それをインスタンスメソッドに格納。
③あとは、each文を使うなり部分テンプレートを使うなりして検索結果を一覧表示させる！
【iOS】Universal Links(別アプリから起動)の実装方法とサーバーレスでの実装方法(Firebase Hosting)

どうも、日焼け対策をしておけばよかったと後悔しているiOSエンジニアのkaです。

サーバーを用意せずとも無料でFirebase Hostingを使ってUniversal Linksの実装をできますよということで、自分でやってみてハマりポイントもいくつかあったので紹介します。

#Universal Linksの実装
###Apple Developerサイトでの準備
1. Certificates, Identifiers & Profilesのページを開く
- [Identifiersの一覧ページ](https://developer.apple.com/account/resources/identifiers/list)で設定したいIdentifierを選択
Associated Domainsのチェックを選択してSave
![スクリーンショット 2020-08-25 10.46.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678249/6d34b265-0b1f-0ba2-2d18-eb57d7885233.png)
- provisioning profileが取り消されているので、[Profilesの一覧ページ](https://developer.apple.com/account/resources/profiles/list)で再度選択してEdit
- 再度保存してDownload
- これでAssociated Domainsが有効になったProvisioning Profileが作成できました。

###Xcodeでの実装

1. Projectファイルを開く
1. メニュー → Editor → Add Capability Associated Domainsを選択
1. ドメインを入れる applinks:の後にドメインを入れます httpsの文字列は入りません(例:applinks:sampledomain.co.jp)
![スクリーンショット 2020-08-25 11.02.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678249/347f4557-27f8-fb2b-70a8-710ee42ed7dc.png)

###AppDelegateの実装
外部アプリでドメインをタップしてアプリが起動した際にはAppDelegateでハンドリングされます。
AppDelegateに以下のコードを挿入します。


```AppDelegate.swift
func application(_ application: UIApplication,
                     continue userActivity: NSUserActivity,
                     restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let incomingURL = userActivity.webpageURL,
        let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true) else {
            return false
    }
    return true
}
```


#Firebase Hostingの設定
###apple-app-site-associationファイルの準備
apple-app-site-associationというファイル名で.jsonなどの拡張子は要りません

```apple-app-site-association
{
  "applinks": {
       "apps": [],
        "details": [
           {
               "appID":"{Team ID}.{bundle ID}",
               "paths":[ "*" ]
           }
         ]
    }
}
```
TeamIDはDeveloperAccountサイトで確認できるTeam IDです。
pathsの部分はドメインの全てのpathをアプリに通すという意味のワイルドカードに設定しています。
特定のpathはアプリに遷移させないという設定をすることもこの部分でできます。

###配置
ドメイン/.well-known/apple-app-site-association
でアクセスできる場所に配置します。

ここで注意点ですが、
最初自分が試したのはドメインの直下に
ドメイン/apple-app-site-association
のように配置していたのですが何故かうまくいきませんでした。

apple-app-site-associationはアプリのインストール時にアクセスして取得しにいくのですが
.well-known配下のファイルを優先してアクセスしにいくという仕様があるようで
何とドメイン/.well-known/apple-app-site-associationにアクセスしてみたところ空のapple-app-site-associationが最初から配置されていたのです。
そこで、.well-known配下に配置したところうまくいきました。

###firebase.jsonの設定
firebase.jsonを編集して
apple-app-site-associationのContentTypeをapplication/jsonになるようにします。

以上の実装でメモ帳アプリなどでドメインを書いてタップすればスムーズにアプリ起動ができるはずです。

#補足
- 運用しているアプリでapple-app-site-associationを変更する場合アプリのインストールとアップデート時にしか更新されないので注意が必要
- 同一のドメインから同一のドメインへリンクしているとアプリ起動しない。Safariの場合は上部にアプリを開くボタンがでできてそこからアプリを開くことができる。


公式ドキュメント:
[Universal Links](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html)
[Firebase Hosting](https://firebase.google.com/docs/hosting?hl=ja)

#終わりです

プールや海に遊びにいくときは絶対にラッシュガードを着て遊びましょう！

Brewus,Inc.
株式会社ブリューアス
https://brewus.co.jp
Node.jsでExpress.jsを使ってpng画像を動的に表示するサンプル

画像ファイルを動的に表示するコードです。なかなか見つからなかったのでメモしておきます。

```javascript:express.js

const express = require('express');
const fs = require('fs');

const app = express();

app.get('/image', (req, res) => {
    console.log('image');
    fs.readFile('./example.png', (err, data) => {
      res.type('png');
      res.send(data);
    });
});

app.listen('3000', () => {
    console.log('Application started');
});
```

スクリプトを実行し

```bash
% node express.js
Application started
image
```

ブラウザで下記URLにアクセスすると画像が表示されます
http://localhost:3000/image

![スクリーンショット 2020-08-25 12.40.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32195/35c626b0-9c1a-e061-3f4f-b06254dc82bb.png)

ちなみにディレクトリのファイル一覧はこんな感じです

```bash
% ls
example.png		package-lock.json
express.js		package.json
node_modules
```
ララベルで背景画像を透過させる

###背景画像を透過させる
背景画像を使用していると画像の主張が強くて文字が見えにくいという人もいると思います！
その際に画像を薄くするといった方法を紹介しようと思います！![スクリーンショット 2020-08-25 11.54.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696811/568a788e-6cfa-5bfc-f4bc-c16ef9f77510.png)
こちらはログイン画面です
今は通常の画像となっています
![スクリーンショット 2020-08-25 12.03.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696811/598c0fef-d0f3-5293-df6b-8a8faedc353e.png)
こちらが薄くした画像となります！
この画面では透過させる意味はあまりなさそうですが文字などのコンテンツが多いページでは画像を透過させることで文字などが見やすくなります！
###それではコードの方の紹介をします
```app.blade.php
<body style="background:url({{ asset('images/image02.jpg') }}); background-size:cover; background-color:rgba(255,255,255,0.5);
    background-blend-mode:lighten;">
```
このbackground-color:rgba(255,255,255,0.5);の0.5の数値を調整することで薄さの調整ができるので個人の好みでしてみてください！
background-blend-mode:lighten;も忘れずに書いてください！
###まとめ
今回はララベルで背景画像を透過させる方法について紹介しました！
この書き方がおそらくわかりやすいと思うので、よければ試してみてください！
(エラー）Line X : StartTag: invalid element name

今回は、共同開発をしている時にぶつかったGitHubのmerge後に発生した
エラーの解決法について書いて行きたいと思います。



<img width="400" alt="スクリーンショット 2020-07-09 23.12.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/a573e116-fe98-1410-773e-0880b300ff46.png">

##解決法

<img width="600" alt="スクリーンショット 2020-07-09 23.12.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/46ef9ae0-ffc3-4708-fa9e-e6ec3062020a.png">

**Main.storyboardを左クリック**→**Open As**→　**Source Code**

```swift
<<<<<<< HEAD

========

>>>>>>>>Sub

========

```

**Sub**（Mergeしたブランチ）の内容　or **Master**のどちらかの内容を消してください！
**source code**で表示されていて、どっちのコードを残すかわからない場合は
**GitHub**にいって**Storyboard**の**source code**を見ながら消すのがオススメです。


##以上☀️
最後に、**storyboard**を**sourcecode**のままだと分かりにくいので、
**interface builder**に戻すことを忘れずに。😏✨
SQLServer: ID値をリセットするときに気をつけること

#背景と調査内容
ID値のリセットをプロダクション環境でオンラインで実施することがたまにあるため、挙動について調べてみました。

テーブル作成

```sql
create table t1 (col1 int identity(1,1), col2 int)
```

トランザクションログ確認

```sql
checkpoint
select * from sys.fn_dblog(null, null) --トランザクションログ確認
DBCC CHECKIDENT (t1, RESEED, 100)
select * from sys.fn_dblog(null, null) --トランザクションログ確認
```

ロックの情報から、オブジェクト名を特定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/2dd9a84e-5f55-f0a6-08ba-85148436d9d9.png)

1つはt1テーブルへのSch-Mロックでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/11fa37ef-7f24-82f3-47f9-6ddb8677d0b1.png)

もう一つはsyscolparsという内部のシステムテーブルでした。
[ドキュメント](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-tables/system-base-tables?view=sql-server-ver15)にも掲載されています。

```sql
SELECT 
    sc.name as schema_name, 
    so.name as object_name, 
    si.name as index_name
FROM sys.partitions AS p
JOIN sys.objects as so on 
    p.object_id=so.object_id
JOIN sys.indexes as si on 
    p.index_id=si.index_id and 
    p.object_id=si.object_id
JOIN sys.schemas AS sc on 
    so.schema_id=sc.schema_id
WHERE hobt_id = 281474979397632;
GO
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/20a18992-c7a6-743f-98ad-3ce7c6ae7562.png)

syscolparsの中身を見るためにはDAC接続が必要になります。
DAC接続後に以下のクエリを実行すると、更新したレコードまで特定できます。

```sql
SELECT
    *
FROM sys.syscolpars (NOLOCK)
WHERE %%lockres%% = '(eb60ca9093af)';
GO
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/0c39944e-e503-5b08-538c-b3c8aac9c2ab.png)

ID値が変更されると、syscolparsの該当レコードのidtvalカラムが更新される挙動となっていました。
※idtvalについては[こちらの記事](https://www.linkedin.com/pulse/sql-server-identity-property-internals-dobereiner-miller/)がより詳しいです。

#調査を踏まえて、ID値リセットの際に気をつけること
トランザクションログの中身を見る限り、ロックを取得できてしまえば、レコード数に関係なく瞬時に終わる処理といえます。

ただ、Sch-Mロックを取得する必要があるため、ブロッキングに注意が必要です。
DBCC CHECKIDENTを実行→1秒経過しても終わらなければ中断→再度実行
を繰り返すと良いかと思います。

なかなかSch-Mロックを獲得できない環境下では、[こちらの記事](https://qiita.com/maaaaaaaa/items/4e31220292135f4622d4)で紹介している方法を使うのもありだと思います。
.NET Coreを使用したWPFのRaspberry Piへの移植（失敗）

Windows上で.NET Coreを使用してアプリケーションを開発し、
他OS向けにアプリケーションと依存ファイル一式を発行する方法と、
WPFをRaspberry Pi（Linux）向けにビルドしようとして失敗した内容を記載。

# Raspberry Pi（Linux）向けビルド

Raspberry Pi Model 3+ 上の Ubuntu Server 64 ビットなど、64 ビット ARM で実行されている Linux向けビルドには以下のコマンドを使用します。

    dotnet publish -r linux-arm64

`linux-arm64`以外のランタイム識別子(RID)に関しては以下公式ドキュメント参照。
https://docs.microsoft.com/ja-jp/dotnet/core/rid-catalog

# console、WPFアプリケーションのビルド

consoleアプリケーションを`dotnet new console`で作成し、
`dotnet publish -r linux-arm64`でビルドをかけたところ成功しました。
WPFアプリケーションを`dotnet new wpf`で作成し、
`dotnet publish -r linux-arm64`でビルドをかけたところ失敗しました。
以下、エラー内容
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/6e28be14-87a7-71ce-e183-a8ef28784565.png)

公式ドキュメントにもWPFはWindowsのみ対応と記載されていました。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/ae5fecc1-4564-ac92-407e-c7b6b6be733a.png)

既存のWPFアプリケーションを他OSに移植は厳しいようなのでconsoleアプリケーション等で作り直す必要がありそうです。
Vagrant + VirtualBox 環境で vagrant up が "SSH auth method: private key" でタイムアウトする

|項目	|バージョン|
|:------------:|:------------:|
| Windows       | 10 Pro      |
| Vagrnat       | 2.2.6       |
| VirtualBox    | 6.1.12      |

```
> vagrant up
==> default: VM not created. Moving on...
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos/7'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'centos/7' is up to date...
==> default: Setting the name of the VM: centos7_default_1532083277111_17188
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.

If you look above, you should be able to see the error(s) that
Vagrant had when attempting to connect to the machine. These errors
are usually good hints as to what may be wrong.

If you're using a custom box, make sure that networking is properly
working and you're able to connect to the machine. It is a common
problem that networking isn't setup properly in these boxes.
Verify that authentication configurations are also setup properly,
as well.

If the box appears to be booting properly, you may want to increase
the timeout ("config.vm.boot_timeout") value.
```

|項目	|バージョン|
|:------------:|:------------:|
| Windows       | 10 Pro      |
| Vagrnat       | 2.2.6       |
| VirtualBox    | 6.1.12 → 6.0.24 |

`VirtualBox` 過去バージョンで入れなおしたら起動した！
二次元配列をforeachで参照渡ししたい

# やりたいこと
以下のような二次元配列の一部を更新したい。

```
$tests = [['values'=>[1,2]],['values'=>[3,4]]];
```

# 環境(今回の作業に関連ないものも記載)
* MacBookPro(macOSCatalina10.15.5)
* PHP7.4
* PHPStorm2020.2
* docker desktop2.2.0.3
* cakephp4.1.2
* xdebug2.9.6

# 実装
## まずは基本の参照渡し

foreachで利用する変数に`&`を付与する。

```test1.php
$tests = [1,2,3,4];
foreach ($tests as &$test) {
    if($test === 3) {
        $test = 5;
    }
}
$test = 6;
var_dump($tests);

/* 
array (size=4)
  0 => int 1
  1 => int 2
  2 => int 5
  3 => int 6←おかしい
*/
```

上記だと$testへのポインタが残ったままなので、foreachを出た後に同じ変数名を利用すると、配列のデータが更新されてしまう。
以下のようにunsetする必要があることに注意。

```test2.php
$tests = [1,2,3,4];
foreach ($tests as &$test) {
    if($test === 3) {
        $test = 5;
    }
}
unset($test);
$test = 6;
var_dump($tests);

/* 
array (size=4)
  0 => int 1
  1 => int 2
  2 => int 5
  3 => int 4←正しい
*/
```

どんな仕様だよと思わなくもない。

## 二次元配列の参照渡し

foreachを二重で回す。
２つ目のforeachにだけ`&`をつけてもうまくいかない。

```test.php
$tests = [['values'=>[1,2]],['values'=>[3,4]]];
foreach ($tests as $test) {
    foreach ($test['values'] as &$value) {
        if($value === 2){
            $value = 5;
        }
    }
    unset($value);
}
var_dump($tests);

/* 
array (size=2)
  0 => 
    array (size=1)
      'values' => 
        array (size=2)
          0 => int 1
          1 => int 2←おかしい
  1 => 
    array (size=1)
      'values' => 
        array (size=2)
          0 => int 3
          1 => int 4
*/
```

両方に`&`をつけるとうまくいく。

```test4.php
$tests = [['values'=>[1,2]],['values'=>[3,4]]];
foreach ($tests as &$test) {
    foreach ($test['values'] as &$value) {
        if($value === 2){
            $value = 5;
        }
    }
    unset($value);
}
unset($test);

/*
array (size=2)
  0 => 
    array (size=1)
      'values' => 
        array (size=2)
          0 => int 1
          1 => int 5←正しい
  1 => 
    array (size=1)
      'values' => 
        array (size=2)
          0 => int 3
          1 => int 4
*/
```
IPhoneのホームボタンによりSiri起動停止する方法

IPhoneのホームボタンを押下することにより起動されるApple社のヴォイスアシスタンスのSiriを
簡単に停止することが可能です。Siriの起動を停止したい場合、下記の手順を参照してください。

変更手順：

① 設定アイコンを開く

![01_TR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697349/b08cc050-08fe-6f20-4a8c-1242bfe09ed1.png)

② 設定の項目一覧にある「アクセシビリティ」を開く

![02_TR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697349/96f086f1-4cbb-7f3b-4cc5-c626518e843e.png)

③ アクセシビリティの項目一覧にある「身体および動作」項目内にある「ホームボタン」を開く

![04TR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697349/969f6bd6-6866-a2a5-5b45-f1244fd3479f.png)

④ ホームボタンの項目一覧にある「押したままにして話す」を「Siri」から「オフ」に選択

![03_TR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697349/db9eb4df-a1bc-05f2-ed4c-7b05e0793b31.png)
     
⑤ 完了
非推奨であるwmicコマンドの代替を探す(Get-WmiObject)

# （追記）wmicの廃止スケジュールが発表されています
[WMI command line (WMIC) utility deprecation: Next steps](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/wmi-command-line-wmic-utility-deprecation-next-steps/ba-p/4039242)
[窓の杜 WMIコマンドの廃止スケジュールが発表 ～次期Windowsで「デフォルト無効」](https://forest.watch.impress.co.jp/docs/news/1564283.html)

# wmicは非推奨です

`wmic`は、Windowsのいろんな情報を引けるWMI（Windows Management Instrumentation）を扱うコマンド。
いまこれのヘルプを引くと「非推奨です」と表示される。

```console:cmd
>wmic /?

WMIC は非推奨です。
```

[公式ドキュメント](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/wmic)には記述が見当たらないが、情報によると2012年Windows8から非推奨扱いになったんだそうで。いまも実際に非推奨と表示される以上非推奨なんだろう…

変わりなく動くのでそのまま使っているものの、非推奨だよと明記されてるものをいつまでも使い続けるのは気分が悪い。
代替か後継があるんだろうな～ってことで、PowerShellコマンドレットを探す。

# 引きたい情報の具体例

主にプリンタ情報を取得するのに使っていたので、それを例にする。
下のように一覧表示して目星をつけて、ポート疎通確認したりステータス調べたりする。

```console:cmd
# プリンタ情報を取得する
# 実際はnodeを取得したい先のホスト名にする
wmic /node:"localhost" printer get Name,Default,Status,PortName
```

```console:出力
Default  Name                    PortName     Status
FALSE    Microsoft Print to PDF  PORTPROMPT:  Unknown
FALSE    Fax                     SHRFAX:      Unknown
TRUE     DocumentPrinter         192.0.2.71   Unknown
```

# Get-WmiObjectコマンドレット

[Get-WmiObject](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-wmiobject?view=powershell-5.1)
`Get-WmiObject`という、いかにもWMI取り扱いですよという名前のコマンドレットがある。これで`Win32_Printer`クラスを呼んでやれば求める結果が返ってくる。パラメータ指定もおおむね似通った感じで書けて、結果も似たようなものになる。
出力をどうこうしたい場合もPowerShellのほうが扱いやすい。

```powershell:PowerShell
Get-WmiObject -Class Win32_Printer -ComputerName "localhost" | select Default,Name,Portname,Status
```

```powershell:出力
Default Name                   Portname       Status
------- ----                   --------       ------
  False Microsoft Print to PDF PORTPROMPT:    Unknown
  False Fax                    SHRFAX:        Unknown
   True DocumentPrinter        192.0.2.71     Unknown
```

代替としてはこれでいいだろう。
他に得たいプロパティがあれば、`select *`で表示して必要なものを探すこと。86個も出てきてそんなにいらねえよってなった。


## Computer System Hardware Classes

`Get-WmiObject`を使って、他にも様々な情報を読み出せる。
多すぎて一覧は無理なので、欲しいものがあったら公式で探すといい。
[Computer System Hardware Classes](https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes)


# Get-Printerコマンドレット？

[Get-Printer](https://docs.microsoft.com/en-us/powershell/module/printmanagement/get-printer?view=win10-ps)
Get-Printerという、これまたいかにもプリンタ取り扱いですよという名前のコマンドレットもある。
こちらは得られる情報の種類が異なっている。例えば`Default`プロパティと`Status`プロパティは同じ名前では存在しないようで、出てこない。
`ComputerName`パラメータをlocalhostにすると返事がやたら遅かったり、なんか挙動不審。(hostnameを明記すれば早い)

```powershell
Get-Printer -ComputerName "hostname" | select Default,Name,Portname,Status
```

```powershell:出力
Default Name                   Portname       Status
------- ----                   --------       ------
        Microsoft Print to PDF PORTPROMPT:
        Fax                    SHRFAX:
        DocumentPrinter        192.0.2.71
```

`select *`で調べてみると`Get-WmiObject Win32_Printer`とはだいぶ違うプロパティを持っている。`CimInstanceProperties`プロパティの中にあれこれ情報が埋まっているようだ。(例示は省略)
こちらは`wmic`の代替の意味では扱いづらい。もっと別な使い方のために用意されたコマンドレットなんだろう。たぶん。
[Gitlab]issue〜マジリクまでの流れMEMO

# 流れ
1. 着手するissueの「Assignee」に自分を追加

2. issueにある「Create merge request」となっている緑枠のプルダウン(▼)を開いて、「Create branch」に変更、「Branch name(※半角英数字)」を設定、「Source」はmasterのまま、終わったら「Create branch」の緑ボタンを押してブランチを作成する。
 ※issueのページの下の方にある「Related Branch」に作成したブランチがあればOK

3. 仮想環境にssh接続しているターミナルで以下を実行してローカルにブランチを作成して確認する。

```ruby

$ git remote update

$ git checkout [作成したブランチ名]
# ブランチを間違えた場合は git branch -D [削除したいブランチ名]で削除

$ git status
# ブランチ名が作成したブランチ名になっていればOK
```

4.issueの「Labels」の「ToDo」を「Doing」に変更し、issueの内容に沿って追加や修正を行う

5.サーバーを起動して動作確認をしていない場合は確認する。
※ Macで適当なブラウザを開いて`http://[ubuntuのipアドレス]:3000`で接続できる

```

$ bundle exec rails s -b 0.0.0.0
```

6.rspecのテストを実行して問題があれば修正する。

```

$ bundle exec rspec rspecのファイルパス
```

7.rubocopを実行して問題があれば修正する。

```

$ bundle exec rubocop
```

8.rspecの全テスト実行をして問題があれば修正する。

```

$ bundle exec rake spec
```

9.git statusを実行して変なファイルが追加されていたり、変更した記憶のないファイルに変更が入っていないか確認する。

```

$ git status
```

10.以下を実行して変更に問題がないか再度確認する

```ruby

$ git add .

$ git diff --cached
# 既存ファイルを変更してaddする前ならgit diffで変更が確認できる
```

11.問題がなければ以下を実行して変更をコミット、プッシュ

```

$ git commit -m "[コミットメッセージ(日本語可)]"

$ git push origin [作成したブランチ名]
```

12.issueのページに戻って下の方にある「Related Branch」の作成したブランチをクリック
遷移先のページで「Source」が作成したブランチ、「Target」がmasterになっていることを確認して、「Create merge request」をクリック

13.「Assignee」にマージを実行してもらう相手(担当者)を設定する。
「Milestone・Labels」はそのままでOK。「Source branch・Target branch」が合っていることを確認したら「Submit merge request」をクリック

14.slackで担当者にマージリクエストのURLを付けて確認をお願いをする。

15.担当者が確認して修正事項がなければ担当者がマージを実行する。
※修正事項があれば、その部分を修正して5~11の流れを行い、マージリクエストのページで「Commits」のタブに修正したコミットが入っていることを確認して、担当者に修正したこととその確認をお願いする。
[Linux]よく使うLinuxコマンド(ファイル操作編)

###ファイルへの書き込み
「>」の結果を右側にあるファイルに出力します。
ファイルがない場合は、新規に作成されます。

```
$ echo 'Hello World' > ./aaa.txt
```

###ファイルをコピー

```
$ cp aaa.txt aaa1.txt
```

###ファイルを削除

```
$ rm aaa.txt
```

###ファイルの内容確認

```
$ cat aaa1.txt
```

実行結果、、、

```
Hello World
```

###ファイルやディレクトリを検索
sudoを使うのは、管理者権限がないと閲覧不可なファイルなどがあることがあるからです。

```
$ sudo find aaa1.txt
```

実行結果、、、

```
aaa1.txt
```

###文字列を検索
「control + f」で検索することがあると思いますが、それと同じようなものです。

```
$ grep He aaa1.txt
```

実行結果、、、

```
Hello World
```
色々な言語でファイルIOを競って速度比較

複数のプログラミング言語で約 1GB の CSV ファイルを Read/Write して時間を測定してみました！

# 共通ルール

- どの言語でも同じファイルを使用して確認すること
- ファイルは一行ずつ読み散り、一行ずつ書き込むこと
- OSの差を無くすため、Docker Image は全て base(Ubuntu 18.04 LTS)を使用すること

# まずは結果

|言語|5回実行した平均タイム(秒)|
|:--|:--|
|C-lang|6.2962|
|C++|6.0538|
|C#|17.1798|
|Golang|10.3966|
|Java|21.0840|
|Python|32.6949|
|Ruby|30.7153|
|Scala|21.8364|

やっぱりC/C++がダントツで早い！！
次点でGo言語

# 実装サンプル

5年ぶりくらいにC++書いたので綺麗ではないと思いますが、一番早かったのでサンプルとして載せます。

他の言語でも以下の動作をベースとして実装しました。

- 5回実行した平均時間を計算
- 1行読んで１行書き込む

```c
#include <iostream>
#include <fstream>
#include <time.h>
#include <iomanip>

using namespace std;

int main(int argc, char *argv[])
{
    cout << "START!!!" << endl;
    clock_t start, end;
    double time, sum = 0;
    int count = 5;

    for (int i = 0; i < count; i++)
    {
        start = clock();

        ifstream ifs("/fixtures/sample.csv");
        ofstream ofs("./sample.csv");

        const int SIZE = 1024;
        char buffer[SIZE];

        while (ifs.getline(buffer, SIZE))
        {
            // ofs << buffer << endl; だとめっちゃ遅い
            ofs << buffer << "\n";
        }

        end = clock();
        time = (double)(end - start) / CLOCKS_PER_SEC;
        cout << "Time Result: ";
        cout << fixed << setprecision(4) << time << endl;
        sum += time;
    }

    cout << "C++ Average: ";
    cout << fixed << setprecision(4) << sum / count << endl;

    return 0;
}
```

ソース内のコメントに記載しましたが、C++では `ofs << buffer << endl;` で書き込むと速度が著しく低下する問題が発生したため、自分で改行コードを追記しています。

# 所感

結果としては予想通りで、C/C++がダントツでした。
RubyやPythonはスクリプト言語なので遅いかな〜と思いましたがやはり遅かったです。(私の書き方の問題かもですが)
Go言語も早かったので仕事で使ったことが無いのですがとても興味が湧きました！

# その他

本当はRustも作りたかったのですが知識不足で途中まで実装して挫折したので今回は対象外としました。
Rustラブな方からのPRいつでもお待ちしております！

また、私の実装よりもより早くできて今回の順位と異なる結果となる書き方がありましたらPRお待ちしております！
(基本コンセプトはそのままだとありがたいです)

# 今回作成したリポジトリ

https://github.com/MasanoriIwakura/multi-lang-battle
CGMにパワポがコピペされた時にフォントサイズ指定を無効化するCSS

CGM開発に関わるフロントエンジニアは、勝手気ままにWordやパワポをコピペしてフロントコードが荒らされることに辟易してる方も多いと思います。私もです。

システムやエディタ側で余分なHTMLを除去すべきととは思いますが、そこはコストと優先度の話。最低限のコストでしれっと改修できる、CSSのみで対応する方法のメモです。

## CSS

```css
span {
  font-size: inherit !important;
}
```

これだけ。
全体に及ぶと問題あるなら以下のように出力コンテンツ枠を対象にしても良いでしょう。

```css
.output span {
  font-size: inherit !important;
}
```

パワポはspanタグにfont-sizeを埋め込んでくるので、これで一括してベースのフォントサイズに調整できます。

色も適当に設定されるのを避けるなら、以下のようにしても良いでしょう。

```css
span {
  font-size: inherit !important;
  color: inherit !important;
}
```

表示だけはこれで対応できますが、WordやパワポのコピペはHTMLに汚いインラインCSSが残りまくるので、本質的にはそれを除去したいですね…
Chrome拡張だけでIP偽装する方法

![image.png](https://img.shields.io/badge/Chrome-2084.0.4147.135-%3CCOLOR%3E)

# こんなことありませんか？

リモートワーク中心になった会社も多いと思いますが、
そんな時に困るのがIPの問題です。

いつものように匿名で内部告発しようと思ったものの、GIPから住所を特定されて
窓から石を投げられたら大変です。

５ちゃんのアイドルスレに過激な書き込みをしているのがバレたり、
うっかり如何わしいサイトを踏んでIP控えられたりしてしまうなど
オフィス勤務に比べて自宅のルーターで仕事をするのはたくさんリスクがあります。

そんな時こそ活用したい
Chrome拡張を使ったIPの偽装方法を簡単に紹介します。

# Chrome拡張を入れる 

やり方は簡単、Chromeに拡張を入れるだけ！！
いくつかツールはありますが、今回は**HotSheild**というChrome拡張を使用します。

[Hotspot Shield Free VPN Proxy](https://chrome.google.com/webstore/detail/hotspot-shield-free-vpn-p/nlbejmccbhkncgokjcmghpfloaajcffj?hl=ja)

ちなみに、アプリ版もあります。
ブラウザ以外で利用する場合はこちらを使えばできそうな気がしますが
今回はブラウザアクセスでのみ使えればいいので対象外とします。

有効化するとこんな感じのアイコンが出現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454065/9d38c2d5-dc57-7c9b-0295-db73bc0334f0.png)

さあもうIP偽装したくてウズウズしていますね？

早速IPを偽りましょう

# ボタン一つでIP偽装

さて、早速IPを偽装していきましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454065/62917e50-6f9c-7050-af66-78686a441d97.png)

真ん中の押したそうにされているボタンを押すだけでVPNに接続され、IPが変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454065/da44776a-9938-0aaa-148c-e336707c1fcf.png)

起動中の画面。
速度まで測ってくれます。わあ親切!

ここでGIPを確認すると、自宅のルーターとは違った値になってるはずです。

さあこれでもう、やりたい放題
怯える夜にさよならを告げましょう！

# [おまけ]偽装場所を選ぼう

ちなみに 偽装先の国は選択可能です。
デフォルトで `Auto server` となっていますがこちらはランダムで選択される模様

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454065/15993e88-32a4-c037-9cb0-66551cc3c119.png)

鍵アイコンになっているところは有料版でしか使えないようです。
偽装界隈では人気の国々なんでしょうか

ちょうどビールが飲みたかったので試しに `Germany` を選択してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454065/5f6c4ca2-5039-391d-9b32-aa415b0c01c2.png)

はい！！！変わりました。

続いて `Canada` を選択してみましょう！！
パンケーキだけでなく、しょっぱいものでもなににでもメープルシロップをかけるんだとか。
甘じょっぱ好きの自分からしたら魅力的ですね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454065/1769ae4b-f797-b6a7-6927-991efa6c1983.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454065/2c78e61a-6e7b-26c7-ecdb-abdaa4a48558.png)

はい！！！変わりました。

ちなみに、再起動は必要ありません。


# 最後に

悪用厳禁 + 当然ですが自己責任で使用をお願いします。

マジレスするとIPホワイトリストの確認とか、いちいち4Gに切り替えなくてもできるので
そういう場合に便利だと思います。

何か参考になれば幸いです。

ちなみに、どんなにIP偽装を頑張っても**バレる時はバレます**
vistaでquartus その33

#概要

vistaでquartusやってみた。
cpu作ってみた。
シミュレータで実行。
アセンブラでコンパイル。
実機で実行。

#ソース

1-99を表示。

```
  push  1
  set  i
loop:
  get  i
  push  99
  >
pass:
  jz  pass 
  push  32
  out
  get  i
  push  10
  /
  push  48
  +
  out
  get  i
  push  10
  %
  push  48
  +
  out
  get  i
  push  1
  +
  set  i
  jmp loop
i:
  end

```

#シミュレータで実行。

https://embed.plnkr.co/plunk/xMps5G0CxyEOiA1q

#アセンブラでコンパイル。

https://embed.plnkr.co/plunk/c2GuFjSf1Othg3Zi

#実機で実行。

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/689cdf0a-362d-511d-114d-4b5ecf6a39ba.jpeg)


以上。
rails db:migrateが失敗！

##rails db:migrateを実行した際のエラー

`rails db:migrate`を実行すると
以下のエラーが出ました！

```
StandardError: An error has occurred, all later migrations canceled:
```
直訳すると以後の全てのマイグレーションでエラーが発生しキャンセルされましたという内容です。



更に、こんなエラーも出ています。

```
Mysql2::Error: Specified key was too long; max key length is 767 bytes
```
こちらのエラーは指定したキーが長すぎるためエラーが発生しているようです。
maxのkeyの長さは767bytesのようです。


##今回のエラーの仮説
keyの長さがmax767バイトなのに対し、keyが長すぎたためエラーが発生しているようです。

railsでデフォルトで生成される255文字のVARCHER型の場合、

◎**utf8mb4は1文字4バイト**、
255×4バイト= 1020バイト
　
767バイトを超えてしまうためエラーが発生してしまいます。

##解決法
文字コードの指定を**utf8**に変える

◎utf8は1文字3バイト、
255×3バイト= 765バイト

ほぼぴったり収まるためこれで解決できます！

```ruby:database.yml

   default: &default
   encoding: utf8
   
```
`bundle install`をし、`rails s`で再起動をします！

その後、

```
$ rails db:migrate:reset

```
これで無事にマイグレーションされました！
PHP学習メモ<MVCの書き方>



.blade.php

テンプレートエンジン
{{ 変数名 }}画面への出力

@if
@ifelse
@ifend

### route

return view('archives.index');
# 「/」ではなく「.」でアーカイブを区切る


▼参考動画
https://www.youtube.com/watch?v=M7ZV0GKm4lI&list=PLh6V6_7fbbo8bb7eajaLdsQZ9fLhMJ-oc&index=1
mecab, neologd-ipadicのcolab上での使用方法

## はじめに  
ipadic-neologdとは、
![mecab-ipadic-NEologd : Neologism dictionary for MeCab](https://github.com/neologd/mecab-ipadic-neologd)
mecab用の辞書の一つ。週2回以上更新してくださるので、新語や固有表現に対応ができる。
## 例　　
```python

#ipadic-neologd未使用
m=MeCab.Tagger()
print(m.parse("COVID-19によりオーバーシュートが起こった。"))
>COVID	COVID	COVID	名詞-固有名詞-組織		
 -	-	-	名詞-サ変接続		
 19	19	19	名詞-数		
 により	ニヨリ	により	助詞-格助詞-連語		
 オーバー	オーバー	オーバー	名詞-サ変接続		
 シュート	シュート	シュート	名詞-サ変接続		
 が	ガ	が	助詞-格助詞-一般		
 起こっ	オコッ	起こる	動詞-自立	五段・ラ行	連用タ接続
 た	タ	た	助動詞	特殊・タ	基本形
 。	。	。	記号-句点		
 EOS
```

```python

#ipadic-neologd使用
m=MeCab.Tagger("-d {辞書のパス}")
print(m.parse("COVID-19によりオーバーシュートが起こった。"))
>COVID-19	名詞,固有名詞,一般,*,*,*,COVID-19,コビッドナインティーン,コビッドナインティーン
 により	助詞,格助詞,連語,*,*,*,により,ニヨリ,ニヨリ
 オーバーシュート	名詞,固有名詞,一般,*,*,*,オーバーシュート,オーバーシュート,オーバーシュート
 が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
 起こっ	動詞,自立,*,*,五段・ラ行,連用タ接続,起こる,オコッ,オコッ
 た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
 。	記号,句点,*,*,*,*,。,。,。
 EOS
```  

## Colabへのインストール方法
以下の記事が非常にわかりやすかったです。
![mecab ipadic-NEologd を Google Colaboratory で使う](https://qiita.com/Fulltea/items/90f6ebe6dcceaf64eaef)
エラーが出る場合、以下を追加すると上手くいきました。
```!sudo cp /etc/mecabrc /usr/local/etc/```  

## 使用方法
```python

import MeCab
m=MeCab.Tagger("{出力形式(以下を参照)} -d {ipadic-neologdのパス}")
print(m.parse("ソーシャルディスタンスを保とう"))
```  
## 出力形式
### 1. mecabrc: 引数なし  
```python

ソーシャルディスタンス	名詞,固有名詞,一般,*,*,*,ソーシャルディスタンス,ソーシャルディスタンス,ソーシャルディスタンス
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
保と	動詞,自立,*,*,五段・タ行,未然ウ接続,保つ,タモト,タモト
う	助動詞,*,*,*,不変化型,基本形,う,ウ,ウ
EOS
```
表層形 : 形態素に区切ったまま
品詞 : 名詞、動詞、助詞、助動詞 etc
品詞細分類1 : 名詞→固有名詞、動詞→自立、助詞→格助詞
品詞細分類2 : 一般、引用
品詞細分類3 : 
活用型 : 動詞→五段・タ行
活用形 : 未然ウ接続
原形.読み,発音 : 

### 2. -Ochasen: ChaSen 互換形式  
```python

ソーシャルディスタンス	ソーシャルディスタンス	ソーシャルディスタンス	名詞-固有名詞-一般
を	ヲ	を	助詞-格助詞-一般
保と	タモト	保つ	動詞-自立	五段・タ行	未然ウ接続
う	ウ	う	助動詞	不変化型	基本形
EOS
```  
### 3. -Owakati: 分かち書きのみ  
```python

ソーシャルディスタンス を 保と う 
```  
### 4. -Oyomi: 読みのみ
```python
ソーシャルディスタンスヲタモトウ
```
### 5. -Odump: 全情報を出力  
```python
0 BOS BOS/EOS,*,*,*,*,*,*,*,* 0 0 0 0 0 0 2 1 0.000000 0.000000 0.000000 0
6 ソーシャルディスタンス 名詞,固有名詞,一般,*,*,*,ソーシャルディスタンス,ソーシャルディスタンス,ソーシャルディスタンス 0 33 1288 1288 41 7 0 1 0.000000 0.000000 0.000000 -1987
213 を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 33 36 156 156 13 6 0 1 0.000000 0.000000 0.000000 -1613
218 保と 動詞,自立,*,*,五段・タ行,未然ウ接続,保つ,タモト,タモト 36 42 739 739 31 2 0 1 0.000000 0.000000 0.000000 3067
234 う 助動詞,*,*,*,不変化型,基本形,う,ウ,ウ 42 45 506 506 25 6 0 1 0.000000 0.000000 0.000000 3215
236 EOS BOS/EOS,*,*,*,*,*,*,*,* 45 45 0 0 0 0 3 1 0.000000 0.000000 0.000000 1300```
Nuxt.js(1)インストール

今日はNuxt.jsのインストールにつてを記録します。事前にnode.jsをインストールしました。Nuxt.jsの公式サイトを参考して、そして新しいnuxtプロジェクトを作成しましょう。

```terminal
$:create-nuxt-app my-first-nuxt-project
```
以下の情報を現します、プロジェクトを確認しましょう。
![螢幕快照 2020-08-25 10.23.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/803b3901-3d85-d3df-fdec-9fdb0d52910b.png)

次ましてはプロジェクトについての説明。
![螢幕快照 2020-08-25 10.26.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/c8850fec-c97c-4796-99d5-1df4df1a8132.png)

そしては開発者名。
![螢幕快照 2020-08-25 10.27.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/a8b67d7a-0488-d639-cf0d-1cd9f59673e2.png)
更に開発言語を選びましょう。ここはJavaScriptを選びました。
![螢幕快照 2020-08-25 10.28.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/313bbeab-ff19-5d7e-d3ab-eb3629b8d992.png)
自分慣れるのパッケージをパッケージ。ここはYarnを選びました。後は様々なUI項目を表す、今回は一応見逃します。
![螢幕快照 2020-08-25 10.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/1f345741-d95e-0627-e59b-93916858123c.png)
サーバーについては今回もいりません。
![螢幕快照 2020-08-25 10.35.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/9e732c68-075e-cfce-4d4c-ea1eb707f765.png)
更にmodulesも選べますが、公式サイト説明下に追記します。ここはDotEnvを選びました。
![螢幕快照 2020-08-25 10.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/708bb507-f924-f83f-91b9-54974bd0a71c.png)
![螢幕快照 2020-08-25 10.36.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/d1362b68-c116-7823-9256-694412cb13e8.png)

継ぎましてはJS書き方検察機能。ここはESLintを決めました。
![螢幕快照 2020-08-25 10.47.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/12ad092d-5dea-ca1c-8c91-c0d8cb472615.png)
テストは一応見逃しました。
![螢幕快照 2020-08-25 10.50.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/459a1fb5-37d1-01d6-578c-9ab5db3fdf96.png)
ここはサーバーレンタは要りません。SPAを選びました。
![螢幕快照 2020-08-25 10.51.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/1694ca7f-3f27-d439-6db6-4d56062fd2c0.png)
開発ツールはvscodeなので、jsconfigを選びました。
![螢幕快照 2020-08-25 10.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/b4b49bb7-8a20-c403-d7e2-ddcb2f6a9309.png)
インストール成功しました。
![螢幕快照 2020-08-25 10.58.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475097/356a6060-ae9b-2399-8a7f-2d4569c07e72.png)
TypeScript 個人的によく使う型関連の機能まとめ

## TypeScript、面白いけど新しく覚えることが多い！  せや、まとめよう！ :fist:

というわけで忘備録 兼 理解したことをまとめている記事です。
どなたかのお力になれば幸いです。

## interfaceって？

型の情報だけを持ついわゆる構造体。
意図しているtypeを含んだ構造体を使って、その値にどんな型が含まれるべきかを制御できます。
declareを使って書くこともできる。

```typescript

/*
* item.createdDateを返します。
*/
function convertItem (item) {
  return item.createdDate;
}

// このままだと itemにcreatedDateが含まれていない場合でも使用できてしまったり、
// createdDateがどんな形式なのかわからないのであとあと困ることに繋がる。

// これをTypeScriptで置き換えると
// 以下のように型定義を使って、引数に入る値を制御することができ、返却値も明示的にでき、可読性やバグ認知度があがる
// 以下の場合だと、引数に Itemのオブジェクトが期待されているので、他の型の値は使えない。
// 返却値も string型であると明示されているのでこの処理の結果も分かりやすくなっている。

// 引数Itemの型定義
interface Item {
  id: number,
  createdDate: string,
}

/*
* item.createdDateを返します。
*/ 
convertItem (item: Item): string {
  return item.createdDate;
}

```

## Type Assertion（型アサーション)

TypeScript では型付けを行い、引数や返却値の型を明示的にすることができます。
特に、JavascriptからTypeScriptへ移行していく際に、適宜 型Assertionを行い
どういった値が引数に使えるのか、その処理の結果どういった値が返却されるのかなどを
を明示的にすることが多いです。
(具体的には 頑張ってtypeofなどを使って型判定している部分をTypeScriptで置き換えて分かりやすくする)


```typescript
// UpdateRequestの型定義
interface UpdateRequest {
  id: number,
  name: string,
}

const hoge = {} as UpdateRequest;

hoge.id = 1 // => OK
hoge.name = "MyName" // => OK

hoge.id = "1" // => エラー
hoge.name = １２３ // => エラー


// こっちの書き方もできる
const AnotherRequest = {
  id: 2,
  name: "SecondName"
} as UpdateRequest;

// あとからプロパティ追加もできない
AnotherRequest.updateFlag = true; // エラー

```

#### type assertion 注意点

type assertionは便利ですが、悪用することも可能です。 
`as any` を使うことで any型として判定させることができ、コンパイルエラーを回避することができます。
ただし、typescriptの型付けの恩恵を受けられなくなるといったデメリットがあります。
ちなみにそういったコンパイルエラーの場合、だいたいどこかで型が意図せず変換されてしまっているか、どこかで何かを間違えているかなので、まずは自分のコードを疑ったほうがよいかも知れませんね :thermometer_face: 

```typescript

interface UpdateRequest {
  id: number,
  name: string,
}

// 
const badRequest = {
  id: 2,
  name: "SecondName"
} as UpdateRequest;

// あとからプロパティ追加できない
badRequest.updateFlag = true; // エラー

const copiedRequest = badRequest as any;

// これなら入ってしまう。 型付けの恩恵を受けられなくなるデメリット
copiedRequest.updateFlag = true; // OK

```


### intersection

あるインターフェースと別のインターフェースを合体させて作る簡易的な interfaceです。
すでに存在しているinterfaceを組み合わせてinterfaceを作れるので、とても便利で取り回しが良いです。

```typescript

interface FavaoriteFood {
  sushi: Sushi;
}

interface FavoriteDrink {
  drink: GreenTea;
}

type FavoriteLunch = FavaoriteFood & FavoriteDrink;
// 以下と同じ扱い
// interface FavoriteLunch {
//   sushi: Sushi;
//   drink: GreenTea;
// }

// 以下のように interface内でも使える
interface Sushi {
 sumeshi: Vinegar & Rice,
 neta: Fish | Shellfish,
}
```


### 所感

まだまだ TypeScriptに触り始めたばかりなので、他の機能もどんどん試していってここに追記していきたいと思います :relaxed:
Type関連だけでもいろんなテクニックやどんどん追加される機能があるので理解したら随時更新します。

##### 参考

* https://typescript-jp.gitbook.io/deep-dive/type-system/type-assertion
* https://qiita.com/markey/items/134386ee98b277f181f7 
    *  (intersectionの名前を知らなくてググったときに教えていただいた記事です。)
* https://future-architect.github.io/typescript-guide/index.html
RSpecでCSVの値をチェックする

今参画しているプロジェクトでCSVのRSpecは

```Ruby
expect(csv).to have_content('value')
```
のような形で書いていたのですが行毎の値を確認する必要が出てきたのでいろいろ調べていたんですが地味に検索で出てこなかったのでメモ。

以下のようなcsvを想定

|column_0  |column_1  |
|---|---|
|value_1  |value_2  |
|value_3  |value_4  |

```Ruby
it 'example' do
  csv_content = Sample.csv_content
  csv = CSV.parse(csv_content)
  # [行番号][列番号]
  expect(csv[0][0]).to eq 'value_1'
  expect(csv[0][1]).to eq 'value_2'
  expect(csv[1][0]).to eq 'value_3'
  expect(csv[1][1]).to eq 'value_4'

  # 行毎に比較もできる
  expect(csv[0]).to eq ['value_1', 'value_2']
  expect(csv[1]).to eq ['value_3', 'value_4']
end
```

これでテストが捗ります。

# 追記
コメントで`CSV.table`なるものを教えて頂きました！

```Ruby
it 'example' do
  csv_content_path = Sample.csv_content.path
  table = CSV.table(csv_content_path) # Pathを渡す
  table.headers # => [:column_0, :column_1]

  # [ヘッダー名][行番号]
  expect(table[:column_0][0]).to eq 'value_1'
  expect(table[:column_0][1]).to eq 'value_2'
  expect(table[:column_1][0]).to eq 'value_3'
  expect(table[:column_1][1]).to eq 'value_4'

  # 行毎の取得
  expect(table[0]).to eq ['value_1', 'value_2']
  expect(table[1]).to eq ['value_3', 'value_4']

  # 列毎の取得
  expect(table[:column_0]).to eq ['value_1', 'value_3']
  expect(table[:column_1]).to eq ['value_2', 'value_4']
end
```

実装中ならこっちの方が使いやすいかもですね。
列毎にまとめて取得できるのもかなり使い所ありそうです。

ただ、CSV.tableはファイルのPathを渡す必要があるのでそこだけ注意ですね。

---
参考リンク
https://qiita.com/gotchane/items/e615fed15901aed6c18a
https://melborne.github.io/2013/01/24/csv-table-method-is-awesome/
https://docs.ruby-lang.org/ja/latest/class/CSV=3a=3aTable.html
executeでfatal errorが発生。原因はbindValueの引数だった(PHP)

#executeでfatal errorが発生。原因はbindValueだった


【エラーが出たコード】

```php

$name = John;
$id = 1;

$sql = SELECT * FROM bbs WHERE name? OR id=?
$statement = prepare($sql);
$statement->bindValue(1, $name);
$statement->bindValue(2, $id);
$statement->execute();
```

```
fatal error:C in...
```
みたいなエラーが出て原因がさっぱりわからない！
少し勉強をしたことのある方でしたらパッと見てここが原因だなとお分かりになるかもしれませんが、
私は気付くのに何時間もかかってしまいました。


**答えはbindValueの第三引数！**

bindValueはの第三引数は入力しないと**初期値でSTR型が設定される**ことになっています。
そこに数値型を入力していたためエラーが出ていました。

bindValueを使用するときは面倒でも

```php
$statement->bindValue(1, $name, PDO::PARAM_STR);//STR型
$statement->bindValue(2, $id, PDO::PARAM_INT);//INT型
```
のように第三引数を指定してあげるとこのようなミスは防げますね。
プログラミング初心者で詰まった方の参考になると嬉しいです。

#参考
[PHP公式ドキュメント] https://www.php.net/manual/ja/pdostatement.bindvalue.php
Unity2020でVuforiaをインストールする

# Unity2020でVuforiaをインストールする

Unity2020以降、PackageManagerのUnity Technologyの公式パッケージからVuforiaは無くなりました。
今後VuforiaはAsset StoreもしくはPTCから入手することになります。

# インストール前の注意
Vuforiaのインストール時に本体のプロジェクト設定をかなり広い範囲で上書きしてきます。
よく目立つ範囲では下記の項目があります。

- アイコン
- パッケージ名
- バージョン
- バンドルバージョン

アイコンについてはCommonフォルダのインポートを避けることで上書きを避けられます。
それ以外はプロジェクトセッティングのフォルダのインポートを避けることで上書きを避けられますが、
最初の1回目は設定が必要なので、上書きを受容する必要があります。

Unityのアップデートか何かでVuforiaの再インポートが必要になった場合は既に必要な設定は済んでいると思われるので
プロジェクトセッティングのインポートは不要になると思われます。

# 方法1
まずはこちらを試してください。

## Asset StoreからVuforia Engine(インストール用)を入手する
蛇足ですがUnity2020からUnity Editor内のAsset Storeが無くなりました。
Web版のAsset Storeを開くように誘導されます。

- [Unity アセットストア - ゲーム制作のための最高のアセット](https://assetstore.unity.com/?locale=ja-JP)
    - [Vuforia Engine | Packs | Unity Asset Store](https://assetstore.unity.com/packages/templates/packs/vuforia-engine-163598)

Asset StoreからVuforia Engineを検索して購入(無料)してください。

## PackageManagerからVuforiaをインストールする

Unity内でPackageManagerを開き、左上のPackagesからMy Assetsを選んでください。
ここから購入したAssetが選択できるのでVuforiaを選択して↓ボタンを押してダウンロードしたのち、
右下のimportボタンからプロジェクトにインポートしてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18135/eff1ae5f-2c7f-f16a-72de-56a04b2b86dd.png" width="50%">

このときVuforiaの本体がPTCから自動的にDLされます。(結構時間がかかります)
正しくインストールされていればGameObjectからVuforia Engine -> ARCameraなどが追加できるようになります。

# 方法2
方法1がダメな場合、もしくはVuforia本体のDLが済んでおり、再度DLがめんどくさいとき。
古いプロジェクトとかでごちゃごちゃしてる時は方法1が失敗するケースもありました。

**最近のUnity2020.1周りだと、Unityのバージョンが変わるたびにVuforiaがPackageにいなくなることがあり、
さらにMy Assetからのインストールもできないケースが手元で発生したため、
こちらの手段(tarball)を準備しておいた方が良いかもしれません。**

## ptcからVuforia本体を入手する
- [Vuforia Engine package](https://packages.developer.vuforia.com/)

から最新のVuforiaを取得してください。

## PackageManagerでVuforiaを追加する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18135/c3bcecd3-821d-6d00-83d5-9745c68c461c.png" width=50%>

PackageManagerの左上の+ボタンを押してtarballからパッケージを追加してください。
先ほどDLしたファイルが選べます。

この方法でインストールしたVuforiaもちゃんとPackageManagerでアップデートできるので安心です。

# 参考記事

- [Vuforia Engine Package Hosting for Unity](https://library.vuforia.com/content/vuforia-library/en/articles/Solution/vuforia-engine-package-hosting-for-unity.html)
- [Vuforia Engine package](https://packages.developer.vuforia.com/)