OmniAICreator/Qiita-1.07M huggingface dataset:
AWS CodeStar と Bitbucket 上の既存リポジトリを連携しようとしてみた

　ローカルで作っている Web アプリケーションを公開しようかなーと思ったとき、ふと以下のことを思いついて試してみたときのメモです。

* 使い慣れてるので Bitbucket でソースコードを管理したい
* ビルドやデプロイ環境を楽につくりたい

　そういうわけで試しに AWS CodeStar と連携してみました。AWS CodeStar って何ぞやという説明は割愛します。以降、AWS Code* 系のサービスは 「AWS」を略して記載します（省略後：CodeStar、CodeCommit、CodeBuild、CodeDeploy、および CodePipeline）。

## 環境
言語： Java 8（Spring Boot 2.0.2）
ビルドツール： Gradle

## 結論
　うまくいった部分もうまくいかなかった部分もありました。

* CodeStar により開発からデプロイ環境が一斉に整うのはとても楽
  * とても楽だが、CodeStar で生成されたものと既存プロジェクトでの差分は吸収する必要がある
* CodeBuild 上でテストしようとするとエラーで失敗した（未解決。ただ、ローカルでは通る）
  * （テストをスキップすれば）Bitbucket の master ブランチを更新するだけでビルドされデプロイされる

　そもそも CodeStar は「新規プロジェクトにどうぞ」というスタンスであり、上記の使い方は AWS 側の想定していないものです。私が今までやってきたような Bitbucket 中心のソースコード管理や CI を前提に考えると、現実的には、Bitbucket + CI + CodeDeploy のような構成がよいかなと思ってます。単にまだ使いこなせてないだけかも、多分その可能性が濃厚。

## 手順
1. CodeStar で新規プロジェクトを作成する
2. CodeCommit に作成された新規リポジトリと Bitbucket 上の既存リポジトリのソースコードをマージする
3. 上記 2. でマージしたソースコードを CodeCommit と Bitbucket に push して両者の状況を揃える
4. Bitbucket の Pipelines を設定（Bitbucket から CodeCommit への push のため）
5. 動作確認。Bitbucket の master ブランチを更新した後、デプロイまで成功することを CodeStar のダッシュボードで確認
6. 何かしらのエラーがあるか、エラーが無くてもデプロイされていない場合は設定などを確認

## 1. CodeStar で新規プロジェクトを作成する
こちらについては特に説明することはありません。公式のガイドにしたがってプロジェクトを作成します。

## 2. CodeCommit に作成された新規リポジトリと Bitbucket 上の既存リポジトリのソースコードをマージする
CodeCommit と接続する方法は AWS のガイドにあるのでそちらを参照してください。
冒頭に述べた環境においては、CodeCommit に作成されたファイルのうち、以下のファイルがマージ対象です。

* appspec.yml
  * CodeDeploy で使用されます
* buildspec.yml
  * CodeBuild で使用されます
* template.yml
  * CloudFormation で使用されます
