OmniAICreator/Qiita-1.07M huggingface dataset:
Next.js 9 Error: Module did not self-register への対応

Next.js 9で発生する下記のようなやつ

```
{ Error: Module did not self-register.
    at Object.Module._extensions..node (internal/modules/cjs/loader.js:807:18)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/root/project/node_modules/grpc/src/grpc_extension.js:32:13)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32) type: 'Error', '$error': '$error' }
```

「v9.0.4-canary.3」で修正されているようなので、自分は一旦canaryにあげて対応してます。

## 参考サイト等
[`next build` fails with "Module did not self-register." #7894](https://github.com/zeit/next.js/issues/7894)
[Remove cache clearing from static-checker #8290](https://github.com/zeit/next.js/pull/8290)
[The gRPC binary module was not installed. This may be fixed by running "npm rebuild" #7821](https://github.com/zeit/next.js/issues/7821)
Vue基礎：Vuexの永続化対応

Vuexのステートデータを永続化対応しないと、F5とかページreloads操作でデータはなくなります。
一般的に永続化の対応が必要だと思います。

ツールとして、「vuex-persistedstate」がよく使います。

#vuex-persistedstateとは
Persist and rehydrate your Vuex state between page reloads.

#インストール
`npm install --save vuex-persistedstate`

#storeに設定追加
```javascript
import createPersistedState from 'vuex-persistedstate'

const store = new Vuex.Store({
  // ...
  plugins: [createPersistedState()],
})
```

#ストレージの種類
###1. LocalStorage
デフォルトのストレージはlocalstorageです。

###2. SessionStorage

```javascript
import createPersistedState from 'vuex-persistedstate'

const store = new Vuex.Store({
  // ...
  plugins: [createPersistedState({ storage: window.sessionStorage })],
})
```

###3. Cookies
cookieに保存したい場合は、カスタマイズが必要です。
getItem、setItem、removeItemを実装すればよいです。
下記はCookieに保存するサンプルです。

```javascript
import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'

const store = new Store({
  // ...
  plugins: [
    createPersistedState({
      storage: {
        getItem: key => Cookies.get(key),
        setItem: (key, value) =>
          Cookies.set(key, value, { expires: 7, secure: true }), //7日間有効
        removeItem: key => Cookies.remove(key),
      },
    }),
  ],
})
```

js-cookies: https://github.com/js-cookie/js-cookie
vuex-persistedstate：https://github.com/robinvdvleuten/vuex-persistedstate

以上
[memo]shellでAWS S3にログデータを定期に同期させる実行

## 承前
今までPHPのバックエンドしかやってこなかった人間が初めてShell Scriptに挑戦した記録的なやつ。
AWSコマンド(AWS cli)は[事前インストール](https://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)しておいてください

## 何するの？
EC2に吐き出したログをS3バケットに同期しなきゃという使命感をもって対応する

### 何した？
EC２のlogを吐き出している場所に対して、S3にSyncをする処理を作る
同期の際は同日に反映されたファイルは上書きするていで良かったらしい（お現場事情）

```s3_sync_log_api_details.sh
#!/bin/sh
## s3_sync_log_api_details.sh $@
##

# initial parameter
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
export EC2_REGION=`curl -s http://[domain_name]/latest/meta-data/local-hostname | cut -d '.' -f2`
INSTANCE_ID=`curl -s http://[domain_name]/latest/meta-data/instance-id`
AWS_CONFIG_FILE="/root/.aws/config"

# sync detail directories
LOG_DIR="/var/log/[project_name]"

# sync s3 buckets
BUKET_NAME="s3://[s3_repository_domain]/api/log/"

# sync logging file into s3
aws s3 sync ${LOG_DIR} ${BUKET_NAME}
```
### その次は？
定期的に同期をする必要があるので設定をする必要がありますね
今回は１０分毎に同期させようという話

```crontab.conf
/10 * * * * cd /srv/www/[my_directory]/config/sync; sh ./s3_sync_log_api_details.sh
```

[時間とかの設定はこちらを参照](https://qiita.com/katsukii/items/d5f90a6e4592d1414f99)

## 感想
このときLaravelを使っていたんですがなんでAtrisanを使わなかったんでしょうねっていう感じ。

でも実はしっかりとバッチで動かすってことをしてこなかったので経験としては非常によかったです。
Swiftlintで警告を消す方法


Swiftlintを導入すると、いろいろとWarningを出してもらえるので便利な反面、
エラーが出すぎるとエディタの可視性が悪くなるので、警告を消す方法です。`swiftlint: disable 警告名`をswiftファイルのコメントに記載します。

``` swift
// swiftlint: disable type-body-length
```
js　メソッド　find,map 備忘録

#find

findメソッドとは、コールバック関数の処理部分に記述した条件式に合う1つ目の要素を配列の中から取り出すメソッドです。配列の要素がオブジェクトの場合もfindメソッドを使うことができます。

```.js
const numbers = [1,3,6,9,100]
const FoundNumber = numbers.find((number)=>{
   return number > 3;
)
console.log(FoundNumber);
//出力５=> 条件に合う最初の要素が指定される。
```

#map
mapメソッドとは、配列内のすべての要素に処理を行い、その戻り値から新しい配列を作成するメソッドです。

```.js
const numbers = [1, 2, 3, 4];

// 定数numbersにmapメソッドを使って配列を作り、定数doubledNumbersに代入してください
const doubledNumbers = numbers.map((number)=>{
  return number*2;
});

// 定数doubledNumbersを出力してください
console.log(doubledNumbers);


const names = [
  {firstName: "Kate", lastName: "Jones"},
	{firstName: "John", lastName: "Smith"},
	{firstName: "Denis", lastName: "Williams"},
	{firstName: "David", lastName: "Black"}
];

const fullNames = names.map((name)=>{
  return name.firstName + name.lastName;
});

console.log(fullNames);

```
【PBCS】ASO（集約ストレージ・オプション）- MDX式の利用その③

前回の記事はこちら：
[【PBCS】ASO（集約ストレージ・オプション）- MDX式の利用その②](https://qiita.com/iwa_gino/items/705c9481410aeecfb272)

# 主な変換例




## (5) IsUDA

・UDAのチェック を行う


（例）Accountのカレントメンバーが「UDA001」に紐づけられている場合：4月の値
　　　上記以外の場合：3月～5月の合算値


```
IIF(IsUda([Account].CurrentMember,"UDA001"), 
 [Apr],[Mar]+[Apr]+[May]
)
```

## (6) Lag

・n世代（nレベル）前のメンバーを返す（≒@PRIOR）

```
member.Lag (
n
[,
世代orレベル
] [, 
hierarchy
] )
```
        
・メンバー式の場合（例：前年実績データの取得）                

```
@PRIOR("Actual",1,@CHILDREN("Years"));
```

・MDXに変換するとこうなる

```
(Years.CurrentMember.Lag(1, LEVEL), [Actual]).Value
```

# (7) Round


```
Round ( numeric_value_expression, index )
```


numeric_value_expression：数値式
index：丸め桁数

・数値式が指定された桁数に丸められる（四捨五入）
・反対に、値を切り捨てしたい場合は「Truncate」を使用する

## BSOの場合

```
@ROUND("Member1"*100,2);
```



## ASOの場合

```
ROUND([Member1]*100,2)
```


# (8) Truncate


```
Truncate ( numeric_value_expression )
```


numeric_value_expression：数値式

## BSOの場合

```
@TRUNCATE(-8.12)
```
戻り値：-8

## ASOの場合

```
Truncate(-8.12)
```

戻り値：-8
webarenaでubuntu その17

#概要

webarenaでubuntu18.04やってみた。
postfix3.3やってみた。
mailutilsでテストしてみた。

#インストール

```
sudo apt-get install mailutils
```

#main.cfの修正

```
mydestination = hoge.com
```

#テスト

##ubuntuからubuntuへ送信 

```
mail ubuntu
```

##ubuntuから外部へ送信

```
mail hoge@honge.com
```

##外部からubuntuへ送信

メーラーでubuntu@hoge.comへ送信。

##ubuntu@hoge.comから外部へ送信 

```
mail hoge@honge.com -aFrom:ubuntu@hoge.com
```


以上。
Node.jsのgRPC Clientツール：grpc-caller

Node.jsがクライアントとしてgRPCのメソッドを呼び出したい場合は、
https://github.com/grpc/grpc-node
にてやり方を記載しておりますが、一番シンプルなClientのCallerとして、「grpc-caller」は便利だと思います。

「node-grpc-client」というツールも試しましたが、やはり「grpc-caller」ですね。

#インストール
`npm install grpc-caller`

#サンプル

```javascript
const path = require('path')
const caller = require('grpc-caller')

const PROTO_PATH = path.resolve(__dirname, './protos/cassandra.proto')
const client = caller('localhost:50051', PROTO_PATH, 'Calendar')

client.getCalendar({ calendarId: '20191010abc' }, (err, res) => {
  console.log(res)
})
```

以上
MongoDBの同期の仕組みと知っておくべき注意点

# はじめに
MongoDBでReplica Setの構成を組むと、メンバー間でデータの同期が行われます。
同期の仕組みを理解していないと、障害が発生した時の対応を誤ってしまうことがあるので、ここにまとめておきます。

# 環境
```shell:バージョン
$ mongod --version
db version v4.0.8
```

# 同期の仕組み
簡単にまとめると下記の通りです。

- Primaryで書き込みが実行されると、そのオペレーションをlocal.oplog.rsというcollectionに保存する。
- Secondaryは、Primaryからlocal.oplog.rsをコピーする。
- Secondaryは、コピーしたlocal.oplog.rsを順次実行する。

データをコピーしているのではなく、オペレーションをコピーしているというところが味噌です。

# oplogの容量制限
oplogは[capped collection](https://docs.mongodb.com/manual/core/capped-collections/)という容量に制限のあるcollectionです。
つまり、長時間のダウンでoplogが保存されている期間を過ぎた場合は、同期が不可能になってしまいます(STALE状態)。
こうなってしまうと、[Initial Sync](https://docs.mongodb.com/manual/tutorial/resync-replica-set-member/)でゼロから同期を始めなければいけなくなります。


oplogのサイズや保存されている期間は下記コマンドで確認できます。

```
PRIMARY> rs.printReplicationInfo()
configured oplog size:   2574.97265625MB
log length start to end: 11667867secs (3241.07hrs)
oplog first event time:  Wed Apr 03 2019 16:54:58 GMT+0900 (JST)
oplog last event time:   Fri Aug 16 2019 17:59:25 GMT+0900 (JST)
now:                     Fri Aug 16 2019 17:59:27 GMT+0900 (JST)
```

保存期間が短く、長時間ダウンで同期が不可能になってしまう危険性がある場合は、oplogの容量を大きくすることで対応ができます。

下記コマンドでoplogの容量を変更できます(単位はMB)。

```
PRIMARY> db.adminCommand({ replSetResizeOplog: 1, size: 3000 })
```

# lastStableCheckpointTimestamp (ver.4.0〜)
Replica Set全てが同期された最終時刻のことです。
下記コマンドで確認できます。

```
PRIMARY> db.adminCommand( { replSetGetStatus : 1 } )
〜
"lastStableCheckpointTimestamp" : Timestamp(1565946285, 1),
〜
```

Replica SetのメンバーがInitial Sync等で同期していたり、ダウンしていたりすると、この値は長時間更新されません。これは注意が必要です（詳細は下記Recoveryで）。

[lastStableCheckpointTimestamp](https://docs.mongodb.com/manual/reference/command/replSetGetStatus/#replSetGetStatus.lastStableCheckpointTimestamp)

# Recovery ※注意
Replica Setメンバーは、起動時にRecoveryが実行されます。
公式には見当たりませんでしたが、どうやらlastStableCheckpointTimestamp 〜 oplogの最終更新日までのoplogを実行しているようです。

```:起動時、Recoveryが実行された時のログ
[initandlisten] Recovering from stable timestamp: Timestamp(1565241749, 5) (top of oplog: { ts: Timestamp(1565281045, 1), t: 61 }, appliedThrough: { ts: Timestamp(0, 0), t: -1 }, TruncateAfter: Timestamp(0, 0))
[initandlisten] Starting recovery oplog application at the stable timestamp: Timestamp(1565241749, 5)
[initandlisten] Replaying stored operations from { : Timestamp(1565241749, 5) } (exclusive) to { : Timestamp(1565281045, 1) } (inclusive).
```

Initial Sync中はlastStableCheckpointTimestampが更新されておらず、その間にレプリカセットのメンバーを再起動すると、Recoveryが走り、Initial Sync開始時刻から現在までのoplogが実行され、完了するまで正常起動しないということが起きます。
データ量の多いDBだとInitial Syncに長時間かかることがあるので、その間に下手に再起動をかけると、oplog実行待ちの間サービスが停止してしまう、なんてことになりかねないので注意が必要です。
また、Secondaryがダウンしている状態で、Primaryを再起動すると、Secondaryがダウンしている期間中のoplogがPrimaryで実行されてしまいます。これも同様に注意が必要です。SecondaryがダウンしたままPrimaryを再起動したい場合は、そのSecondaryをメンバーから外しておくという操作が必要です。
Oracle18cをインストール際のフォルダ構成に関する注意点

Oracle12cまでは、ダウンロードしてきたOracle Universal Installer(OUI)を含む圧縮ファイルを任意の一時フォルダに展開し
一時フォルダからOUIを実行、Oracleホームディレクトリを指定してインストールを行った。
この場合、一時フォルダ内に展開されていた各種のツールやバイナリファイルは、Oracleホーム以下にコピーされ
インストール終了後には一時フォルダは削除するのが通例だった。

ところが、Oracle18cのインストールでは圧縮ファイルを一時的に展開するフォルダを作成する必要は無く
setup.batを実行したフォルダが、ツールやバイナリファイルを含むOracleホームフォルダとして自動で設定されてしまう。
そのためセットアップの途中で指定するべきフォルダはOracleホームではなく、インストールの情報等を保持するためのOracleベースフォルダを指定することになる。

OracleホームとOracleベースの関係は、自由な配置で指定することが可能であるが、公式のガイド(database-installation-guide-microsoft-windows.pdf)によると

以下のような設定とすることを推奨している。
>#Oracle Home Directory Naming Convention
>
>By default, Oracle Universal Installer configures Oracle home directories using these
>Oracle Optimal Flexible Architecture conventions.
>The directory pattern syntax for Oracle homes is /pm/s/u/product/v/type_[n]. The
>following table describes the variables used in this syntax:
>
>###Variable Description
>|名前|説明|
>|---|---|
>|pm|A mount point name.|
>|s|A standard directory name.|
>|u|The name of the owner of the directory.|
>|v|The version of the software.|
>|type|The type of installation. For example: Database (dbhome), Client (client),or Oracle Grid Infrastructure (grid)|
>|n|An optional counter, which enables you to install the same product morethan once in the same Oracle base directory. >For example: Database 1 and Database 2 (dbhome_1, dbhome_2)|

したがって、oraclehomeというユーザーをOracleホーム・ユーザーとして、従来通りC:\appフォルダ以下にDBをインストールする場合は C:\app\oraclehome\product\18.0.0\db_home1 に、DBのインストール用圧縮ファイルを展開し、OracleBaseにC:\app\oraclehomeを指定すればよいということである。

なお、アンインストールをする場合には、Oracleホームの下にあるdeinstallフォルダ内のdeinstall.batを実行すればよいが、実行後には当然Oracleベース以下のディレクトリは削除されることに注意しよう。
WordPressの管理画面IP制限で.htaccessが効かないのはAWS Lightsailが原因だった

##やったこと
/opt/bitnami/apps/wordpress/htdocs/.htaccessに追記

```
<FilesMatch "wp-login.php|wp-admin">
    Order deny, allow
    Deny from all
    Allow from 000.000.000.000
</FilesMatch>
```
IP制限されず・・・
題名の通り、AWS Lightsailだと.htaccessは無効になるらしい。

##解決策

1. /opt/bitnami/apps/wordpress/conf/htaccess.confに追記
2. 再起動


####追記するコードはDirectoryタグの外
htaccess.confのデフォルト

```
<Directory "/opt/bitnami/apps/wordpress/htdocs/wp-content/plugins/akismet">
   <IfModule !mod_authz_core.c>
	Order Deny,Allow
	Deny from all
   </IfModule>
   <IfModule mod_authz_core.c>
	Require all denied
   </IfModule>

   <FilesMatch "^(form\.js|akismet\.js|akismet\.css)$">
	<IfModule !mod_authz_core.c>
		Allow from all
	</IfModule>
	
	<IfModule mod_authz_core.c>
		Require all granted
	</IfModule>
   </FilesMatch>

   <FilesMatch "^logo-full-2x\.png$">
	<IfModule !mod_authz_core.c>
		Allow from all
	</IfModule>
	
	<IfModule mod_authz_core.c>
		Require all granted
	</IfModule>
   </FilesMatch>
</Directory>
```
ビギナーだけかもしれないけど、Directoryタグの中に追記したくなる。
でもそれだと効かないので外に記述する。

htaccess.confに追記

```
</Directory>

<FilesMatch "wp-login.php|wp-admin">
Order Allow,Deny
Allow from 000.000.000.000
</FilesMatch>
```

FilesMacthタグ内の記述が少し変わっているのは、前のコードだとsyntaxエラーになったから。
調べてみた

```
<FilesMatch "wp-login.php|wp-admin">  //URLにwp-login.phpとwp-adminが含まれている時
    Order deny, allow  //デフォルトで許可、拒否するかの選択。Order allow,denyに変更するとデフォルトで拒否になる
    Deny from all  //デフォルトは許可してるけど、全て拒否に変更してる
    Allow from 000.000.000.000  //指定のIPのみ許可
</FilesMatch>
```
やってることは全く同じ。前のコードのほうが無駄があるように見える。
なぜsyntaxエラーが出たのかはUbuntuが原因かなと思います。Linuxなら大丈夫なはず。

再起動

```
sudo /opt/bitnami/ctlscript.sh restart apache
```

##おまけ
FilesMatchタグ内を工夫することで、より特定したURLを指定できる。

```
<FilesMatch "^wp-login.php|wp-admin$">
```

####^wp-login.php
wp-login.phpから始まる文字列を指定。　例）aaa-wp-login.phpは除外

####wp-admin$
wp-adminで終わる文字列を指定。　例）wp-admin-aaaは除外

|  量指定子 | 説明 |
| --- | --- |
|  ^ | 行の先頭 |
|  $ | 行の末尾 |
|  . | あらゆる一文字 |
|  ＋ | １回以上の繰り返し |
|  * | ０回以上の繰り返し |
|  ? | ０回か、１回の繰り返し |
|  { n } | n 回の繰り返し |
|  { n ,} | n 回以上の繰り返し |
|  {n,m} | n 回から m 回の繰り返し |
Linuxディストリビューションまとめ(ざっくり)

どのディストロ入れるか迷ったのでまとめてみた。

# ディストリビューションとは
* 英語でDistribution
* 分布, 配布, 流通を指す言葉
* Linuxカーネルにライブラリ, ツール, ユーティリティ, サーバ/デスクトップ向けのアプリケーションを集め, パッケージとしてひとまとまりにしたもの

# ディストリビューションの流派
* RedHat系
    * 有償のRHEL(RedHat Enterprise Linux), そのクローンのCentOS, RHELの試験的な機能を盛り込んだFedora等
    * 「仕事」という言葉が似合う
* Debian系
    * 普通のPCとして使いたい場合によく使われる
    * Debianやそこから派生したUbuntu, Linux Mint等
    * ユーザフレンドリな考え方を持っている
* Slackware系
    * 公式に配布されている状態が一つの完成形となっている
    * そのため, アプリケーションの追加導入や依存関係の管理が難しい
    * 初心者向けではない
    * ただし, 安定性や安全性, 高速といったメリットを持つ
    * 老舗

# ディストリビューションの比較

### RedHat系

* RHEL
    * 有償
    * 技術的なサポート, 長期的で的確なバグフィックス
    * サポート期間は10年と長い
* CentOS
    * RHELのクローンOS
    * RHELの有償部分を取り除いたもの
    * 無償だが, RedHatのサポートは受けられない
    * 情報は豊富でトラシューしやすい
* Fedora
    * アグレッシブなディストリビューション
    * 最新の機能をどんどん取り込んでいる
    * Fedora -取り込む-> RHEL -クローン-> CentOS といった流れ
    * FedoraはRHELとCentOSとはバージョンの付け方が異なっている

### Debian系

* Debian
    * 無償でサーバを構築するならCentOS, Debian, Ubuntuの三択
* Ubuntu
    * ユーザフレンドリ
    * Debianから派生
    * Ubuntuという言葉自体が「他者への思いやり」を意味している
    * 資金面でも問題無く, この先も無償で提供することが宣言されている
    * 情報が豊富でトラブルシューティングしやすい
* Linux Mint
    * Ubuntuから派生
    * かなり簡単に使えるようになっている
* Kubuntu
    * Ubuntuのデスクトップ環境をKDEに置き換えたもの(UbuntuはGNOME)
* Xubuntu
    * Ubuntuのデスクトップ環境をXFceに置き換えたもの
* Zorin OS
    * Ubuntuから派生
    * スキンをWindows風/Mac風にできる
* Voyager Linux
    * Xubuntuから派生
    * フランス産
    * Xubuntuの高カスタマイズ版といった立ち位置
* Kali Linux
    * ペネトレーションテストを主な目的としている
    * 2011年に開発が開始されたため, 割と新しい部類
    * Debian -> SLAX(元はSlackwareベース) -> Whoppix -> BackTrack -> Kali Linux
* Tails
    * プライバシと匿名性の保護に特化している
    * Debianベース
    * The Amnesic Incognito Live System の略

### Slackware系

* Slackware
    * 最古のディストリビューション
    * シンプルで堅実
    * パッケージの依存関係等は自分で解決する必要がある
    * 初心者向けではない
* openSUSE
    * Slackware系
    * SUSE Linuxから改名
    * 様々な用途で利用できる
    * 意外と初心者向け？

### その他

* Gentoo Linux
    * 最も難易度が高いと言われるLinuxディストリビューション
    * 公式ドキュメントを見て一からインストールする
    * より細かくチューニングできる
* Arch Linux
    * 決してユーザフレンドリではないが, 開発者からみてとてもシンプル
    * コアな部分でシンプルさと使いやすさを両立
    * パワーユーザに人気
    * インストールは基本CUIでGUIを使う場合はインストール後
* Manjaro Linux
    * ArchLinuxから派生
    * ユーザフレンドリを目指してGUI環境が追加された
* Linux From Scratch(LFS)
    * 全てを自分で構築したいという人間が行き着く果て
    * システムとして最低限何があれば実用的に機能するのかが理解できる
    * 自分でディストリビューションを構築する基礎が身につく
#Rails - GrapeLogging でパスワードのパラメータをフィルタする設定例

#Rails-Configuration example for filtering password parameters with GrapeLogging


```rb
logger.formatter = GrapeLogging::Formatters::Default.new
use GrapeLogging::Middleware::RequestLogger,
  logger: logger,
  include: [
    GrapeLogging::Loggers::FilterParameters.new
  ]

```

 # ログの例 (一部)

```
"password":"[FILTERED]","password_confirmation":"[FILTERED]"
```


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2313








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Linuxが生まれるまでの変遷(ざっくり)

# IBM System/360
* OSのはじまり
* 1960年代前半から1970年代後半まで活躍
* OSという概念が登場したのは1960年代
* それまでは計算用であれば計算専用のコンピュータ, 事務処理用であれば事務処理専用のコンピュータを構築するのが一般的だったらしいが, それでは効率が悪いので, その基盤をなすOS(Operating System)という概念が生まれた

# Multics
* AT&Tベル研究所で作られた
* 多機能だったが機能を盛り込みすぎたせいでまともに使えなかった

# UNIX
* Multicsの反省を生かして開発された
* はじめはアセンブリ言語で記述されていたが, 後にC言語で書き直された
* ケン・トンプソン, デニス・リッチー, ブライアン・カーニハン等によって開発
* 1960年代後半〜1970年代に主に開発された

# GNU
* GNU’s Not Unix! の略
* GNUプロジェクトはリチャード・ストールマンによって1983年に開始される
* 1990年代初頭までにライブラリ, コンパイラ, テキストエディタ, シェル, ウィンドウシステムが完成
* しかしデバドラ, デーモン, カーネルは未完成だった
* この時点でGNU Hurd(カーネル)が完成していた場合, リーナスはLinuxを開発していなかったという

# BSD
* 派生版UNIX
* 1970年代後半から開発
* カリフォルニア大学バークレー校で開発
* しかし1984年にUNIXプロプライエタリ製品になったため, 自由に公開できなくなった
* そこでBSDからAT&Tのライセンスが必要な部分を削り92年に386BSDをリリース
* 386BSDがNetBSDやFreeBSDの祖先となる

# FreeBSD
* 元々はx86環境のサポートの充実を念頭に置いて開発がはじめられた
* macOSはFreeBSDから派生したOSである

# NetBSD
* 多くのアーキテクチャで動作させることを念頭に置いて開発がはじめられた

# OpenBSD
* NetBSDから派生
* セキュリティに注意して開発が進められている

# Solaris
* サン・マイクロシステムズ(現オラクル)によって開発されたOS
* SUS(Single UNIX Specification)というUNIXを名乗ることが許される認証を受けている
* 元々はSunOSというBSDベースのOSだったが, UNIXベースのものに書き換えられ, Solarisに改名された

# MIINIX
* アンドリュー・タネンバウムによって開発されたUNIX系OS
* コンピュータサイエンスにおけるOSの教育という目的に重点を置いた設計

# Linux
* UNIXが商用で高価であったことや, MINIXはあくまで教育用で機能が大幅にカットされていたということから開発を開始
【jQuery】一つだけ展開＋矢印も同時に動くアコーディオンの実装

jQueryを使って、アコーディオンを実装する方法について記録しておきます。
アコーディオンの条件

- 一つだけ展開し、他の要素は閉じる
- 矢印も一緒に動く

こんな感じで実装する方法です。

##一つだけ展開し、矢印も一緒に動く
<p class="codepen" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="kei_01011" data-slug-hash="RXoVyx" data-pen-title="RXoVyx">See the Pen <a href="https://codepen.io/kei_01011/pen/RXoVyx/">
RXoVyx</a> by kei (<a href="https://codepen.io/kei_01011">@kei_01011</a>)
on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

実際にクリックしていただければわかりますが、１つの要素が展開されている時には、他の要素は閉じるようになっています。




###一つの要素だけを展開する

```javascript
jQuery(function ($) {
  $(".answer").css("display", "none");
  // 質問の答えをあらかじめ非表示

  
  
  //質問をクリック
  $(".question").click(function () {
    
    $(".question").not(this).removeClass("open");
    //クリックしたquestion以外の全てのopenを取る

    $(".question").not(this).next().slideUp(300);
    //クリックされたquestion以外のanswerを閉じる
    
    $(this).toggleClass("open");
    //thisにopenクラスを付与
    
    $(this).next().slideToggle(300);
    //thisのanswerを展開、開いていれば閉じる
  
  });
});

```




` $(".question").not(this).next().slideUp(300);`でクリックした要素以外を閉じる。
`not'(this)`でクリックした要素以外を指定し、`slideUp`で隠します。



###矢印も一緒に動く

シンプルにCSSで矢印を作るパターンを実装します。
擬似要素を使って矢印を作ります。

```css
.question:after {
  content: "";
  position: absolute;
  right: 25px;
  top: 38%;
  transition: all 0.2s ease-in-out;
/*   要素の動きを指定 */
  
  display: block;
  width: 8px;
  height: 8px;
  border-top: solid 4px #000;
  border-right: solid 4px #000;
  
  -webkit-transform: rotate(135deg);
  transform: rotate(135deg);
/* transform: rotateで要素の角度を指定 */
  
}

.question.open:after {
  -webkit-transform: rotate(-45deg);
  transform: rotate(-45deg);
  top: 45%;
/*   .openクラスがついた時の要素の角度を指定 */
}

```



`.open`クラスがついたときに、`transform: rotate`で要素の角度を変更すれば、矢印も一緒に動くようになります。



JavaScriptでもjQueryでも、addClassやremoveClassを使った操作は基本だと思います。CSSを使った矢印の他に、FontAwesomeを使ったものでも応用が可能です。
【VSCode】WindowsでGo言語の開発環境を構築した

# 環境
- Windows 10
- Golang(go1.12.9)
- VS Code
- Git

# 実装
## Golangのダウンロード
https://golang.org/dl/
上記からDLしていく。

- Featured downloads
    - Microsoft Windows go1.12.9.windows-amd64.msi

を選択する。

## インストーラの進め方
ダウンロードが完了したら、インストーラが起動する。
今回はすべてチェックを変えずに、そのまま進めた。
(インストール場所もC:\Go\)

## 環境変数の設定
環境変数を編集する。
PowerShellを管理者で開き、以下のコマンド。

```
Start C:\Windows\system32\rundll32.exe sysdm.cpl, EditEnvironmentVariables
```
GOPATHとGOROOTがあることを確認したら、
ユーザー環境変数のPathを変数値:%GOPATH%\binに設定する。
また、GitのPathが通っているか確認し、通っていない場合はPathを通しておく。

次に、PowerShellを再起動させ、GoとGitのPathが通っていることを確認する。

```
go version
git --version
```
### Golangのデバッガをインストール
VS Code上でGolangのデバッグができるようにする。

```
go get -u -v github.com/derekparker/delve/cmd/dlv
```

## Golangの開発に必要な外部パッケージをインストールする。
VS Codeを開き、拡張機能のGoをインストールする。
VS Code上で、Ctrl+Shift+pでコマンドパレットを開き、GO: Install/Update toolsで検索する。
全てのツールを選択し、OKボタンをクリックしてインストールする。

正常にインストールに成功した場合、以下の表示がでる。

```
All tools successfully installed. You're ready to Go :).
```

# 終わりに
以上で、Go言語の開発環境を構築することができました。
自分がつまったところを以下に記載しましたので、よかったら参考にしてください。
[VS Code上でGolangのパッケージをインストールする時にでたエラーを解決した](https://qiita.com/ta9star/items/c793c546b002cf10e799)
VS Code上でGolangのパッケージをインストールする時にでたエラーを解決した

# 環境
- windows 10
- Golang 1.12.9
- VS Code
# 問題
VS Code上でGolangのパッケージをインストールする時に、表示されたエラーは以下。

```
//一部分のみ記載
Installing 16 tools at C:\Users\~\go\bin


  gocode

Installing github.com/mdempsky/gocode FAILED

16 tools failed to install.

gocode:
Error: Command failed: C:\Program Files\Go\bin\go.exe get -u -v github.com/mdempsky/gocode
github.com/mdempsky/gocode (download)
go: missing Git command. See https://golang.org/s/gogetcmd
package github.com/mdempsky/gocode: exec: "git": executable file not found in %PATH%
github.com/mdempsky/gocode (download)
go: missing Git command. See https://golang.org/s/gogetcmd
package github.com/mdempsky/gocode: exec: "git": executable file not found in %PATH%
```

# 解決策
エラーメッセージを読むと、

- Gitがインストールされていない
- GitのPATHが通っていない

いずれかが問題であるらしいので、コマンドプロンプトを開いて確認。

```
git --version
```
gitはインストールしてあるが認識しなかったので、PATHを通す。

Golangのパッケージのインストールを再度試し、以下の表示がでた。

```
All tools successfully installed. You're ready to Go :).
```
以上で、正常にインストールが完了した。
twurlを使ってユーザをTwitter Account Activity APIでsubscribeする

[Twitter Account Activity API](https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/overview)では、以下のURLへPOSTリクエストを送ることでイベントを購読するユーザを登録できる。

```
https://api.twitter.com/1.1/account_activity/all/dev/subscriptions.json
```

登録時しかリクエストを送らないので、わざわざコードを書くよりも[Insomnia](https://insomnia.rest/)などで送ると楽。
Twitter Appを作成した時のConsumer Key, Consumer Secret, Access Token, Access Token Secretを使ってOAuth1認証すれば良い。

が、このAPIはpayloadを何も受け付けない(Premium版のみ。Enterprise版はwebhook_idをbodyで受け取る)。購読対象のユーザはAccess Token/Secretを発行したユーザになる。
App作成時のTokenでは、Developerとして登録したTwitterアカウントのイベントを購読してしまうが、大体の場合はbot用アカウントのイベントを拾いたいため、そちらを登録する必要がある。

WebでのOAuth認証を実装すればToken発行はできるのだが、今回は一般ユーザが自由に購読できるようなものではなくbotがリプライに反応するために使いたいだけなので、わざわざ実装するのがめんどくさい。bot用のTokenぐらいもっと手軽に発行できないのだろうか?と思っていたところ、[twurl](https://github.com/twitter/twurl)を使うといいよと[書いてあった。](https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/authenticating-users)gemでインストールできる。

```bash
$ gem install twurl
```

CONSUMER KEYとCONSUMER SECRETを使って認証する。以下のコマンドを実行するとブラウザが開くので、表示されたPINを入力する。(historyに残るのが嫌だったので環境変数から取っているが、別に直接渡しても良い)

```
$ twurl authorize --consumer-key $TWITTER_CONSUMER_KEY \
                  --consumer-secret $TWITTER_CONSUMER_SECRET
```

認証に成功すると`~/.twurlrc`が生成されており、ここに書かれている認証情報を使って上記のAPIを叩けば、このユーザが購読開始される。

```yml
---
profiles:
  screen_name:
    consumer_key_will_be_insert_here:
      username: sutaba_police
      consumer_key: xxxxxxxx
      consumer_secret: xxxxxxx
      token: xxxxxxx # <- Access Token
      secret: xxxxxxxx # <- Access Token Secret
configuration:
  default_profile:
  - screen_name
  - consumer_key_will_be_insert_here
```

もし既にイベントを受け取るwebhookを登録していれば、適当なツイートにLikeしてみると`favorite_events`が飛んでくるのがわかる。
JavaScript: ローカルのJSからfetch APIでGETしたJSONをFileSaver.jsを使ってファイルに保存する


ローカルでfetchを使うにはCORS対応が一工夫必要なので、下記の記事を参考までにどうぞ
[Qiita - ローカルのHTMLファイルでfetchを試す & CORSとその回避策](https://qiita.com/k-shimoji/items/acbbbb49530fb97f5893)




# やりたいこと
* ローカルのJSからfetch APIを使って公開APIを叩き、GETしたJSONをファイルに保存する
* FileSaver.jsというnpmのパッケージをnode.jsとかの無いローカル環境で動かしてみる

# FileSaver.js
* Github: https://github.com/eligrey/FileSaver.js/
* ファイル生成・保存をよしなにやってくれるライブラリ
* 1ファイルだけなのでローカルでも動いてくれた


# コード
```html:test.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script type="text/javascript" src="FileSaver.js"></script>
  </head>
  <body>
    <input type="button" value="取得" onclick="apiRequest()" />
    <div id="export"></div>
    <script>
      async function apiRequest() {
        const downloadUrl =
          "http://zipcloud.ibsnet.co.jp/api/search?zipcode=1620825";
        const response = await fetch(downloadUrl);
        const blob = response.blob();
        const fileName = "test.json";
        saveAs(blob, fileName);
      }
    </script>
  </body>
</html>
```

ファイルの中身

```json:test.json
{
	"message": null,
	"results": [
		{
			"address1": "東京都",
			"address2": "新宿区",
			"address3": "神楽坂",
			"kana1": "ﾄｳｷｮｳﾄ",
			"kana2": "ｼﾝｼﾞｭｸｸ",
			"kana3": "ｶｸﾞﾗｻﾞｶ",
			"prefcode": "13",
			"zipcode": "1620825"
		}
	],
	"status": 200
}
```

# まとめ
* 簡単だった
* 今度何やろう
Vue.jsを仮想ウインドウ化するモジュールをnpmに登録してみる

# Vue.jsを仮想ウインドウ化するモジュールをnpmに登録してみる

## １．動作画面

![動作画面](https://raw.githubusercontent.com/JavaScript-WindowFramework/jswf-vue/image/image.gif)

　
 見ての通り、Vue.jsを仮想ウインドウ化してみました。
 内容的には大したことはしていません。
 以前作成した[JavaScript-Window-Framework(JWF)](https://www.npmjs.com/package/javascript-window-framework)にVueのコンポーネントをマウントする処理を入れただけです。

## ２．使い方

### モジュールのインストール

```.sh
npm -D i @jswf/vue
```

　npmでjwfスコープを取りたかったのですが、すでに取得済みだったようなのでjswfになっています。
　そのうちJWF本体をこちらのスコープに移すかもしれません。
　ちなみにnpmのスコープ登録の仕方を知ったのは最近になってからです。

### サンプルコード

 以下はrouterを有効にしたテンプレートに、必要なコードを追加したものです。

```main.ts
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import { VueWindow } from '@jswf/vue';

Vue.config.productionTip = false;

new Vue({router, render: (h) => h(App)}).$mount('#app');

//---------------------
//Create Virtual Window
const win = new VueWindow(
  new Vue({router,render: h => h(App)})
);

win.setTitle('WindowTest');  //タイトル設定
win.setPos();               //位置を中心に揃える
//---------------------
```

### ３．まとめ

　JWF自体はウインドウ生成や子ウインドウの配置を主にしているフレームワークなので、クライアント領域に表示するコンテンツには干渉しない形になっています。そのためJWFに標準機能として付いているTreeViewやListViewは、かなり大きめのコードになっています。この状態で機能を追加しようと思ったら、自由はききますが、がっつりコードを書かなければなりません。今回はVue.jsを入れることによって、Vueのコンポーネントを簡単に持ってこられるようにしました。これでユーザからの入出力が頻繁に起こる部分の作成がかなり楽になると思います。
【リリース】Nextcloud のバージョン 16.0.4、15.0.11、14.0.14 がリリースされました

2019年8月15日に Nextcloud の最新バージョンとして、16.0.4、15.0.11、14.0.14がリリースされました。

半分以上が出荷されたライブラリの更新であり、非常にマイナーなものとなっております。その他、さまざまな小さな問題が修正されております。

* 監査ログにメール共有が含まれるようになりました。
* 隠し SMB 共有 ($で終わるもの) を設定できるようになりました。
* 色のコントラストの修正
* 新しいテキストアプリとの混乱を避けるため、現在のテキストエディタをプレーンテキストエディタに名称変更

変更としては小さいですが、マイナーバージョンアップでは信頼性、セキュリティ、安定性の向上を目指しています。
リリースにあたっては RC版を提供して広範囲なテストを行っておりますので、より信頼できるものが提供されております。
Nextcloud の更新スピードはとても早いので、更新を前提とした運用をしていくことが薦められます。

### 【重要!】
**Nextcloud 14系のマイナーアップデートは、今回のリリースが最後の公開アップデートとなり、2019年9月をもってサポート終了となります。16系もしくは15系へのアップグレードの検討／適用を強くお勧めします。**

### 主な改善点

* HTTP/1.1 のみを利用した Amazon S3 アクセス
* 監査ログへのより完全なログ記録
* 冗長とならないデフォルトログ記録
* その他小さな問題に対するインターフェース強化、バグ修正

**★この記事は、[スタイルズ社のNextcloudサイト](https://nextcloud.stylez.co.jp/) の [Nextcloudブログ](https://nextcloud.stylez.co.jp/nextcloudblog)にも公開しております！**
EcmaScriptまわりを整理

# ECMAScript Editions
|Official Name|a.k.a.|a.k.a|
|:--|:--|:--|
|ECMAScript2009|ECMAScript5|ES5|
|ECMAScript2015|ECMAScript6|ES6|
[Versions](https://www.w3schools.com/js/js_versions.asp)
# ES6
- let, const
- Default parameter values
- Arrow Functions 

# 周辺ツールなどをざっくりと
## Babel
- JSのコンパイラ
- ES6で書いたコードをES5に変換してくれる

## Webpack
- 複数のJSファイルや画像ファイルをまとめる
- モジュールバンドラーと言われるもの

## Node.js
- サーバーでJavascriptが動作する環境
- シングルスレッド+非同期処理により大量のリクエストを処理できる
- V8エンジンで動作している

# 言語仕様
### let
- ブロックスコープ
- 再代入ができる

### const
- ブロックスコープ
- 再代入が出来ない

# コーディングルール(参考)
[参考）Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)

- ステートメントの最後にセミコロンを書く。セミコロンの自動挿入に依存しない。
session。 コントローラー間でデータの受け渡しができる魔法のコード

どうも！！！
チャンクノです。
最近はチーム開発が始まりブログ書くかコード書くかで悩んでいます。
ただブログは備忘録でもあるし、忘れてしまったら意味ないので書く時間を作ろうかなと思います。

さて今回はsessionというものについて書きます。
正直あまり深くは理解はしていません🙇‍♂️
あくまでも使い方の一例程度にとらえていただければと思います！！！
自分たちのコードを元に書いていきます！！！

#　sessionの書き方
sessionは以下のような書き方になります

```
                 sessionに代入する値
                       ↓
session[:sns] = user_params[:name]
          ↑
　　　ここの名前はなんでもいい
```
次は自分たちのコードを実例にとって書いていきます。

```
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def facebook
　　 //下のcallback_from(provider)からのデータをsessionに入れています。
    session[:sns] = callback_from :facebook
    @user = User.find_oauth(request.env["omniauth.auth"])
    if @user.persisted?←userがすでにDBに存在するかどうかの確認
    else
      redirect_to users_sign_up_profile_path and return
    end
  end

  private

  def callback_from(provider)
    @user = User.find_oauth(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, event: :authentication
      set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
    else
      session["devise.#{provider}_data"] = request.env["omniauth.auth"].except("extra")
    end
  end
end
```

急にややこしい！！！
ここでは下のcallback_from(provider)からデータが送られてきているんだな程度でいいです。
細かいところは気にせずいきましょう。

redirectでデータを送りたいコントローラーのパスを指定します。
今回は下記に送っています。

```
def new_profile←今回の送り先
    binding.pry←ここにbinding.pryをかけてsession[:sns]を入力
    @user = User.new
　　 session[:user] = @user
    if session[:sns]!=nil
      session[:user]["nickname"] =  session[:sns]["info"]["name"]
      session[:user]["email"] =  session[:sns]["info"]["email"]
    end
end
```
一見データがきているのかよく分からないですが来ています。
binding.pryなどを使えばデータがちゃんと送られていることがわかります。
session[:sns]で出なかったらsession[:sns] = callback_from :facebookをそのまま打ち込んでみてください。データが送られてきていることが確認できるはずです。

ここで、session[:user]["nickname"]この記述や、session[:sns]["info"]["name"]この記述の仕方が気になるかと思います。
これは

```
モデルクラスが入っている箱    　　　　　　
          ↓       
session[:user]["nickname"] =  session[:sns]["info"]["name"]
                   ↑                 
           モデルクラス内部のカラム名
```
こういうことです。
ちなみに**["info"]["name"]**と書いてあるのはinfoの中にあるnameだからこう記述します。

```
   12: def facebook
    13:   session[:sns] = callback_from :facebook
 => 14:   binding.pry
    15:   @user = User.find_oauth(request.env["omniauth.auth"])
    16:   if @user.persisted?
    17:   else
    18:     redirect_to users_sign_up_profile_path and return
    19:   end
    20: end

[1] pry(#<Users::OmniauthCallbacksController>)> session[:sns]
=> {"provider"=>"facebook",
 "uid"=>"",
 "info"=>　　　　　　　　　　　　　　
  {"name"=>"名無し権兵衛",
   "email"=>"",
   }
```
これでどういうことかわかりますかね😅
文字で説明するの難しい！！！

最後に気をつけなければならないのが、sessionはデータを目的地に飛ばすために使うものなので別途保存をしなければなりません！！！
行う動作が全て済んだ段階でsaveして保存しましょう！！！

コントローラー間でデータの受け渡しのやり方が分からず困っていたのですがsessionを使えば簡単にできました。
教えてくれたチームメイトに感謝ですね🤗
チームの中で自分が一番技術力ないのでいつも与えてもらってばっかで申し訳ないです😰
いつか自分も何かを与えられるようにがんばるぞい💪

ということでsessionについてでした！！！
それでは皆様のよきプログラミングライフを祈って🙏🙏🙏
php-master-changes 2019-08-18

今日は不要コードを削除する修正があった！

# 2019-08-18
## beberlei: Cleanup unnecessary if guard clause to free buffer.
- https://github.com/php/php-src/commit/58d661cd7d0c60aba2708993e584ef47b6cd3cd8
- 不要コードの削除
- どっちにしても free() して return じゃねえか！っていう
[Bookmarklet] 画面に表示されている一覧内のIssue(チケット/課題)を新しいタブで一気に開く(GitHubとBacklogに対応)

テスト中に修正確認するとき、私は以下の流れで行っています。

1. 新しいブラウザを開く
2. 確認したいIssueを新しいタブで全部開く
3. 1件ずつ確認し、確認が終わったらタブを閉じる

タブを全部閉じる = ウィンドウが閉じるので終わった後いい感じの達成感があります。
しかし確認したいIssueが多いとき、Step.2の作業がかなりめんどくさいので、一覧に表示されているIssueをすべて新しいタブで開くというBookmarkletを作りました。
普段業務ではGithubとBacklogを使っているのでこの2つのみ対応しています。

※ チケット = Issue、課題、バグ票、などのこと。
※ 修正確認: 開発者が修正完了したチケットをテストチームが確認することをそう呼んでいます。
私のところでは、テストチームがバグを見つけるとIssueを書き、開発者がIssue対応を行い、対応後はテストチームが再確認し、問題なければIssueを閉じるというフローをとっています。  

## 使い方

1. ブラウザを起動する(Chromeのみ動作確認済み)
2. ブックマークマネージャーを起動する
3. 新しいブックマークを作成で以下を入力し保存する  
・ ブックマーク名: 任意のもの  
・ URL: 下記のコード
4. Github: Issue一覧、またはBacklog: 課題一覧を表示する
5. Step.3で登録したブックマークをクリックする

## ソースコード

```js
javascript:
(function(){
    var url = location.href;
    if(url.match(/github\.com[\w-./%]*\/issues/)){
        /*GitHub用*/
        document.querySelectorAll('a[data-hovercard-type="issue"]').forEach((v) => {
            window.open(v.href, v.href);
        });
    }
    else if(url.match(/backlog\.[\w-%]*\/find/)){
        /*Backlog用*/
        var space_url = url.match(/https:\/\/[\w-%]*\.backlog\.[\w-%]*\//); 
        var elm = document.querySelectorAll('td[data-column-name="issueKey"]');
        var result = true;
        if(elm.length > 25)result = confirm( elm.length + '個のタブが開きます。本当に開きますか？');
        if(result){
            elm.forEach((v) => {
                var issuekey = v.getElementsByTagName('a')[0].text;
                window.open(space_url + 'view/'+issuekey,issuekey);
            });
        }
    }   
}())
```
## 実行結果
こんな感じです。
![f2d9a6490613e75d6e40410397adad1b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259668/3f90d6b4-2307-078b-6e2e-f83b2b8d7f47.gif)


## 補足
※ 初回実行時は「ポップアップがブロックされました」となる可能性があるので、許可する必要があります
<img width="330" alt="スクリーンショット 2019-08-19 8.03.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259668/e4e90cfa-2610-0043-048d-c53ce7dc5fea.png">

※ Backlogの場合、課題を26件以上開くときは警告Alertが出ます。
└ Backlogは1ページに最大100件の課題を表示できるので。
※ GitHubはIssueが何件だろうと警告Alertは出ません。
└ GitHubは1ページに最大25件までしか表示できないので。

Backlogで試しに50件開いてみたところ、私のPCではさすがに時間がかかりました。。。
これなら1件ずつ開いたほうがストレスがないので、26件以上開く場合は一応警告をつけました。

また、Backlogでは課題一覧に表示されている課題のリンクを開いた場合、1つの課題が表示されるまでに時間がかかるようです。
リダイレクトされるのが原因かと思ってます。
なので、課題一覧では課題番号を取得し、課題のURLを生成して直接叩くようにしました。
GitHubのと同じ感じの記述でも動きますが、↑にしたほうが体感早くなりました。
AtCoder Beginner Contest 138 D - Ki のテストケースがコンテスト後に増えている件について

# AtCoder Beginner Contest 138 D - Ki のテストケースがコンテスト後に増えている件について

**追記: 1≤a<sub>i</sub>&lt;b<sub>i</sub>≤N の条件があるので、以下の想像は誤りです!!**
**追々記: [AtCoder Beginner Contest 138 D - Ki のテストケースがコンテスト後に増えている件について (修正版) - Qiita](https://qiita.com/c-yan/items/887e2c2f410ecec60650) をご覧ください**

AtCoder Beginner Contest 138 の終了後も D 問題を解説を見て試行錯誤していたら、AC だったコードが WA になって、after_contest_15, after_contest_16, after_contest_17 が増えていることに気づいた. 解説 PDF にも修正が入っていた.

問題文には 「この木の根は頂点 1 で、i 番目の辺 (1≤i≤N−1) は頂点 a<sub>i</sub> と頂点 b<sub>i</sub> を結びます。」とだけ書かれていて、頂点 a<sub>i</sub> と頂点 b<sub>i</sub> のどちらが根に近いかは不明なのだが、テストケースが追加される前は頂点 a<sub>i</sub> のほうが根に近いという決めつけをしていても通るテストケースになっていたと思われます. 追加されたテストケースはこの決めつけをしていると通らないように思われます. (だから解説 PDF に「根に近い頂点から順に行えば」という追記が入ったと思われる).

なので、追加されたテストケースの入力例としては、「入力例 1」の4行目をひっくり返した以下で行えそうである.

```
4 3
1 2
2 3
4 2
2 10
1 100
3 1
```

出力例は、「出力例 1」と同じ

```
100 110 111 110
```

となる.
【Python】オブジェクト指向プログラミング基礎vol.6~ポリモーフィズム~

## ポリモーフィズム

**同名のメソッドが、インスタンスによって振る舞いを適切に変えること**

以下のプログラムを見ると、

Soccerクラス、Baseballクラス、Basketballクラスすべてが`get_score()`メソッドを持つ。

```python
class Soccer:
    def get_score(self):
        print('kick')    
    
class Baseball:
    def get_score(self):
        print('swing')
        
class Basketball:
    def get_score(self):
        print('throw')

def motion(sports):
    sports.get_score()

soccer = Soccer()
baseball = Baseball()
basketball = Basketball()

motion(soccer)
motion(baseball)
motion(basketball)
```

実行結果

```
kick
swing
throw
```

このように異なるクラスに共通の名前のメソッドを定義することで、**どのクラスのオブジェクトかを気にせずget_score()メソッドを使用できるようになっている**。

しかし、ポリモーフィズムを使わないで実装を行う余地が残ってしまっている

ポリモーフィズムを使わないで実装を強制する方法として、**抽象クラス・抽象メソッド**を利用する方法がある

**抽象(基底)くらすとは**

継承されることを前提としたクラス、インスタンスを生成できない

**抽象メソッドとは**

実装をもたない、インターフェースを規定するためのメソッド、抽象クラスに定義できる

抽象メソッドはサブクラスの中のオーバーライドによって実装されなければいけない



Pythonで抽象クラス・抽象メソッドを利用するには、**ABC (Abstract Base Class)モジュール**を使う

抽象クラスを定義するには**ABCクラス**を継承し、抽象メソッドを定義するには**`@abstractmethod`デコレータ**を使用する

```python
from abc import ABC, abstractmethod

class Sports(ABC):
    @abstractmethod
    def get_score(self):
        pass
    
class Soccer:
    def get_score(self):
        print('kick')    
    
class Baseball:
    def get_score(self):
        print('swing')
        
class Basketball:
    def get_score(self):
        print('throw')

soccer = Soccer()
baseball = Baseball()
basketball = Basketball()

soccer.get_score()
baseball.get_score()
basketball.get_score()
```

実行結果

```
kick
swing
throw
```
webarenaでubuntu その16

#概要

webarenaでubuntu18.04やってみた。
postfix3.3やってみた。

#インストール

```
sudo apt-get install postfix
```

#ポート開放

```
tcp:25,25,ip4:0.0.0.0/0
tcp:110,110,ip4:0.0.0.0/0
```

#第三者中継試験


https://mxtoolbox.com/diagnostic.aspx

http://check.jippg.org/

http://www.antispam-ufrj.pads.ufrj.br/test-relay.html



以上。
AviUtlでクイックに動画の一部を黒塗りにする

# AviUtlでクイックに動画の一部を黒塗りにする

　動画の一部をフィルタするに当たり、無料かつ多機能ということで、AviUtlを使ってみました。しかし多機能なぶん操作に慣れるまでが大変で、心が折れそうになる箇所があったので、初めて使う人が引っかかるようなポイントをまとめつつ、動画の一部を黒塗りにする手順をまとめました。


## AviUtlの導入

　[AviUtl初心者が最初に読むべきページ【導入から使い方まで】 \| AviUtlの易しい使い方](https://aviutl.info/intro/)が非常にわかりやすいので、こちらを参考に導入し、基本操作までを確認しておきましょう。


## 動画の読み込み

　拡張編集から動画を読み込みます。あちこちの参考文献に「拡張編集から～」などの記載があるものの、それが全然見つからず。ここが初心者つまづきポイント。
「設定」→「拡張編集の設定」で表示できます。（参考：[【AviUtl】タイムラインが表示されないときの対処法 \| AviUtlの易しい使い方](https://aviutl.info/taimurainn-hyouzi/)）

　動画の編集はレイヤーという概念を知っておくとスムーズです。元になる動画の上や下にレイヤーと呼ばれるオブジェクトを配置し、様々な表現をすることが可能です。

　動画の一部を黒塗りにしたい場合は、このようなイメージで動画を編集します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/cc702806-f25c-0bd4-1de6-221c54a976a6.png)

　動画を読み込むとLayer1とLayer2に動画と音声が割り当てられるので、Layer3以降に画像を登録していきます。

## 黒塗り画像をレイヤーとして登録

　Layer3に黒塗りの画像をドラッグ&ドロップすることで、Layer3に黒塗り画像をレイヤーとして登録できます。


## 黒塗り画像レイヤーのリサイズ

　レイヤーに登録した画像を適切な範囲に収めるため、AviUtl内でサイズを変更する必要があります。こちらを参照：[【AviUtl】動画をリサイズする方法【アスペクト比】 \| AviUtlの易しい使い方](https://aviutl.info/risaizu/)


## エンコード範囲を決める

　動画の最初と最後には不要な部分が写っていることがあるので、不要な部分を除いてエンコードします。（参考：[【AviUtl】動画の一部だけをエンコードする方法 \| AviUtlの易しい使い方](https://aviutl.info/itibu-ennko-do/)）

　手順どおりプラグインを導入しているとmp4形式で保存できるはずなので、mp4で保存しておくと色々と使い勝手が便利です。（参考：[x264guiexで動画をエンコードする方法](https://aviutl.info/x264guiex-intro/#toc9)）



## 初心者が手間取る手順について

### 新規プロジェクトの作成ができない
　既に何かプロジェクトが1つ立ち上がっていると新規プロジェクトが作れないため「ファイル」→「閉じる」で新規プロジェクトが閉じたうえで、「拡張編集」を右クリックすればOK。


## 「標準描画」ウィンドウが消えた
　何でも良いのでオブジェクトをダブルクリックすると再表示されます。


## 音ずれが発生する
　こちらに詳しくまとまっています：[【AviUtl】音ズレの原因と対策一覧【エンコード】 \| AviUtlの易しい使い方](https://aviutl.info/otozure/)

## 何故か動画サイズが大きくなった
　フレームレートとフレーム数の値から各種設定値を計算し、指定してエンコードすることでサイズ圧縮が可能な場合があります。手順はこちらに詳しくまとまっています。：[【x264導入済『AviUtl』】出力ファイルの容量が大きくなる場合の対処法 \| あおのページ](https://aonopage.com/aviutl-out-setting/)
デフォルトシェルでPython3系を使いたい！ → pyenvを使ってみる 



# -
独学初心者がRaspberryPiを使って色々動かしてみる記事です。
あくまで備忘録として書いていますが間違っているところ、アドバイスなどがあればコメントお願いします:bow_tone1:


# 前提条件
- Raspberry Pi 3 Model B+
-  Python 3.7.4
-  pyenv

#ターミナルを使ってみる

**Pythonのパスを確認**



```
pi@pi:~ $which python
```
``/home/pi/.pyenv/shims/python``




**Pythonのバージョンを確認**


```
pi@pi:~ $python --version
```


``python 2.7.14``



```
pi@pi:~ $python3 --version
```
``python 3.7.4``



```
pi@pi:~ $python
```

```python 2.7.14```
デフォルトは2.7.14
→デフォルトを3.7.4にしたい

# pyenvをインストールする
**pyenvとは**
>Pythonのバージョン管理、複数のバージョンを使い分けるコマンドラインツール

Google検索　```pyenv git```
一番上に表示されたGithubページリンクから
```https://github.com/pyenv/pyenv.git```をコピー＆ペースト



```
pi@pi:~ $git clone https://github.com/pyenv/pyenv.git
```

# pyenvコマンドを使えるようにPathを通す

```
pi@pi:~ $ sudo nano .bashrc
```
編集画面が開く

```
export PYENV_ROOT="\$HOME/.pyenv"
export PATH="\$PYENV_ROOT/bin:\$PATH"
eval "$(pyenv init -)"
```

変更内容を反映する

```
pi@pi:~ $ source .bashrc
```
Pathを通すっていうことが曖昧にわかったようなわかんないような感じ
*とりあえず動いたから後日調べ直し


# pyenvでPythonをインストール
**インストール可能なバーション一覧**

```
pi@pi:~ $ pyenv install --list
```

**インストール**

```
pi@pi:~ $ pyenv install 3.7.4
```
結構長い時間がかかって途中ラズパイのCPU使用が１００％になって心配だったがインストール完了
*エラーが起きたところを後日追記



**デフォルトのPythonシェルを3.7.4に設定**

```
pi@pi:~ $ pyenv global 3.7.4
```

```
pi@pi:~ $python
```

```python 3.7.4```

デフォルトをPython3.7.４に設定することができた:raised_hands_tone2:


# まとめ
わからないことがたくさんあったけどとりあえず動いたからよかった
後日少しずつ追記を書いて理解を深める。
　
# 参考記事

[pyenv + Python3.7の環境構築 【Raspberry Pi】](https://note.mu/mokuichi/n/n988bcf9812f5)
[pyenv 利用のまとめ](https://qiita.com/m3y/items/45c7be319e401b24fca8)
[\[Python\] pyenvを使ってPythonの複数のバージョンを使い分ける](https://www.yoheim.net/blog.php?q=20170204)
MacOS X クライアントから SSH サーバーへパスワードなしで接続する方法

パスワードありの SSH 接続ができることが前提。

## クライアントマシンで秘密鍵と公開鍵を作成
秘密鍵と公開鍵をまだ作成していない場合、ターミナルで以下のコマンドを入力する。

```
$ ssh-keygen
```

デフォルトでは鍵タイプが RSA、鍵長が 2048 ビットになる。通常はこれで十分。

鍵の保存場所を聞かれるので、そのまま `Enter` を押す。

パスフレーズを聞かれるので、そのまま `Enter` を押す。

パスフレーズの確認を求められるので、そのまま `Enter` を押す。

鍵が作成されたことを確認する。

```
$ ls -1 ~/.ssh | grep "id_rsa"
```

`id_rsa` が秘密鍵、`id_rsa.pub` が公開鍵。**秘密鍵は絶対にインターネットに流さないこと。**

## クライアントマシンからサーバーマシンへ公開鍵を転送
以下のコマンドで、公開鍵をサーバーに転送する。

```
$ ssh-copy-id <ユーザー名>@<サーバー名>
```

SSH で使用するポートを変更している場合 `-p <ポート番号>` をつける。

公開鍵の名前や場所を変更している場合 `-i <公開鍵のパス>` をつける。

SSH 接続するためのパスワードを聞かれるので、入力する。自動的にサーバーマシンで公開鍵が登録される。

## 接続の確認
`ssh <ユーザー名>@<サーバー名>` で接続する。パスワードを入力しなくても接続できるはず。
Amazon EKSのオンラインセミナー受けてみた

「[AWS Black Belt Online Seminar Amazon Elastic Container Service for Kubernetes (Amazon EKS)](https://www.slideshare.net/AmazonWebServicesJapan/20190410-aws-black-belt-online-seminar-amazon-elastic-container-service-for-kubernetes-amazon-eks)」の自分向けメモ
EKSって何？......レベルの人向け


## 何故コンテナなのか
 - パッケージング
 - 配布
 - イミュータブルインフラストラクチャ

上記が人気の理由
1台のサーバーでDockerコンテナを利用するのは簡単だが、サーバーが増えると管理が大変になっていく

## Kubernets（K8s）概要
 - 複数ホスト間でのアプリの管理
 - デプロイ、メンテ、スケーリング機能
 - CNCF（Cloud Native Computing Foundation）による管理、推進
 
### できること
 - ホスト管理、スケジューリング
 - コンテナの死活管理
 - オートリカバリ
    - 再起動
- サービスディスカバリ、ロードバランシング
    - 負荷分散
- アプリ設定の管理
- バッチ実行
- エコシステムとの連携

### アーキテクチャ
Workerとplaneで構成される

 - k8s master（Control plane）
    - k8s APIを実行するためのCLIであるkubectl（キューブコントロール）で操作する
 - Worker Node
    - EC2インスタンス群
    - 実行環境

#### Control plane
 - etcd：3つに分散されたKVS
 - Kubectlからload balancer経由でetcdにアクセスする
 - 構成、管理するのは大変　⇒　EKSの誕生
    - Worker Nodeを配置するVPCの用意だけでよい

#### Workloadsリソース
リソースのうち、コンテナ実行に関するリソースは以下

##### Pods
 - 最小デプロイ単位
 - 1Podに1つのコンテナが基本
 - 1Podに複数コンテナを含むことも可能
    - VolumeやNetworkを共有し、コンテナ間はlocalhostで通信


##### ReplicaSet
 - Podのレプリカを作成し、Podの数を維持するリソース
 - ロングランニングなPod向け
 - 障害時に別NodeにPodを作成する

##### Deployment
 - 複数のReplicaSetを作成、管理
 - Podのローリングアップデートやロールバックを実現するためのリソース
    - ローリングアップデート：バージョンアップ時に新バージョンの起動、旧バージョンの停止をする

##### DeamonSet
 - 選択したノードの組に対して、各ノードにPodを1つ動かすためのリソース
 - fluentdなどログ収集用のノードで利用する

##### Job
 - 1つ以上のPodを作成し、指定された数のPodが正常に完了するようにコントロールするリソース
 - Podが失敗した場合は新しいPodを作成する
 - CronJob：Jobを時間通りに実行する

##### Service/Ingressリソース
 - 外部公開する際のリソース
 - Serviceリソース
    - 外部からのアクセスをロードバランシングできる
 - Ingress
    - ALBを公開できる

## EKS概要
 - 運用難易度の高いControl planeのマネージドサービスで提供
 - K8sをそのまま動かせる
 - 2018年に東京リージョンで利用可能になった

### 使い方
 - クラスター作成
 - Worker Node配置
 - アタッチ

#### 事前準備
 - kubectl等のインストール
 - ロール、VPC作成

#### クラスター作成
 - CLIで作成可能
    - クラスター名
    - ロール指定
    - サブネット指定
    - セキュリティグループ（ENIに適用する）
 - kubeconfigの作成

↑Control plane作成完了

#### Worker Node配置
 - テンプレートから作成完了
    - インスタンスタイプやEKS最適化AMIを指定可能

#### Worker Nodeをクラスターに参加させる
 - ファイルをダウンロードし、インスタンスロールを記載し、適用で参加
 - CNI（Container Networking Interface）を利用し、シンプルでセキュアなネットワークの構築が可能

#### アドオン起動
 - オートスケーリング
    - Worker NodeとPodを考慮する
    - k8s自体は考慮不要
 - Fluentdを用いたログ収集
 - EKS Deployment Pipeline
    - コミットをトリガーにローリングアップデートまで自動化が可能
Amazon WorkSpacesのオンラインセミナー受けてみた

「[AWS Black Belt Online Seminar Amazon WorkSpaces](https://www.slideshare.net/AmazonWebServicesJapan/20190226-aws-black-belt-online-seminar-amazon-workspaces)」の自分向けメモ
Amazon WorkSpaces語感はなんとなく分かるけど......レベルの人向け


## デスクトップ仮想化（VDI）の背景
 - セキュリティ向上が目的で注目されるようになった
    - データをローカルに持ち出せない
    - 安価
 - 最近はリモートワークとしてさらに注目されている（働き方改革）

### オンプレのVDIの課題
 - 高額な初期投資
 - 利用までに時間がかかる
 - 定期的な大規模システム更改
 - 利用者増減対応が困難
 - サイジングが重要だが困難
    - 業務内容を踏まえたサイジングが困難

## 概要
 - オンプレの課題の解決を図った
    - クラウド上のデスクトップ環境（いつでも・どこでも）
 - 初期投資不要
 - サイジング、増減が容易
 - デプロイ、管理がシンプル
 - グローバル展開しやすい
 - AWSサービスとの連携が容易
    - WorkSpacesの監視をCloudWatchで行う
 - 価格要素
    - スペック・タイプ
    - 利用時間（MonthlyかHourly）
        - 月80h以下ならHourlyがお得
 - ユースケース
    - モバイルワーク
    - 短期PRJ
    - トレーニング
    - 派遣社員
    - コンプライアンスの準拠
 - 機能
    - シミュレーション、3Dエンジニアリングも耐えうるスペック
    - Amazon Linux 2がベース
    - ブラウザ、Libre Office、AWS SDKが標準搭載
    - セルフサービス管理機能
        - 管理者の負担軽減
    - Windowsを利用することも可能（Bring Your Online Licence（BYOL））
        - ライセンスをAWSに持ち込み、利用することが可能
        - 200台の利用から
        - BYOLが自動化され、2ヶ月かかっていた移行プロセスを大幅改善

## 利用方法
### セットアップ
 1. ディレクトリ作成
 - ディレクトリにユーザー追加
 - ユーザーにバンドル割り当て
 - WorkSpacesの設定
    - 自動停止
    - 暗号化
 - 起動

### WorkSpacesクライアント
 - ネットワーク接続性の確認
 - ユーザー名とパスワードでデスクトップ画面が立ち上がる
    - ブラウザでのアクセスも可能

## アーキテクチャ
### ログインフロー
 - インターネット経由で接続リクエストが認証ゲートに送られる
 - AWS内で、ディレクトリサービスにリクエストが飛ぶ
 - ディレクトリサービスはドメインコントロール経由でオンプレにDirect Connectでリクエストを投げる
 - 認証情報を入力し、ストリーミングゲートウェイにリクエストを投げる
 - 認証が通ると、Direct Connect経由でDIVがユーザーに見える
 - ストリーミングとそれ以外の通信でネットワークが分かれている

### VPC
 - AWS管理VPCとユーザー用VPCがある

### ストリーミングプロトコル
 - PCoIPプロトコルを使用
 - 通信の暗号化

### 冗長構成
 - 認証Gateway、Streaming Gatewayは冗長化済みで考慮不要
 - Directory Service
    - 異なるAZに展開されている
- WorkSpaces
    - いずれかのサブネットにデプロイされ、全体的には均等分散される
    - Dドライブは12時間ごとにバックアップをとっている
    - Cドライブは起動時の状態に戻る

### ディレクトリサービス
 - AWS Directory Serviceを利用したデスクトップ認証
 - AD Connectorを利用した既存ドメイン連携

### トラフィックフローとネットワーク接続
#### デスクトップストリーミング
 - 認証はインターネット経由
 - WorkSpacesからオンプレは専用線
 - 認証も専用線にすることが可能

#### WorkSpacesからインターネット接続
 - WorkSpacesにEIPを付与（セキュリティ設定は必要）
 - NAT Gatewayを利用
 - オンプレ経由で利用（壁、proxyは既存のオンプレを使う）

### セキュリティとアクセス制御
 - ユーザー認証
    - ADドメイン認証
    - MFA
        - RADIUSとの連携
 - IP制限
    - IPアクセスコントロールグループ
    - セキュリティグループ
        - ディレクトリ用
        - WorkSpaces用
 - デバイス制御
    - クライアント証明書
    - デバイスタイプによってアクセス可否設定
 - WorkSpacesのグループポリシー
    - デスクトップやOS上での挙動を制御
        - ローカルプリンターのサポート
        - クリップボードのリダイレクト
        - セッションレジュームのタイムアウト
        - ストリーミングの暗号強度
    - 一般的なWindowsのグループポリシーも利用可能

## デザインパターン
### ユースケース、要件の収集
 - WorkSpacesの数、予想される増加の程度からサブネットのサイズを決定
 - ユーザーのタイプからペルソナを定義
    - 業務種類
    - 気密性
    - 認証
    - セルフサーボス
    - 端末種類
    - アクセス制限
- 接続するActive Directoryドメインの数
    - 単一ドメイン、複数ドメイン
    - 既存ドメインの設定ポリシー

### AWSアカウントの構造
 - 用途に応じてAWSアカウントを分割、課金はPayerアカウントに集約
 - WorkSpaces用の独立したアカウント
 - ログや認証は共有サービスに集約
 - 全アカウントで一貫したタグ付け

### VPC、サブネットの設計
 - WorkSpaces専用VPC作成と複数サブネット
 - 将来の拡張性を考慮したサブネット作成によるIP枯渇を避ける

## まとめ
 - フルマネージドなDIVサービス
 - セキュアなデスクトップ環境
 - 初期投資不要、すぐ始められる
 - AWS連携可能
 - 適切なアーキテクチャ設計が重要
UnityでInputの分岐器を作った話

#概要
Unityあるある、「複数の操作可能なオブジェクトが同時に操作できてしまう」を抹殺するため、常に1か所にのみインプットを流す仕組みを作ったお話。
![example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483991/f0741fdb-4bf4-d7b7-9f68-7e1bab5d6e00.gif)

#作成したもの
https://github.com/domasyake/InputTurnout

#経緯
　Unity、カスタマイズ前提で敢えて最低限の機能しか用意してないんだろうなーっていうもの幾つかあると個人的には思います、インプットなんかはそのうちの1つ。ゲームはプレイヤーキャラやUIなど、「入力によって操作できるもの」が多数必要になりますが、各自がバラバラにインプット情報を取得するとなると、操作対象の切り替えもBoolで判定したりとかGameObjectそのもののActiveで止めたりとかするしかなく、バグの温床になること請け合い。
　そこでインプット情報を常に1か所にのみ流すようにする分岐器(線路の切り替えするアレ)みたいなものを経由すれば、制御対象=インプット出力先となり各自で判定せずに済むだろうと考え作成しました。　
　ついでにインプットの依存先をInterfaceに強制できるのでインプット出力元の可変(アセット使ったりモック使ったり)にも対応できるようになります。

#仕組み
インプットの出力元をサプライヤー、インプットを利用する側をレシーバーとします。
サプライヤーとして、実際に出力を行うEntityと常に非入力値を返すEmptyの2つを用意します。レシーバーは分岐器を介してサプライヤーにアクセスしますが、1つのレシーバーにのみEntityを、それ以外にEmptyを常に返すことでレシーバーは自身が今操作対象なのかどうかを意識せずに実装することができます。

#使い方
GitHubのReleaseにあるUnityPackageをインポートしてください。サンプルも含まれているのでそちらも参考に。

##レシーバー

```csharp

private void Start(){
   InputTt.ChangeReceiver(this);//本来はレシーバーが直接ChangeReceiverするのではなく別途Managerなどの制御クラスで行うべき
}
	
private void Update(){	
   if (InputTt.Input(this).XXXX()){
   //移動処理とか
   }
}
```

##サプライヤー
###Interface
標準ではUnityEngine.Inputの主要メソッドのラッパーとして定義しています

```IInputSupplier.cs
public interface IInputSupplier{
   bool anyKey{ get; }
   //中略
}
```

###Entity

```WrapUnityStandardInputEntity.cs
public class WrapUnityStandardInputEntity:IInputSupplier{
   public bool anyKey => Input.anyKey;
   //中略
}
```

###Empty

```WrapUnityStandardInputEmpty.cs
public class WrapUnityStandardInputEmpty:IInputSupplier{
   public bool anyKey => false;	
   //中略
}
```

#Tips
- あくまで本ライブラリはインプットを中継し分岐させるだけなので、サプライヤーはカスタマイズ前提です。　
- EntityにMonobehaviour継承クラスを使用したい場合は、下記のようにInputTtクラスの初期化をコメントアウト等で無効にした上でセットを行ってください。

```InputTt.cs
private static void SupplierInitialize(){
   //SetSupplier(new WrapUnityStandardInputEntity(),new WrapUnityStandardInputEmpty());
}

public static void SetSupplier(IInputSupplier entity,IInputSupplier empty){
   LogWrite("------see Input Supplier------");
   inputSupplier = entity;
   emptySupplier = empty;
}
```
- あくまでInputTt.Input(object key)に渡されたインスタンスで判定を行っているだけなので複数のレシーバーで共通のインスタンスを持ってそれをキーとしてアクセスすれば複数クラスでインプットを受け取ることも可能です。
- InputTt.IsActiveプロパティでインプットを停止できます。
- インスタンスをキーにあらゆる変更を停止するFreeze()と解除用のUnFreeze()メソッドが用意されています。暗転時等、是が非でも操作させたくない時にIsActiveと合わせて使用したりなど。

#余談
　一元管理できない処理が死ぬほど嫌いなので今まで3個くらいインプット制御のアプローチ作ってきたのですが、これが一番使い勝手よくてカスタマイズも楽だったので公開してみました。