* scripts/*
  * CodeDeploy で使用されます

## 3. 上記 2. でマージしたソースコードを CodeCommit と Bitbucket に push して両者の状況を揃える
特筆することはありません。

## 4. Bitbucket の Pipelines を設定（Bitbucket から CodeCommit への push のため）
以下のサイトを参考を元に設定しました。
https://medium.com/@jay_proulx/aws-codecommit-from-atlassian-bitbucket-and-bitbucket-pipelines-for-ci-offloading-4f1131695802

AWS 上に Bitbucket 用のユーザを用意してあげて、後は、自分が CodeCommit と連携するときの要領で諸々を設定してあげるという感じです。

## 5. 動作確認。Bitbucket の master ブランチを更新した後、デプロイまで成功することを CodeStar のダッシュボードで確認
タイトルの通りですが、デプロイ完了までには結構かかります。CodeStar プロジェクトによって生成された初期コードでも 6 か 7 分ほどなので、気長に待ちます。CodePipeline のフェーズすべてに成功しており、アプリケーションエンドポイントにアクセスして想定どおりのページを確認できればOK。

## 6. 何かしらのエラーがあるか、エラーが無くてもデプロイされていない場合は設定などを確認
ここまでの手順により、Bitbucket のブランチが更新されると、自動的に CodeCommit に同期され、CodeBuild が走り、CodeDeploy されるようになるかと思います。とはいえ、開発やデプロイのために万事整ったかというと、そうではないかもしれません。恐らく、既存プロジェクトとの差分を吸収せざるを得ないでしょう。私が遭遇した課題は例えば以下です。

* 既存プロジェクトは Gradle でビルドしているが、CodeStar の初期プロジェクトは Maven でビルドしている
* 既存プロジェクトは jar ファイルを生成しているが、CodeStar の初期プロジェクトは war ファイルを生成している
* 先述した通りだが、CodeBuild で ./gradlew test に失敗する（ローカルでは成功する）
* などなど……

次に述べるものは既存プロジェクトとの差分ではありませんが、DB との繋ぎ込みや、Web サイトの SSL 化や、ステージングにデプロイするように CodePipeline を編集したり、場合によって本番デプロイ前に承認フェーズを挟むよう CodePipeline を編集するなど、要件に応じて他に対応する必要がありそうな要素はいろいろ考えつきます。

## 感想
　古式ゆかしきサーバ構築はおろか、パブリッククラウドにも全然詳しくないのですが、何とか目的は達成できましたし、勉強にもなりました。でも CodeBuild でテスト通せないのは致命的なので、もう少し調べてみようかなという感じです。
Ren'Pyでノベルゲームを作ろう

２周目だよ,AdventCalendar第12回はじまるよ〜

#Ren'Pyって知ってる?
はい,今回はRen'Pyというノベルゲーム制作に非常に役に立つフリーソフトウェアエンジンを紹介します!

Ren'Pyというのは名前にもある通りナウい言語であるpythonで書かれています.
Ren'Pyで作られたゲームの代表作は,Steamで非常に有名な「*Doki Doki Literature Club!*」通称**ドキドキ文芸部**です.

これは,多くのYoutuberやVTuberによって実況され,知っている方も多くいるでしょう.かくいう筆者もプレイ済みで,それもあってRen'pyという存在に気づきRen'Pyを触ってみようと思いました.

その他有名になっているゲームとしては,「**かたわ少女**」というゲームも一時期有名になりました.

ドキドキ文芸部しかり,かたわ少女しかりRen'Pyには中々ニッチなゲームが多い気もしますが…(他作品もあるのですが,筆者がやったことないのでどうかはわかんないです.詳しくはこちらをどうぞ→[Ren'Py-Wikipedia](https://ja.wikipedia.org/wiki/Ren%27Py))

まあそんなことは置いといて,これほど有名なゲームを排出するRen'pyがフリーで!誰でも簡単に！ノベルゲームを作れる!というのだから,ノベルゲーム作りたい!という人に対しては非常におすすめです.

#実際に使ってみよう!

ということで,Ren'Py早速触って行きましょう!

基本[ここ](http://ja.renpy.org/doc/html/index.html)を参考にしているので詳しくはぜひこちらへ.

では早速[Ren'Pyをダウンロード](https://www.renpy.org/latest.html)しましょう.

**注意!!最新バージョンのチュートリアルが日本語に対応してないっぽいので,日本語でチュートリアルをしたい方は[こちら](http://ja.renpy.org/latest.html)からダウンロードしてください**

ダウンロードができたら展開して,実行しましょう.
Windowsは**Download SDK 7z.exe**,Macでは**Download SDK dmg**,Linux系では**Download SDK tar.bz2**をダウンロードしましょう.(各バージョンは2018/08/23のものです)

各実行の仕方としては

- Windowsはダウンロードをしたファイルをダブルクリックで起動.その後どこに保存するか聞かれるので自分の保存したい場所に保存する.その後renpy.exeを実行してください.
- Macはダウンロードしたdmgをダブルクリックで起動させ出て来たフォルダを任意の自分のフォルダにコピーしてください.その後renpy.appを実行してください.Macなのでrenpy.shでも実行は可能です.
- Linux系はtarballで解凍してください.その後renpy.shを実行してください.

起動できたましたか?もし,起動できなければ,保存場所などを変えてみたりとか,各自ドキュメントをしっかり確認してください.

では,次は言語設定です.Ren'Pyは初期状態では英語となっています.変更したい場合はアプリケーション下部の**Launch Project**の下に**preference**があるのでそこから**Language**の欄からお好みの言語に設定してください.

ここまでくればあとは実際に動かして見るだけです.日本語設定にしたと仮定して,**プロジェクトの起動**をクリックしてください.

そうするとアプリケーションが立ち上がるので,**Start**を押しましょう.
すると,Tutorialが立ち上がるのでそれを見て色々やって行きましょう!

#最後に
今回は喋ることが多すぎるので,最初の導入のみ書きました.基本Tutorialに沿ってやって行けば簡単なノベルゲーならすぐにできると思いますが,細かくやって行くとpythonの知識な度が必要になってくるのでその辺を分割してまた書こうかなと思ってます.それでは今回はここで終了です.おつかれさまでした.

#参考資料

[Ren'Pyの日本語ドキュメント](http://ja.renpy.org/doc/html/index.html)
[本家ドキュメント](https://www.renpy.org/doc/html/index.html)
[Ren'PyのWiki](https://ja.wikipedia.org/wiki/Ren'Py)
Cognos Analytics で逆スタースキーマモデルの実践 - ①基本的なモデルの動作検証

#概要
とあるCognos Analyticsのプロジェクトで、逆スタースキーマモデルを実践してみましたので、学んだ事を何回かに分けて投稿しておきます。
要件として、以下の様な要件があっため、逆スタースキーマモデルを選択しました。
① データベースのテーブル構造として、ファクトデータが正規化された多数の表に分散していて、分析向けのデータウェアハウスのテーブル構造ではなく、オペレーショナルモデル構造であった。
② ETLを行いファクト表をまとめ、データウェアハウスを構築していくという要員も時間も無かった
③ 定型レポートだけでなく、エンドユーザーによる自由分析も要件として存在した

#逆スタースキーマモデルとは
逆スタースキーマモデルの前に、スタースキーマモデルのおさらいです。
スタースキーマモデルとは、ラルフ・キンボールが提唱したBIのデータ分析向けのモデルで、こんな感じに巨大な1つのファクト表の周りを複数のディメンション表（マスター表）が取り囲むモデルで、通常のCognosのプロジェクトでは、できる限りこのモデルになるように意識して、テーブル構造の設計を行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/f94fd768-23a3-30b5-5d70-9dcda9faab48.png)

それに対して、逆スタースキーマモデルとは、1つのディメンション表の回りを、複数のファクト表が囲むモデルになります。
要件にあった、オペレーショナルモデルでの多数のファクト表があるテーブル構造での分析を行うため、このモデルを選択しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/239a97f1-c018-4594-05f0-16ffb5a1b3d4.png)

ちなみに、ディメンション表が複数ある場合、こういうモデルになり、Customer Type Dimensionの様な、個々のファクトにユニークなディメンション（Customer Typeデータ列は、Bad Debt Fact表にしか存在せず、他のファクト表には存在しない状態）は、個々のファクト表とのみリレーションを張ります。
Time Dimensionの様な、複数のファクトで使用されるディメンションは、青枠の様にエリアスを作成して、各ファクト表とリレーションを張ります。
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/2578b05f-4951-5a95-f3ae-e39c9c580667.jpeg)


**参考：THE REVERSE STAR SCHEMA**
http://www.digitalviper.co.uk/documents/The_Reverse_Star_Schema_v2.1.pdf

#とりあえず検証してみてわかった事
まず、こんな感じの簡単なテーブル構造を作成して検証してみました。
DIMA1表が逆スタースキーマの中心で、FACTA1、FACTA2、FACTA3表が回りを取り囲みます。
FACTA1とFACTA2にのみ保持されているYEAR列を持つDIMA2表は、エリアスを作成しFACTA2表に接続しています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/bdd4835a-7f62-1eec-e135-d7466fd41d09.png)

**DIMA1.PROD、FACTA1.SALES、FACTA2.PLAN、FACTA3.STOCK をリストに配置**
問題なく正常な値が表示されました。
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/7e85a66b-ed54-74d5-a029-771e81f7cde2.jpeg)

**DIMA1.PROD、FACTA1.SALES、FACTA2.PLAN、FACTA3.STOCK をリストに配置し、DIMA2.YEAR='2017'でフィルター**
DIMA2と接続されているFACTA1表のSALESに対しては、しっかりとフィルターが効きますが、FACTA2表のPLANに対してはフィルターが効かない事が分かります。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/5c8062dd-dbc1-df17-d989-5aaa58ab5fc3.jpeg)

**DIMA1.PROD、FACTA1.SALES、FACTA2.PLAN、FACTA3.STOCK をリストに配置し、DIMA2.YEAR='2017'でフィルター、DIMA2(Alias).YEAR='2017'でフィルター**
DIMA2のエリアスのYEARの方からもフィルターを設定すると、PLANに対してもフィルターがかかります。
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/0efe951b-607e-52fc-f9ff-dbb47580c1a2.jpeg)

**DIMA1.PROD、FACTA2.PLAN、FACTA3.STOCK をリストに配置し、DIMA2.YEAR='2017'でフィルター**
以下のエラーメッセージで、エラーになります。
フィルターのDIMA2から接続されているFACTA1のデータがリストのクエリーに存在しないため、こういう組み合わせはNGのようです。
*XQE-PLN-0084 SQL を生成できません。フィルター条件 [DatabaseView].[DIMA2].[YEAR]='2017' を、ファクト射影を含まない次のファクト・ストリームに適用できませんでした: (DIMA2)。*

#この時点での問題点
周りに配置したディメンション表のデータをフィルター等で使用する場合は、どのファクト表とリレーションがあるのか、ファクト表のデータがクエリーに入っているのか、というのをしっかり意識してレポートを作る必要があります。
定型レポートであれば、そこを理解している開発者が行えば良いですが、自由分析が要件にあるので、エンドユーザーにこれを理解して使ってもらうのは無理ですね。
さてどうするか、というのは第②回に投稿させていただきます！

#目次
第①回：基本的なモデルの動作検証
https://qiita.com/shinyama/items/0567425a4a47ad7d6efa

第②回：自由分析への対応
https://qiita.com/shinyama/items/5bb75bae2e67d6e9cac0

第③回：属性データのモデル取り込み
https://qiita.com/shinyama/items/b66d59a92a58533f7c2b

第④回：パフォーマンス・チューニング
https://qiita.com/shinyama/items/b4b28844b4235db70032
WebStorm のプラグイン「String Manipulation」でスネークケースを普通の単語区切りに戻す

https://plugins.jetbrains.com/plugin/2162-string-manipulation

バックエンド、特にデータベース上では snake_case で値が保存されていることが多いと思います。しかし画面表示する際には「Snake Case」と普通の英文として表示したい。ということはよくあります。

こういった場合、なんらかのライブラリで自動変換した方がいいですが、さしあたってハードコーディングしたい場合に、WebStorm の「String Manipulation」が便利です。

```
snake_case => Snake Case に直したい
```

プラグインをインストールして、変換したい文字の上でメニューを開くと、String Manipulation というコマンドが追加されています。

![Screen Shot 2018-08-23 at 2.36.19 PM.png](https://qiita-image-store.s3.amazonaws.com/0/240885/1d997333-f8d4-e984-b8be-924b4f33e607.png)

ここから Switch Case で任意の形式に変換できます。

ちなみに snake_case を Snake Case に変換するには、To camelCase を二回実行すれば OK です。

さらに Keymap(WebStorm のショートカットキーの管理エディタ)でこのコマンドを登録できますので、ささっと形式を変更できます。
MySQL8.0でCircleCIビルドエラー。Authentication plugin 'caching_sha2_password' cannot be loaded

```yml
version: 2
jobs:
  build:
    working_directory: ~/repo
    parallelism: 1
    docker:
      - image: circleci/mysql:8.0.12
        command: mysqld --default-authentication-plugin=mysql_native_password
```

コマンドに`--default-authentication-plugin=mysql_native_password`オプションを付けてあげればとりあえず動く。
VS2017 VC++での文字コードについて

Windowsアプリではビルド設定でUnicode/ANSIが設定可能
VS 2017ではUnicodeはUTF-16、ANSIはshift_jisのことぽい。
Linux系はUTF-8が主流なのでこの辺りはどちらかのシステムで吸収する必要がある。

CStringはビルド環境で変わってしまうため
また意図的に文字コードを意識しなければならないときは
CStringW/CStringAとかstd::wstring/std::stringなどを使う。

変換には
Windows APIのMultiByteToWideChar/WideCharToMultiByteで行う。

昔はコードページIDが定義されてた気がするけど
今はどのヘッダーファイルなのかCP_UTF8/CP_UTF7しかみえない。

https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers
ここに一覧がある。日本語関係で必要なもの

12000 	 	
     
| CodePageId       | .NETでの名称 | 意味 |
|:-----------------|:-----------------:|-------------------:|
| 932 | shift_jis | ANSI/OEM Japanese; Japanese (Shift-JIS) |
| 12000 | utf-32 | Unicode UTF-32, little endian byte order |
| 12001 | utf-32BE | Unicode UTF-32, big endian byte order |
| 20932 | EUC-JP | Japanese (JIS 0208-1990 and 0212-1990) |
| 51932 | euc-jp | EUC Japanese |
| 50220 | iso-2022-jp | ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) |
| 50221 | csISO2022JP | ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) |
| 50222 | iso-2022-jp | ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) |
Rails5.2でCircleCIビルドエラー。Devise.secret_key was not set. Please add the following to your Devise initializer

Rails5.1から`secret_key`を`Rails.application.credentials.secret_key_base`で設定するようになったが、CircleCIには`master.key`が渡されないのでこのエラーが発生する。

CircleCIの Build Settings > Environment Variables で環境変数を設定できる。
`RAILS_MASTER_KEY`に`master.key`の内容を設定してあげれば動く。

参考
[Handle Credentials in CircleCI - Rails App - Stack Overflow](https://stackoverflow.com/questions/48935168/handle-credentials-in-circleci-rails-app)
cakephp3のマイグレーションファイル内でDB接続先を変えれるか

## 結論
接続先別にディレクトリを分けてコマンド叩くときにオプション指定する
[CakePHP3のMigrationsでDB接続先を切り替える方法](https://sousaku-memo.net/php-system/1578)


## 試したこと
```php
<?php
use Migrations\AbstractMigration;
use Cake\Datasource\ConnectionManager;
use \Phinx\Db\Adapter\MysqlAdapter as MysqlAdapter;

class CreateUsers extends AbstractMigration
{
    public function initialize()
    {
        $connectionArray = ConnectionManager::get('other')->config();
        $connectionArray['pass'] = $connectionArray['password'];
        $connectionArray['user'] = $connectionArray['username'];
        $connectionArray['name'] = $connectionArray['database'];
        $this->setAdapter(new MysqlAdapter($connectionArray));
    }
    public function change()
    {
        $this->initialize();

        $table = $this->table('users', ['id' => false, 'primary_key' => ['user_id']]);
        $table->addColumn('user_id', 'biginteger', [
            'autoIncrement' => true,
            'comment' => 'ID',
            'default' => null,
            'limit' => 20,
            'null' => false,
        ]);
        $table->create();
    }
}
```
上記のファイルで下記コマンドをたたけば一応振り分けてくれた。
`./bin/cake migrations migrate`

が、defaultDBとotherDBの両方にphinxlogが出来てしまった。
defaultDB側のphinxlogに実行したログが残り、statusがupとなる。
otherDB側のphinxlogは空だが、tableはこちらのDBに作られた。
もやもやするので却下。

※別の方法があれば追記予定
rmで.や..が使えないんですけど!?

## 問題
```
$ rm -rf .
```

でファイルを削除しようとしたら、こんなエラーが

```
rm: refusing to remove ‘.’ or ‘..’ directory: skipping ‘.’
```

直訳すると、ディレクトリを削除するのに'.'や'..'は使えないってことか。

じゃあどうすれば良いんですかね?

## 解決編
その答えは簡単。
ディレクトリを直接指定してあげればいい。

```
$ ls
. .. a b c

$ rm -rf a b c
```

ζ*'ヮ')ζ<おるおっけー!!


## 参考記事
https://unix.stackexchange.com/questions/192843/why-doesnt-rm-rf-delete-anything
サーバ上のRubyファイルを直接編集する時にやっておくとよい事

# 使える場面

Railsのアプリケーションを運用していると、緊急対応でサーバ上のファイルを直接いじってサーバ再起動なんて事が時々あると思います。
そんな時、サーバを再起動したらシンタックスエラーが出まくってやばいやばいみたいな事態に陥る可能性を少しでも低くするためにやっておくと良い事です。

# 対応内容

`/path-to-app-dir/sample.rb` を編集したら

```
ruby -c /path-to-app-dir/sample.rb
```

を実行しましょう。
`ruby` コマンドの `c` オプションはスクリプトを実行せず、内部形式へのコンパイルのみを行って結果を表示してくれます。
つまり、スクリプトの文法確認ができます。

### 文法エラーが無い場合の出力

```
Syntax OK
```

### 文法エラーがある場合の出力例

```
sample.rb:1: syntax error, unexpected end-of-input, expecting ')'
```

サーバ再起動前にこの確認をしておくとシンタックスエラーで焦る事が無くなるので、ぜひやっておきましょう。
スプレッドシートのアクティブセルに指定した文字を連結するマクロを作ってショートカットで実行できるようにしたメモ


## はじめに
文字を入力して、ショートカットコマンドを打ったら勝手にURLに変わるようにしてみました。

GoogleAppsScript
https://developers.google.com/apps-script/

## 1. スプレッドシートを立ち上げる

<img width="1058" alt="スクリーンショット 2018-08-23 13.51.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/febab937-53cc-c9b9-0e94-8237533f49b1.png">

## 2. ツール＞スクリプトエディタを選択する

<img width="1058" alt="スクリーンショット 2018-08-23 13.51.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/726d9de1-ac14-8a2a-b6fd-6c5a4f4f6774.png">

## 3. 機能を実装する

```
function createUrl() {
 // 現在アクティブのシートを取得する
 var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
 // 現在日付を取得する
 var today = Utilities.formatDate(new Date(), ‘Asia/Tokyo’, ‘yyyyMMdd’);
 // 現在アクティブセルの値を取得する
 var activedValue = sheet.getActiveCell().getDisplayValue();
 // アクティブセルにURLを表示する
 sheet.getActiveCell().setValue(‘http://’ + activedValue + today);
}
```
<img width="741" alt="スクリーンショット 2018-08-23 13.53.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/9653d946-4daa-ae6d-b3c9-cadd2a4ad436.png">

## 4. ツール＞マクロ＞インポートを選択する

<img width="1058" alt="スクリーンショット 2018-08-23 13.53.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/65b956c8-8cc1-b94f-5322-b98e99bd5607.png">

## 5. 実装した機能を選択する

<img width="1058" alt="スクリーンショット 2018-08-23 13.53.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/82379b7c-e85c-e5d0-1152-54308483b79a.png">
<img width="1058" alt="スクリーンショット 2018-08-23 13.53.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/98807e92-1df1-1bac-6947-38d4182dd974.png">

## 6. マクロ　＞マクロを管理を選択する

<img width="1058" alt="スクリーンショット 2018-08-23 13.54.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/d79aa66d-091d-c89c-d91d-eabfa91bc051.png">

## 7. マクロ　＞マクロを管理を選択し、任意の値を入れる

<img width="1058" alt="スクリーンショット 2018-08-23 13.54.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/1ca2ce8d-a85d-1a1d-807a-a6d00890ee54.png">

## 8. 後は、文字列を入力し、 command + option + Shift + [任意の文字列でここでは 0 ]を押下すると、URLできます！
<img width="1058" alt="スクリーンショット 2018-08-23 13.55.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/74e952d7-f6d3-6efd-1948-c503a389ba0b.png">

<img width="1058" alt="スクリーンショット 2018-08-23 13.55.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/184849/35b253c7-cbd7-a6ba-a530-214cee5310a2.png">
文字列はファイル依存？コンパイラ依存？

![image001.png](https://qiita-image-store.s3.amazonaws.com/0/76058/c69454f2-1c28-6e12-3f48-943f66653b92.png)

```bash:error
warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
error C2001: 定数が 2 行目に続いています。
error C2143: 構文エラー : ';' が 'for' の前にありません。
warning C4018: '<' : signed と unsigned の数値を比較しようとしました。
```

Visual C++を使っていてこんなエラーを見たことがあるだろう。

でもこのエラー、文字コードに起因することが原因というのはわかるのだが、ファイルが原因なのか、コンパイラが原因なのかがよくわからなかった。

## 検証

Clang、VCで以下のコードを実行してみた。
shift_jis、UTF-8、UTF-8N(BOM無し)の３種類でそれぞれファイルを保存してコンパイルを実行させている。
実行すると、文字列がコンソールに16進数で表示される。

```c++:main.cpp
#include <iostream>
// int _tmain(int argc, _TCHAR* argv[]) // <- Visual Studio
int main() {
    std::string text = "あ";
    for (int i = 0; i < text.length(); i++) {
        std::cout << std::hex << (int) text[i] << std::endl;
    }
  // system("pause"); //<-VisualStudioのみ
    return 0;
}
```

今回使った環境は下記

|OS|コンパイラ|エディタ|
|:--|:--|:--|:--|
|Mac|Clang|XCode,CLion|
|Win|VisualC++|VisualStudio|

結果は下記

|コンパイラ|ファイルの文字コード|結果表示|
|:--|:--|:--|
|Clang(Mac)|Shift_jis|ffffff82<br/>ffffffa0|
|Clang(Mac)|UTF-8|ffffffe3<br/>ffffff81<br/>ffffff82|
|Clang(Mac)|UTF-8N|ffffffe3<br/>ffffff81<br/>ffffff82|
|VC(Win)|Shift_jis|ffffff82<br/>ffffffa0|
|VC(Win)|UTF-8|ffffff82<br/>ffffffa0|
|VC(Win)|UTF-8N|Error|

ということは、Clangは、ファイルのコードをそのまま通して、VisualStudioはBOMがあればUTF-8であると認識してShiftJISに変換したうえでコンパイルしているということになる。

追記：yumetodo様より、「gccとmsvcは文字コードの変換機能がある。」と教えていただきました。

※結果表示の先頭にある`ffffff`は、charが1バイトに対してintが4バイトであるため。

## wchar_t

文字列をwstring(wchar_t)にしてみた。

```c++:main.cpp
// 略
std::wstring text = L"あ";
// 略
```

|コンパイラ|ファイルの文字コード|結果表示|
|:--|:--|:--|
|Clang(Mac)|Shift_jis|Error|
|Clang(Mac)|UTF-8|3042|
|Clang(Mac)|UTF-8N|3042|
|VC(Win)|Shift_jis|3042|
|VC(Win)|UTF-8|3042|
|VC(Win)|UTF-8N|Error|

今度はClangの方でエラーが発生した。

```bash:CLionコンソール
Scanning dependencies of target test_unit
[ 50%] Building CXX object CMakeFiles/test_unit.dir/main.cpp.o
main.cpp:6:27: error: illegal character encoding in string literal
    std::wstring text = L"<82><A0>";
                          ^~~~~~~~
1 error generated.
make[3]: *** [CMakeFiles/test_unit.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/test_unit.dir/all] Error 2
make[1]: *** [CMakeFiles/test_unit.dir/rule] Error 2
make: *** [test_unit] Error 2
```

ようは、元の文字列をワイド文字列に変換出来ないということらしい。

エラーが無い場合すべて3042になっているのは、ワイド文字列が「1文字を1つの整数値で扱えるようにすることを目指した」ことに起因する。

> [ワイド文字 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AF%E3%82%A4%E3%83%89%E6%96%87%E5%AD%97)

ちなみにUnicode対応表を見ると、UTF-16として3042が割り当てられているのがわかる。

[Unicode](http://ash.jp/code/unitbl21.htm)

<img width="293" alt="image002.png" src="https://qiita-image-store.s3.amazonaws.com/0/76058/51db0921-ce76-28ae-fe53-5755f2653128.png">


## VCのUTF-8ファイル対応

[Visual Studio で UTF-8 で C++ を書いたら心が折れそうになった件 - Hikware.Tech](http://tech.hikware.com/article/20171020a.html)

こちらにあるように`/source-charset:utf-8`とすればutf-8を読み込めるが、なかなか悲しい現実が待ち受けています。
CSS 3-1 快速入門 By 彭彭

```
1 關於 w3c 技術規格的制定和實踐
https://caniuse.com/
````
![WS000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/c21ed195-1f54-9996-805f-a0433ada7333.jpeg)
![WS000003.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/cd7bb4af-6360-3450-6191-19e335628fe8.jpeg)

css3提供視覺效果

![WS000005.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/e97d0916-1b6b-3170-1ba1-171e3ca1247b.jpeg)


```ruby
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
	<title>css3 快速入門</title>
    <style type="text/css">
	.box{
		width:100px;height:100px;background-color:pink;
		opacity:1;
		border-radius:50%;
		box-shadow:0px 0px 100px #000000;
		text-shadow:50px 70px 1px #000000;
	}
	</style>
</head>
<body>
    <div class="box">florence</div>
</body>
</html>
```
Firebase Functions で Cloud Firestore内のデータをCSVでダウンロードする

## Firebase FunctionsをHTTPリクエスト経由で呼び出す
ブラウザから呼び出す仕組みがあります。
https://firebase.google.com/docs/functions/http-events?hl=ja
これを利用してFirebaseのDBのレコードを取得します。

## jsonをcsvにするjson2csvをインストール
Firebaseの基本モジュールには入っていないようなのでローカルでデプロイ前にインストールしておく

``` cmd
# npm install json2csv
```

## 関数の作成
index.js内にこんな関数を作成します。サンプルではusersコレクション内すべてのレコードをcsvにする例

```javascript
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp();

exports.userlist = functions.https.onRequest((request, response) => {
  const json2csv = require("json2csv").parse;
  const db = admin.firestore();
  const ordersRef = db.collection('users');
  return ordersRef.get()
    .then((querySnapshot) => {
      const orders = [];
      querySnapshot.forEach(doc => {
        const order = doc.data();
        orders.push(order);
      });
      const csv = json2csv(orders);
      response.setHeader(
        "Content-disposition",
        "attachment; filename=users.csv"
      );
      response.set("Content-Type", "text/csv");
      response.status(200).send(csv);
      return ""
    }).catch((err) => {
      response.status(200).send("エラー発生： " + err);
      return Promise.resolve();
    });
})
```
collection内のデータを取得して１コレード単位で配列に入れてCSVに変換後、ヘッダを指定して出力するだけ。データの取得条件はもう少し複雑にできるはず。
また、.then()を使う場合は何かをreturnしなきゃいけないので空文字をreturnしています。この辺の仕様はあまり厳密ではないのかも。。。調査中です。

https://us-central1-[PROJECT_NAME].cloudfunctions.net/userlist  でアクセスできます。
iPhoneXでも他でも使える"上に表示するバー"(NavigationBar)を作ろう

# いきさつ
iPhoneX対応のことを一切考えないでNavigationBarをつけてたらiPhoneXで変になったので色々調べてた。
[こちら](https://medium.com/@kahseng.lee123/creating-custom-navigation-bar-tab-bar-for-iphone-x-f03b1e1827d3)にいい感じの記事があったので真似して作ってみた

# 構成はUIView+NavigationBar
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211192/7f735e94-3797-1c1a-1727-e54a15fbad14.png)
作りたいのはこんな感じのNavigationBar。
背景としてNavigationBarに合わせたサイズのUIViewを使い、NavigationBarは高さ44でSafeArea内におく。
こうすることで**NavigationBarにおいたボタンが隠れないで済む**

# いざ実装
## navigationBarを作る

```swift
     func addNavigationBar(){
        //インスタンス生成してviewに入れる
        var navigationBar = UINavigationBar()
        self.view.addSubview(navigationBar)
        //navigationBarの色を透明にする
        navigationBar.setBackgroundImage(UIImage(), for: .default)
        navigationBar.shadowImage = UIImage()
        //navigationBarのサイズと位置を調整
        if #available(iOS 11.0, *) {
            //iOS11よりも上だったら(iPhoneXだろうがiPhone8だろうがiOSが11より上ならこっちでまとめて対応できる)
            navigationBar.frame.origin = self.view.safeAreaLayoutGuide.layoutFrame.origin
            navigationBar.frame.size = CGSize(width: self.view.safeAreaLayoutGuide.layoutFrame.width, height: 44)
        }else{
            //もしもiOS11よりも下だったら
            navigationBar.frame.origin = self.view.frame.origin
            navigationBar.frame.size = CGSize(width: self.view.frame.width, height: 44)
        }
     }
```

## navigationView(背景)を作る

```swift
     func addNavBackView(){
        //背景用のviewのインスタンスを生成してviewに入れる
        var navigationView = UIView()
        self.view.addSubview(navigationView)
        //ここで背景変えてくれ
        navigationView.backgroundColor = UIColor.blue
        //navigationBarの背景のサイズと位置を調整
        if #available(iOS 11.0, *) {
            navigationView.frame.origin = self.view.safeAreaLayoutGuide.owningView!.frame.origin
            navigationView.frame.size = CGSize(width: self.view.safeAreaLayoutGuide.owningView!.frame.width, height: navigationBar.frame.origin.y + navigationBar.frame.height)
        }else{
            navigationView.frame.origin = self.view.frame.origin
            navigationView.frame.size = CGSize(width: self.view.frame.width, height: navigationBar.frame.origin.y + navigationBar.frame.height)
        }
     }
```

## あとは**``viewWillLayoutSubviews()``のなかで**関数を呼ぶ

```swift
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        //順番とviewDidLoad()の中じゃないことに注意！！！
        addNavigationBar()
        addNavBackView()
    }
```

# 完成
やったー
AWS SQSのキューに貯まった100件のメッセージをコマンドラインから一括削除

# 背景

動作確認しまくってたらDLQにメッセージが貯まりまくってしまった。
AWSコンソールから消してもいいけど非効率...。

# 前提

+ わたしは fish ユーザーです
+ [jq](https://stedolan.github.io/jq/) インストール済

# コマンド

```bash
$ for x in (seq 100)
    aws sqs receive-message --queue-url <queue-url> | \
    jq ".Messages[].ReceiptHandle" | \
    xargs aws sqs delete-message --queue-url <queue-url> --receipt-handle
  end
```

以上です。
firebaseのRealtimeDatabaseをtypescriptでいじりたい（webpack + typescript + firebase_admin）

RealtimeDatabaseのデータをmigrationとかでいじりたいときあるっすよね。
想定してないデータができないようにルールを使うと思うんですが、
自分はtypescriptでルール通りに型をつくってデータを作成するようにすると安心できるので気に入ってます。

typescriptのコンパイルでwebpackを使ったんですが構成は下記みたいな感じ↓
https://github.com/chucker34/firebase_admin_pack

ちょっと詰まったところはwebpack.config.jsの`resolve.mainFields`で`main`を優先するようにしないと`TypeError: rtdb.initStandalone is not a function`と怒られたこと。
俺たちのstackoverflowで同じように困っている人がいましたよと。
https://stackoverflow.com/questions/48266195/typeerror-rtdb-initstandalone-is-not-a-function
`target: node`にしてもブラウザ向けのファイルが使われていたのが原因。webpackだから普通そうなるけどね。

```js
// webpack.config.js
const Dotenv = require('dotenv-webpack');

module.exports = {
  target: 'node',
  mode: 'development',
  entry: './src/main.ts',
  output: {
    path: `${__dirname}/dist`,
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader'
      }
    ]
  },
  resolve: {
    extensions: [ '.ts', '.js', '.json' ],
    mainFields: ['main', 'module']
  },
  plugins: [
    new Dotenv()
  ]
};
```
投稿テスト（Markdown記法のヒント）

#参考
>マークダウン記法 一覧表・チートシート
https://qiita.com/kamorits/items/6f342da395ad57468ae3

Markdown記法のヒント
見出し
# 見出し 1
## 見出し 2
### 見出し 3
強調
**強調**
リンク
[リンク](http://...)
コード
```ruby:filename.rb
コード
```
リスト
- リスト 1
- リスト 2
    - リスト 2-1
1. 番号付きリスト 1
2. 番号付きリスト 2
3. 番号付きリスト 3
- [ ] チェックボックス 1
- [ ] チェックボックス 2
- [x] チェックボックス 3
JSでhttpsにリダイレクトする

こういうことはサーバーサイド側でやるべきだが、緊急の一次対応としてフロントエンド側で対応することが起こった。
もちろんサーバーサイドでの恒久対応は別途行うものとする。

# 問題のコード
「http → https にすればいいんだな」と思って文字列のreplace処理にこんなコードを書いた

```js
var url = location.href

if(url.indexOf('http') >= 0) {
  // url文字列の書き換え
  var newUrl = url.replace('http', 'https');
  ...
}
```

「お、書き換わってる」成功だと思ったが、
数分後、問題に気づく。

「https」という文字列にも「http」が含まれているのだ。
なので、httpsのURLでアクセスした場合、if文の判定を通ってしまうため、
このままだと「https」 → 「httpss」 に置き換えられてしまう。


# 修正後
httpとhttpsをちゃんと区別するように一文字加えた。

```js
var url = location.href

if(url.indexOf('http:') >= 0) { // 判定方法の修正
  // url文字列の書き換え
  var newUrl = url.replace('http:', 'https:'); // 書き換え方法の修正

  // リダイレクト
  location.replace(newUrl);
}
```

これでうまく行った。めでたしめでたし

# まとめ
- 書き換え後の文字列に、書き換え前の文字列がまるごと含まれている場合、判定・置換方法を注意しなければならない
小ネタ／Aurora Serverlessを触って気づいたこと

 * **[小ネタ／Aurora Serverlessのバッファプール（バッファキャッシュ）の動きを見てみた](https://qiita.com/hmatsu47/items/aed57af5d72e4f5a00c6)**

の続きです。
この検証をしていて気づいたことをいくつか挙げてみます。

※Aurora Serverless GA 化については、こちらで紹介されています。

 * **[Aurora Serverless MySQL の一般利用が開始](https://aws.amazon.com/jp/blogs/news/aurora-serverless-ga/)（Amazon Web Services ブログ／Randall Hunt さん）**
 * **[Aurora Serverlessが一般利用可能になったので試してみた](https://dev.classmethod.jp/cloud/aws/aurora-serverless-mysql-generally-available/)（Developers.IO／大栗さん）**

# 一時停止→復帰・スケールが生じるとバッファプール（バッファキャッシュ）が初期化される

[先の記事](https://qiita.com/hmatsu47/items/aed57af5d72e4f5a00c6)に書きました。

（一時停止後復帰のほうは別として）スケール時に初期化されるのは仕組み上仕方がないと思いますが、スケールアップ型をやめて（同一リージョンマルチマスタ Aurora の技術を使って）スケールアウト型に変えれば何とかなる…かも？（メモリの退避は必要ですが）。
但し、1 インスタンスが 2 キャパシティユニット（メモリ 4GB）だと、1 インスタンス当たりのバッファプール（バッファキャッシュ）が小さくなりすぎて効率が悪そう…。

# 有効なパラメータグループ項目が少ない

これは、先に挙げた 2 つの記事にも触れられているのですが、**これを書いている 2018/08/23 現在**、キャラクタセット・照合順序・タイムゾーンなどごく一部の DB クラスターのパラメータグループ以外の指定は無効です。
DB のパラメータグループは指定すること自体できません。

これによる影響はかなり広範囲にわたりますが、例えば、以下のようなものがあります。

## バイナリログが出力できない

バイナリログのフォーマットも ON / OFF も指定できません。
結果、外部の MySQL にレプリケーションができません。

## `innodb_file_format`・`innodb_large_prefix`が指定できない

デフォルトで`innodb_file_per_table`は`ON`ですが、`innodb_file_format`は`Antelope`、`innodb_large_prefix`は`OFF`がデフォルトです。
結果、長いインデックスを付けられないなどの制約が生じています。

※上記項目とインデックス長の関係については、以下の記事を参照してください。

 * **[第32回　InnoDBインデックスの最大キー長について](https://gihyo.jp/dev/serial/01/mysql-road-construction-news/0032)（MySQL道普請便り／北川健太郎さん）**

# クライアントから接続している（コネクションが張られている）間は一時停止（pause）しない

コネクションプーリングを使っていると、普通に止まらない Aurora になってしまう可能性が高いので、一時停止（pause）させたい場合はコネクションプーリングを使わないようにしたほうが良いでしょう。
なお、コネクションが張られている状態でも、スケールイン／アウトは実行されます。

# デフォルト設定で負荷が低い状態が約 15 分続くとスケールイン（キャパシティユニットが減少）する

設定によってこの時間が変化するかどうかは未検証です。

---

# 個人的な感想など

色々と制約があるため、自社の開発環境として使うにはまだ難しそうです。
復帰（resume）やスケールに 10 ～ 30 秒掛かってしまうのも若干気になるところ。さすがに瞬時にはならないと思いますが、5 秒程度になればコネクションタイムアウトに引っかかりにくくなるでしょうし、もう少し利用シーンが増えるでしょうね。

今後の展開に期待、です（プレビュー発表当初に「コレ使えねぇ」と酷評されていたことを考えると、現状でも意外とマトモな気はしますが）。

---

 * **[Qiitaに投稿したAmazon Aurora関連記事](https://hmatsu47.hatenablog.com/aurora)**
phpでswitch文の「switch($hoge)★ここ★{case0:」に改行いれるとエラーになる。


## いきなりですが質問です、下記コードはphpで動作するでしょうか？

ひどいコードですが、ご了承ください。。汗

```php:gomennasaicode.php

<?php
$i = 0;
?>

<?php
switch($i){
?>
<?php
 case 0:
?>
<p>aaa</a>

<?php
break;
}

```

はい、これは動作します。

``` aaa ```
と表示される。


## では、こちらはどうでしょうか？

```php:gomennasaicode.php

<?php
$i = 0;
?>

<?php
switch($i){
?>

<?php
 case 0:
?>
<p>aaa</a>

<?php
break;
}

```

。。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37406/88a8368e-8d14-5b79-6bb5-0df41187b054.png)



```:エラー内容
PHP Parse error:  syntax error, unexpected '', expecting case (T_CASE) or default (T_DEFAULT) or '}' in /usr/share/nginx/〜/a.php on line 9
```


普通にswitch文書いていれば気づかないかもしれませんが、
phpとhtmlをごちゃまぜベタ書きしているとぶちあたる可能性が。。汗


<?php
switch($i){
?>
**★★ここに改行が入っているか入っていないかで、エラーでページが表示されない！！**
<?php
 case 0:
?>


### 差分はこんな感じ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37406/0109a45d-db01-f0fa-7841-3a05ae0daa48.png)



長年PHPさわっていますが、このエラーは初めてかも


>ためした環境 PHP 7.0.3
JavaScript でカンタンおみくじを作ってみる

# 目的
・JavaScriptを使っておみくじを作って飲み会における確率操作をしたい

#ゴール
・JavaScriptでの文法超基礎を理解する
・ランダムな数値を出して、それをもとに表示を変える


こんな感じの超簡易的おみくじ
![omikuji.gif](https://qiita-image-store.s3.amazonaws.com/0/202968/becfd159-0c8a-06d2-dc62-92e6655a8a5e.gif)

#コード
``` html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>おみくじ</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id = "btn">push!</div>
  <script src=main.js></script>
</body>
</html>
```

```css:style.css
@charset "utf-8";

body{
  background-color: #efefef;
}

#btn{
  margin:30px auto;
  width:200px;
  height:200px;
  border-radius: 50%;
  background:#EF454A;
  text-align: center;
  line-height:200px;
  color:#fff;
  font-size:42px;
  font-weight: bold;
  cursor:pointer;
  opacity:0.9;
  box-shadow:0 10px 0 #D1483E;
  border:3px solid #D1483E;
  user-select: none;
}

#btn:hover{
  opacity:1;
}

#btn.pushed{
  margin-top:36px;
  box-shadow:0 4px 0 #D1483E;
}

```

```JavaScript:main.js
(function(){
  'use strict';

  var btn = document.getElementById('btn');

  btn.addEventListener('click', function(){
    var n = Math.random()
    if(n < 0.3){
      this.textContent = '大吉'; // 30%
    }else if (n < 0.45){
      this.textContent = '吉';  // 15%
    }else if (n < 0.60){
      this.textContent = '中吉';  // 15%
    }else if (n < 0.85){
      this.textContent = '小吉';  // 15%
    }else{
      this.textContent = '凶';  // 15%
    }
    
  });
  btn.addEventListener('mousedown', function(){
    this.className = 'pushed';
  });
  btn.addEventListener('mouseup', function(){
    this.className = '';
  });
})();

```

##カンタンな解説
```html:index.html
  <div id = "btn">push!</div>
```
```JavaScript:main.js
  var btn = document.getElementById('btn');
```

htmlのbtnに対して、main.jsでbtnという変数を設定する。


```JavaScript:main.js
  btn.addEventListener('click', function(){
   //この中にボタンをクリックした時の動きを記述する
  }
```
btnをクリックした時の動きを記述する。
動きとしては、0-1の間でランダムに生成される数のうち偏りを表示の基準とする。
つまり、
(前提)
・0~1までのランダムな数値が入る
(条件)
・0-0.3の間：「大吉」 →30%
・0.3-0.45の間：「吉」 →15%
・0.45-0.6の間：「中吉」 →15%
・0.6-0.75の間：「小吉」 →15%
・0.75-1の間：「凶」 →約25%(※)

(※)約としたのは、Math.random()の場合0から1を含まない間の数がランダムに生成されるため。よって厳密にはぴったり25%ではない。

これを記述すると以下のようになる。

```JavaScript:main.js
  btn.addEventListener('click', function(){
    var n = Math.random();
    if(n < 0.3){
      this.textContent = '大吉'; // 30%
    }else if (n < 0.45){
      this.textContent = '吉';  // 15%
    }else if (n < 0.60){
      this.textContent = '中吉';  // 15%
    }else if (n < 0.75){
      this.textContent = '小吉';  // 15%
    }else{
      this.textContent = '凶';  // 25%
    }
```
テキスト要素の先頭行だけline-heightを取り除き、上ぴったりに揃えるスタイルシートのテクニック

##考え方

1.テキスト要素の全高（文字の高さ+上スペース+下スペース）は、line-heightにfont-sizeを掛けたものに等しくなります。
2.文字の高さはfont-sizeと等しい（近似値）と仮定します



![2018082003.png](https://qiita-image-store.s3.amazonaws.com/0/239855/dc1e4fdd-9d49-1cf1-8bc4-dbdf6b9f5837.png)
<font color="DarkGreen">■</font>グリーン: font-size、<font color="DarkOrange">■</font>オレンジ: font-sizeとline-height、■ブラック: 上スペース



先頭行だけを上に揃えるには、テキストのブロックからline-heightで加えられた上部のスペースだけを取り除けば実現できます。

#SASS

```
@mixin lhCrop($line-height) {
  &::before {
    content: '';
    display: block;
    height: 0;
    width: 0;
    margin-top: calc((1 - #{$line-height}) * 0.5em);
  }
}
```

適用するテキスト要素に上記を含め、Mixinの引数としてline-heightの値を渡します。

```
.text-to-crop {
  @include lhCrop(1.2); //line-height: 1.2
}
```

[demo](https://codepen.io/anon/pen/RYPxJx)

このルールは、使用するフォントによって異なります。例えばRobotoの文字の高さだと、font-sizeの75%になります。使用するフォントに合わせて、値をカスタマイズして利用してください。

```
margin-top: calc((0.75 - line-height) * 0.5em)
```


変数を利用すると使い勝手がよくなります。

```
@mixin lhCrop($line-height, $capital-letter) {
  &::before {
    content: '';
    display: block;
    height: 0;
    width: 0;
    margin-top: calc((#{$capital-letter} - #{$line-height}) * 0.5em);
  }
}

.text-to-crop {
  @include lhCrop(1.2, 0.75);
}
```

日本語でも数値を変えれば利用可能です。
[demo](https://codepen.io/anon/pen/QVbaeX)
chrome devtools 小ネタいくつか

## jQueryが入っていなくても$$で同じことができる

`$$('.foo')`, `$$('#bar')`, `$$('tagName')`で同等のことができる
（$が2個であることに注意）

ただし、
* `$('selector')`は`document.querySelector()`
* `$$('selector')`は`document.querySelectorAll()`
を呼ぶことと、それぞれ似た様子。しかも`$$('selector')`だと配列を返す


## イベント発生を監視してログ出力

- `monitorEvents($('selector'))`で全てのイベントを監視
- `monitorEvents($('selector'),'eventName')`で指定のイベントを監視
- `monitorEvents($('selector'),['eventName1','eventName3',….])`で複数のイベントを指定
- `unmonitorEvents($('selector'))`で監視解除


## オブジェクトの配列の場合はconsole.logよりconsole.tableの方がよさげ
```
const myArray=[
  {a:1,b:2,c:3},
  {a:1,b:2,c:3,d:4},
  {k:11,f:22},
  {a:1,b:2,c:3}
]
```

console.table(myArray)とすると

![スクリーンショット 2018-08-23 10.17.04.png](https://qiita-image-store.s3.amazonaws.com/0/30278/3dc953a1-f806-9420-728c-d1f54a6eec70.png)

こんな感じになるので、わかりやすくなる。

## Sourcesタブで表示しているJSコードのうち、任意のコードをConsoleで実行することができる

1. SourcesタブでJavaScriptコードを表示する
2. 実行したい箇所のコードを選択する
3. 右クリックしてメニューを表示し、`Evaluate in console`を選択する
![スクリーンショット 2018-08-23 12.04.55.png](https://qiita-image-store.s3.amazonaws.com/0/30278/ecab55f3-4e36-15de-ee3a-6f90f98a636c.png)

4. Consoleでコードが実行される
![スクリーンショット 2018-08-23 12.05.20.png](https://qiita-image-store.s3.amazonaws.com/0/30278/3079805c-26d9-3788-c716-4c7d96d2128f.png)
はじめての自作キーボード ビルドログ 20180819

なにかのきっかけでPlanckをみて作ろう！って思ったけど、勢いが減衰して寝かせてた。
最近自作キーボードが盛り上がってるからと思うけど勢いが復活。材料は揃ってたので一気に手配線を完了。

## 材料
- キースイッチ：3600円 アマゾンで中華青軸キーボードを買ってスイッチをはぎ取り。
- フレーム：2600円 ミストラルで切ってもらった。
- tenssyLC：2300円 スイッチサイエンスで購入。
- 10mm/M2ポスト：480円 アマゾンで購入。
- M2ねじ：？円 近くのホムセンで購入。 ※たぶんアマゾンで見つからなかった
- ダイオード：？円 aitendoで購入。 ※たぶん何かのついでに買ってと思う。
- 配線材etc：手持ち

## プレート作成
KLEでキー配列を作成して、できた配列を使ってswillkbでプレート画像データを作成
できた画像データをミストラルさんに入稿して作成完了を待つ。
http://www.keyboard-layout-editor.com/#/
http://builder.swillkb.com/
http://www.mistral.co.jp/

## キースイッチはぎ取り
開始したのが2016年後半の様だったので、適当な金額でスイッチが確保できるのが剥ぎ取りだったと思われる。でも今だったら間違えなくスイッチを購入してると思う。
で、104キーをはぎ取った後にテスターで導通確認。

## ファーム焼き
なんでteensyLCにしたかが謎だけど、たぶんコンパイル環境が理解できたのがteensyだったのかなと。どうやって環境を作ったのかは忘れてしまったけど、今使っているVirtualBoxにUBUNTUでファームビルド環境を作ってた。

で、出来上がったファームをWindows環境にもっていってteensyLCにファームを焼くが、GUIがあるので楽ちんポン。焼けた後はキーマトリクスを見てキー入力ができるかを確認。

https://github.com/di0ib/tmk_keyboard/tree/master/keyboard/teensy_lc_planck

※以降1.5年くらい放置…

## 配線
プレートにキースイッチを刺すが、すぽすぽだったんでグリューで固めちゃう。
その後ダイオードをつけてスイッチ間配線をして、teensyLCにも配線して無事完了。

この時点で導通確認をしてすべてのキーがタイプできるか確認しないと、グルーで固めたキーは取りにくいので注意。※体験済み※

## 仕上げ
プレートと底板をねじ止めして、中華キーボードのキーキャップをつけてとりあえず完成。USBポートは磁石式のやつにしておかないとモゲるみたいなので、手持ちのやつを使って対応。

まずはデフォルトのキー配列を使って変えたいところが出てくるので、適時変更してビルド→焼きこみを繰り返していい感じの配列を目指す感じ。

## 雑感
はじめてにしては良くできたと自画自賛。
PCB使ったほうがスマートな気がするけど、手配線でも悪くないかな。
でもマイコンはpico microだな。

## 手配線の参照
https://imgur.com/a/Qbbmb#hQHdm76
http://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/
https://imgur.com/gallery/WyWqV
https://geekhack.org/index.php?topic=94258.0

![CollageMaker_20180815_235808966.jpg](https://qiita-image-store.s3.amazonaws.com/0/283328/fc47acc8-32ac-da0d-9e57-4c0a5e685bdc.jpeg)
RxSwift UITableViewCell上に配置したボタンの動作

## UITableView上に配置したボタンの動作がおかしい場合
反応しない、二重に処理が走ってしまうなど

#### disposedするDisposeBagオブジェクトをセル内で生成したものを利用する
大抵これで解決します。
disposeBagオブジェクトはセルの再利用のたびに新しく生成する必要があります。

セル側の例

```swift
class MyTableViewCell: UITableViewCell {
   @IBOutlet weak var replyButton: UIButton!
   var disposeBag = DisposeBag()
   
    override func prepareForReuse() {
        super.prepareForReuse()
        self.disposeBag = DisposeBag() // ここで毎回生成
    }
```

ビューコントローラー側

```swift
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView .dequeueReusableCell(withIdentifier: String(describing: MyTableViewCell.self), for: indexPath) as! MyTableViewCell

        cell.talkButton.rx.tap.asDriver().drive(onNext: { [weak self] _ in
            // タップ時の処理
        }).disposed(by: cell.disposeBag) // セルで生成したDisposeBagオブジェクト
    return cell
   }
```
iPhone 5s 10.3.2をCydia Eraserで入獄。

## Cydia Eraserで入獄。
g0blinで脱獄したiPhone5sのiOS10.3.2をCydia Eraserで入獄しました。

***
## 必要なもの
+ Cydia Eraser
+ Filza File Manager

***
## 準備
Cydia Eraser 0.9.43をインストールしても起動しないので、下記の手順で起動できるようにします。

1. “Eraser_”を検索して削除する。(/Applications/Eraser.app/)
1. “Eraser”を“Eraser_”にリネームする。
1. 再起動
1. 再脱獄（Eraserは脱獄アプリなので）


***
## 入獄
Cydia Eraserを起動して一番下の［<font color=red>erase all data, unjailbreak device</font>］をタップします。
確認アラートが表示されるので［<font color=blue>Erase All</font>］をタップします。
あとは何もしないで待つだけです。
完了するとiOSのバージョンを維持したまま入獄状態になります。


***
## ERROR
エラーが発生した時の対処法のメモ。

### CPP1263
ターミナルで以下のコマンド`mkdir /var/stash`でディレクトリを作成するといいようですが、Filzaがインストールされてたので`/var/stash/`を作成したらエラーが回避できました。

#### 参考
[How to Fix Those Common Errors in Cydia Eraser? - 3uTools](https://www.3u.com/tutorial/articles/6957/how-to-fix-those-common-errors-in-cydia-eraser)
brew upgrade で mysql 8.0 にしてしまって bundle install で mysql2 でコケた時の話

## bundle install できない...
迂闊に `brew update` してしまい
bundle install するとこんなエラー吐かれた

```
Installing mysql2 0.4.4 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

:
:
:

An error occurred while installing mysql2 (0.4.4), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.4.4'` succeeds before bundling.
```

## バージョン確認する
```
mysql --version

# mysql  Ver 14.14 Distrib 8.0.xx, ...
```
8.0じゃぁ-ん


## 完全にMySQLを消し去る
[MacでMySQL5.7をアンインストールする](https://qiita.com/sato11/items/ba887a5655217f60f2a2)

を参考にアンインストール（ありがとうございます）

### 実際に打ったコマンド（コピペ面倒だったので $は省略してます）

```
brew remove mysql
brew cleanup
sudo rm /usr/local/mysql
sudo rm -rf /usr/local/var/mysql
sudo rm -rf /usr/local/mysql*
sudo rm ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
sudo rm -rf /Library/StartupItems/MySQLCOM
sudo rm -rf /Library/PreferencePanes/My*
launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
rm -rf ~/Library/PreferencePanes/My*
sudo rm -rf /Library/Receipts/mysql*
sudo rm -rf /Library/Receipts/MySQL*
sudo rm -rf /private/var/db/receipts/*mysql*
```

### ※STOP:  ここで一旦PC再起動してください！！！
### ...本当に再起動しましたか？
### 再起動したら次へ👍


## コマンドが使えないことを確認

```
mysql -v

# mysql: command not found
```

## mysql 5.7をインストール
```
brew install mysql@5.7
```

## パスを通す
```
echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
```

## バージョン確認

```
mysql --version

# mysql  Ver 14.14 Distrib 5.7.20, ...
```

よくできました！
mongodbでコレクションごとのレコード数を表示

mongodbでコレクションの一覧を取得し、コレクションのレコード数を表示させるクエリは以下になります。

```sql
db.getCollectionNames().forEach(function(n){print(n + ':' + db[n].find().count())})
```

上記の応用で、コレクションごとのストレージサイズを表示させるには以下になります。

```sql
db.getCollectionNames().forEach(function(n){print(n + ':' + db[n].stats().storageSize)})
```
kubectx/kubensにinteractive modeが追加されたよ

# はじめに
Kubernetesクラスタ自体の切り替えや、クラスタ内部のNamespaceの切り替えで活躍する`kubectx`と`kubens`ですが、
この度Interactive Modeが追加されました！

# デモ
![tty.gif](https://qiita-image-store.s3.amazonaws.com/0/116002/4947eda7-eea4-9fd2-2128-fb5b265ac2ad.gif)

# インストール

## kubectx/kubensのインストール
```
sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens
```

## fzfのインストール
Interactive Modeは内部でfzfを利用しているため、fzfをインストールします。
https://github.com/junegunn/fzf-bin/releases
にバイナリがあるので、ダウンロードしてPATHが通るところに配置してください。


# Interactive Modeの仕組み
kubectxの中身を覗いたところ、main処理の先頭でfzfがあるかどうかで分岐をさせているようです。

```bash
# main
# 略
if [[ -t 1 && "$(type fzf &>/dev/null; echo $?)" -eq 0 ]]; then
  choose_context_interactive
else
  list_contexts
fi
# 略
```

fzfがある場合は、下記のchoose_context_interactiveでInteractive Modeに。

```bash
# choose_context_interactive
choose_context_interactive() {
  local choice
  choice="$(FZF_DEFAULT_COMMAND='kubectx' fzf --ansi || true)"
  if [[ -z "${choice}" ]]; then
    echo 2>&1 "error: you did not choose any of the options"
    exit 1
  else
    set_context "${choice}"
  fi
}

```

それではよきk8sライフを！
TBDとかTBAとかWIPとかのチートシート

# よくわからなかったので列挙

* よくわからずに書いてしまうことが多かったので、ここで一旦頭を整理しておくことにした
* これらの略称は、作業や返事のステータスの略称として書かれる

## TBA

* `To Be Announced` の略
* 「追って連絡する」

## TBC

* `To Be Confirmed`の略
  * あくまでも、東京ビューティーセンターの略ではない
* 「だいたい決定事項だが、目下(最終)確認中」

## TBD

* `To Be Determined`の略
* 「現在未決定だが、将来決定する」

## WIP

* `Work in Progress` の略
* 「現在作業中」

# 参考

* [英語の資料に出てくる（TBC）や （TBD）は何の略？](https://www.quicktranslate.com/blog/2013/11/%E8%8B%B1%E8%AA%9E%E3%81%AE%E8%B3%87%E6%96%99%E3%81%AB%E5%87%BA%E3%81%A6%E3%81%8F%E3%82%8B%EF%BC%88tbc%EF%BC%89%E3%82%84-%EF%BC%88tbd%EF%BC%89%E3%81%AF%E4%BD%95%E3%81%AE%E7%95%A5%EF%BC%9F/)
* [TBAとTBD、TBCの違いがどうしても覚えられないのでメモ](http://hase0831.hatenablog.jp/entry/2015/09/14/210000)
* [TBA、TBD、TBCの意味と違いについて](http://www.toishi.info/email/tba_tbd_tbc.html)
Apple Pagesのユーザテンプレートの場所

- Pagesのユーザテンプレートが置かれるディレクトリはバージョンによって異なる。
- Pages 7 では以下のディレクトリ。

`~/Library/Containers/com.apple.iWork.Pages/Data/Library/Application Support/User Templates/`

- 以前の Pages（iWorkの一部だったころ）では以下のディレクトリ。
`~/Library/Application Support/iWork/Pages/テンプレート/マイテンプレート/`

- バージョンアップする際、旧バージョンのユーザテンプレートは引き継がれないようす。
【Unity】～SIerからゲーム業界へ～ 第3回 個人開発で終わらせないために

ゲーム業界への転職が目的なので
個人での開発ではなく、複数人での開発や保守性、拡張性も意識しなければならないと思います。

今までの経験 + ネットでの事例を参考に徐々に実装していきます。
今後の実装予定のメモも兼ねて、随時更新予定です。

##画面に開発情報を表示
開発者に必要な各種情報を見える化
とりあえずは画面に表示

**今後の予定**
・デバッグモードかどうかを設定ファイルで保持
　デバッグモード時のみ表示する
・画面に表示するだけではなく、どこかにログとして落としたい
　かつ、画面情報もキャプチャして落とすような仕組みにしたい

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/582c2935-350e-3018-af3c-b6b0018d80a1.png)

```C#
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class DebugDisplayLog : MonoBehaviour
{
    static public List<string> displayLog = new List<string>();

    private void Start()
    {
        this.oneSecondTime = 0f;
    }

    private void Update()
    {
        // FPS
        if (this.oneSecondTime >= 1f)
        {
            this.fps = this.fpsCounter;
            this.fixedFps = this.fixedFpsCounter;

            // reset
            this.fpsCounter = 0;
            this.fixedFpsCounter = 0;
            this.oneSecondTime = 0f;
        }
        else
        {

            this.fpsCounter++;
            this.oneSecondTime += Time.deltaTime;
        }

        // structure debug string
        this.debugString = "";
        int count = DebugDisplayLog.displayLog.Count;

        for (int i = 0; i < DebugDisplayLog.displayLog.Count; i++)
        {
            this.debugString += DebugDisplayLog.displayLog[i];
            this.debugString += "\n";
        }
        DebugDisplayLog.displayLog.Clear();
    }

    private void FixedUpdate()
    {
        this.fixedFpsCounter++;
    }

    private void OnGUI()
    {
        GUI.Label(
            new Rect(0f, 0f, Screen.width, Screen.height),
            "FPS: " + this.fps + "  FixedUpdate: " + this.fixedFps + "\n" + this.debugString);
    }

    // FPS
    private int fps;
    private int fpsCounter;

    // Fixed FPS
    private int fixedFps;
    private int fixedFpsCounter;

    // Debug Log
    private string debugString;

    // Timer
    private float oneSecondTime;
}
```

##MonoBehaviourを継承
独自処理を実装しやすいように、ベースとなるMonoBehaviourを作成する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/2d697d5a-2ab2-d96e-5048-fa602e3e383f.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/749b8b4e-0835-606c-a92d-dbe121e533d3.png)

##今後の実装予定機能
- 他言語対応

テキスト表示するようなときがあれば、コードで書くのではなく別途ファイルで作成
別の言語にも容易に対応できるよう、日本語の場合だけでも言語コードもキーとして持たせる

- 敵の設定情報など各種情報の外部ファイル化

コードの中で直接書かない。
エクセル、CSV、XMLあたりのファイルで持たせればいい？よく使われる適切な形式はこれから探す
→ **ScriptableObject を使って設定クラスを作成する**

- デバッグモードを実装する

自分が無敵になる、敵がいなくなる、等のデバッグしやすい仕組みを事前に作成する

- ドキュメントの作成

どの処理がどこに実装されてあるかなど、ドキュメントを作成する
その場合、フォルダ名とファイル名を工夫して容易に特定できるように意識する
シェル — BSD版のsedでテキストを改行「に」置換をする方法

過去にも何度かハマったが、その頃はBSDやGNUの違いがあるということも知らず、なんとなくの理解で終わってた案件。

## 結論

使えるならGNU版を使おう。

## GNUの例

```
echo 'A:B:C' | sed 's/:/\n/g'
A
B
C
```

何の不思議もなく直感的に使える。

---

- sed (GNU sed) 4.4
- docker run --interactive --tty ubuntu /bin/bash

## BSD版

こんな風に書かないといけないっぽい。

```
echo 'A:B:C' | sed 's/:/\
/g'

A
B
C
```

または

```
echo 'A:B:C' | sed -e 's/:/\'$'\n/g'
A
B
C
```

嘘だろ。

`'$'` の記号の意味も知らないし、調べたいとも思わないぐらい。

---

- Mac OS X High Sierra
- GNU bash, version 4.4.0(1)-release (x86_64-apple-darwin15.6.0)

### BSDの他のコマンド例

以下の書き方はどれも期待しない結果。

```
echo 'A:B:C' | sed -e 's/:/\n/g'
AnBnC
echo 'A:B:C' | sed 's/:/\n/g'
AnBnC
echo 'A:B:C' | sed 's/:/\\n/g'
A\nB\nC
echo 'A:B:C' | sed 's/:/\r/g'
ArBrC
echo 'A:B:C' | sed 's/:/\\r/g'
A\rB\rC
echo 'A:B:C' | sed "s/:/\n/g"
AnBnC
echo 'A:B:C' | sed "s/:/\\n/g"
AnBnC
echo 'A:B:C' | sed "s/:/\\r/g"
ArBrC
echo 'A:B:C' | sed "s/:/\r/g"
ArBrC
echo 'A:B:C' | sed "s/:/\r\n/g"
ArnBrnC
echo 'A:B:C' | sed "s/:/\\r\\n/g"
ArnBrnC
echo 'A:B:C' | sed "s/:/\\\r\\\n/g"
A\r\nB\r\nC
```

## あわせて読みたい？

- [シェルでコマンドがBSD版かGNU版かを見分けるお手軽な方法 - Qiita](https://qiita.com/YumaInaura/items/c332966d8d1d8810e97a)

## Ref


- [Shell — How to detect some command using GNU or BSD ? ( man sed | grep GNU )](https://gist.github.com/YumaInaura/5c717da2184e5efecd303b8bc4eadd51)
- [regex - How do I use a new-line replacement in a BSD sed? - Stack Overflow](https://stackoverflow.com/questions/1421478/how-do-i-use-a-new-line-replacement-in-a-bsd-sed)

## Links

- [Gist](https://gist.github.com/YumaInaura/0763a99557f66634ae6ca0c9f27cc464)
- [Medium—imported](https://medium.com/supersonic-generation/shell-how-to-detect-command-is-gnu-or-bsd-man-sed-grep-gnu-5b60cc818a6a)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Git commit 取り消したい

# まとめ

- `reset` : 作業を取り消す
- `revert` : commit を打ち消すための commit をうつ

# `reset`

## 直前の commit を index に戻す

```bash
git reset --soft HEAD~
```

## ファイル変更と add と直前の commit を取り消す

```bash
git reset --hard HEAD~
```

ファイル変更と add と特定の commit を消し去る⚡️
間違えたことを歴史から消し去りたい場合に行う
`HEAD` は、 commit hash の値でもOK
ref. [\[git reset \(\-\-hard/\-\-soft\)\]ワーキングツリー、インデックス、HEADを使いこなす方法 \- Qiita](https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe)

## add したファイルを index から working directory に戻す(add を取り消す)

```bash
git reset
```

## やべ！ `reset --hard` 間違えてしちゃった！！

```bash
$ git reflog
019c3d2a (HEAD -> feature/fix-validation, origin/feature/fix-validation) HEAD@{0}: commit: remove
7e01141b (origin/develop, develop) HEAD@{1}: checkout: moving from develop to feature/fix-validation
7e01141b (origin/develop, develop) HEAD@{2}: pull: Fast-forward
...
$ git reset --hard HEAD@{1}
```

ref. [\`git reflog\` についてまとめてみる](https://gist.github.com/kymmt90/9c997726b638b316f9be07aa4e3eea5e)


# `revert`

特定の commit を打ち消す内容の commit をする
間違えた commit も歴史として残る
間違えたことを歴史として残したい場合に行う
`HEAD` は、 commit hash でもOK

## 直前を打ち消す commit をする

```bash
git revert HEAD
```

## 2つ前の commit だけを打ち消す commit をする

conflict する可能性がある

```bash
git revert HEAD~1
```

## 範囲を指定して打ち消す commit をする

```bash
git revert HEAD~7...HEAD
```

## `revert` をやり直したい

conflict などして、revert に失敗
再度 revert をやり直したい時

```bash
git revert --abort
```
【Unity】～SIerからゲーム業界へ～ 第2回 ショートカット

Unityの勉強を始めた上で意識しているのは
効率の良い作業方法を最初のうちから身に着けること。

学んだショートカットをここに追記していきます。

##Scene
- [Q] [W] [E] [R] [T] [Y]

各種ツールの切り替えが可能
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/1a1895d2-9c3a-3f82-c5fd-4ce23ade1eab.png)

- [Ctrl] + [Q] or [E] or [A] or [D]

画面の平行移動
Shiftを同時押しすることでスピードアップ

##VisualStudio
- [Ctrl] + [K] + [F]

選択範囲のソースコードの成形
組織での開発を目指すなら見やすさは大切
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/99458978-3f9d-987f-4019-5a013b57b993.png)
Implement onurlchange Event

Even if modifying build-in functions isn't good hack...

```javascript
function insertOnUrlChange(parent, funcname) {
    let oldFunc = parent[funcname] ? parent[funcname] : function (){}
    parent[funcname] = function() {
        oldFunc.apply(this, arguments)
        return window.onurlchange()
    }
}

insertOnUrlChange(window.history, "pushState")
insertOnUrlChange(window.history, "replaceState")

window.onurlchange = function() {
    doSomething()
}

window.history.pushState(null, null, "/hoge#foo=bar") // doSomething()
```