OmniAICreator/Qiita-1.07M huggingface dataset:
Tendermintってなんぞや？

<h3>はじめに</h3>
皆様、Tendermintという技術をご存知でしょうか？
これはCosmosというブロックチェーンで用いられている技術なんです。

「ブロックチェーンって仮想通貨とかそういうやつ？」
「Cosmosなんてブロックチェーンは知らない」
「イーサリアムくらいなら知ってる！」

ブロックチェーンに関して詳しくご存じの方も、そうでない方も、ぜひ一度目を通していただけたら幸いです。


<h3>ブロックチェーン開発におけるアーキテクチャ</h3>

<p>まずTendermintに関して詳細にご紹介する前に、</p>
<p>ブロックチェーンを構成しているレイヤー(層)に関して以下をご覧ください。</p>


<p>ブロックチェーンは主に3つのレイヤーから構成されており、上から</p>

<p>・<strong>アプリケーション層</strong>→トランザクションを処理する</p>

<p>・<strong>コンセンサス層</strong>→ブロックの生成</p>

<p>・<strong>ネットワーク層</strong>→トランザクション伝搬</p>

<p>という構成になっています。</p>

<p>Tendermintが出来る以前は「ブロックチェーンを開発するぞ」と言えば、それは「上のレイヤー3つを作るぞ」という意味を表していました。</p>

<p>しかしながら熟練したエンジニアでも上記の3層を万遍なく開発するのは難しく、また手間が多くかかってしまうという問題がありました。</p>

<p>その解決を目指して開発されたブロックチェーンとしては、例えばイーサリアムがあります。イーサリアムはスマートコントラクトを記述することで簡単にDapps(分散型アプリケーション)の開発を可能にしたのです。</p>

<p>しかしここでもまだ問題があり、イーサリアムではブロックチェーンに固有の問題である「<strong>スケーラビリティ(拡張性)</strong>」や「<strong>相互運用性</strong>」という問題を解決できていないのです。</p>

<p>そこでTendermintによってブロックチェーンの開発を容易にし、ブロックチェーンに固有の問題である上記の2つを解決するために開発されたのがCosmosでした。</p>

<h3>Tendermintの技術的要約図</h3>

<p><a href="https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview"><a href="https://tendermint.com/docs/introduction/what-is-tendermint.html#stake">https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview</a></a></p>

<p>公式ドキュメントにTendermintを技術的に要約した図が載っています</p>

<p>この図の全てではありませんが、詳細は以下の寄稿内容をご覧ください</p>


<!-- wp:image {"id":188} -->
<figure class="wp-block-image"><img src="https://inside.lcnem.com/wp-content/uploads/2019/07/tm-transaction-flow.258ca020-1024x1024.png" alt="" class="wp-image-188"/></figure>
<!-- /wp:image -->

<h3>ABCIの利用</h3>

<p>TendermintはCosmosブロックチェーンにおいてコンセンサス部分を担っており、申請プロセスと合意プロセスの間に非常に単純なAPI（つまりABCI）を提供することによって<strong>ブロックチェーン設計を分解することができます</strong>。</p>

<p>ABCIとはApplication-BlockChain-Interfaceの略で、Tendermintではこれを通じてアプリケーション層とブロックチェーンエンジン(Tendermint Core)を接続します。詳細は以下の弊社CEO木村の説明をご覧ください</p>

<p><em>"コンセンサスの部分などを担うTendermintに対して、ブロックチェーンのロジック部分から情報を伝える窓口となるのがABCIです。つまり、好きなようにブロックチェーンのロジック部分をつくり、ABCIという窓口を経由してTendermint側に情報を伝えれば、あとはTendermint側がコンセンサスなどをすべてやってくれて、ブロックチェーンとして機能するのです。言わば、Tendermintを利用しつつも特有のロジックを持つブロックチェーンを簡単に作るための、Tendermintへの伝達窓口となります。"</em></p>

<h3>BFT合意プロトコルとバリデータ</h3>

<p>Tendermintは簡易的に理解可能な非同期中心のBFT(Byzantine Fault Tolerance)合意プロトコルですが、以下のようなステートマシン図(オブジェクトの状態が相互作用の中でどのように遷移していくのかを表現するための図)で表現可能です。</p>

<!-- wp:gallery {"ids":[184]} -->
<ul class="wp-block-gallery columns-1 is-cropped"><li class="blocks-gallery-item"><figure><img src="https://inside.lcnem.com/wp-content/uploads/2019/07/consensus_logic.e9f4ca6f-1024x717.png" alt="" data-id="184" data-link="https://inside.lcnem.com/?attachment_id=184" class="wp-image-184"/></figure></li></ul>
<!-- /wp:gallery -->

<p>このプロトコルへの参加者は「<strong>バリデータ</strong>」と呼ばれ、順番にトランザクションのブロックを提案・投票します</p>

<p>ブロックは各高さに1ブロックずつ連鎖してコミットされますが、ブロックがコミットされない可能性もあります。その場合、プロトコルは次の&nbsp;<strong>ラウンド</strong>に進み、新しいバリデータがその高さのブロックを提案します。(ラウンドはラウンドロビン方式のラウンド)</p>

<p>正常にブロックをコミットするには2段階の投票が必要で、それぞれpre-vote(投票前)とpre-commit(コミット前)と呼ばれています。</p>

<p>同じラウンドで同じブロックに対して2/3を超えるバリデータがプリコミットすると、ブロックはコミットされます。</p>
Knowledge が別のwindowsアカウントで登録すると認証エラー(解決済)

### Knowledgeについて
情報共有システムです。リンクは下記です。↓
https://information-knowledge.support-project.org/ja/
ページの右上のDownloadを押すとGithubに飛びます(オープンソース)。

### 問題
職場のサーバーにインストールされて、運用開始しました。サーバー管理者が変更しました。
Knowledgeを対応できるように、新しいアカウントでKnowledgeを動かせたいと思ったが、切り替えができませんでした。
### 現象
変更後のアカウントでKnowledgeを起動すると、ログイン失敗になる。
### ~~考えられる原因~~
~~tomcatに対する設定はuser変数の変更が必要~~

### 解決方法
新しいwindowsユーザーでセットアップ用アカウントでログインして、DBと再接続
ios safariでviewportがずれる

表題の通り
基本的には、["iOS safari 9.2 で window.innerWidth と viewport の値がズレる"](https://qiita.com/tttttahiti/items/b4a7bf3c0ea7dfe28712)で解決している内容です。
つまり、iOSでのviewportのサイズ参照はdocument.documentElement.clientWidth, document.documentElement.clientHeight使えというコトですが

私も含めブラウザのサイズ取得には[これ(stackoverflow)](https://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript#answer-8876069)

```var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);```

をコピペしている方も多いのではないでしょうか。
このままだとmaxの判定でwindow.innerWidth, window.innerHeightが参照されてしまうというバグになります。


この現象は、iOS12.3以降、iPhone6で顕著に現れる様です。
iPhoneのスペック的にdocument.documentElement.client***が
viewportに基づいて更新される前に参照してしまうのが原因ではないかと思われます。
以上
チャレンジ中/[batファイル]フォルダの複製

先の記事ではPyothon勉強中とかきましたが。
自分には難しい＆実務にすぐ関係させられない。。。
というわけで、コマンドプロンプトを勉強中。

# やりたいこと
　「素材」フォルダのなかには複数フォルダ＆なかに画像ファイル。
　フォルダだけ「素材」フォルダと同階層の「書き出し」フォルダに複製したい。

```コマンドプロンプト
cd batファイルを置いている場所
```
```コマンドプロンプト
xcopy /t /e "素材" "書き出し"
```


このあと

```コマンドプロンプト
書き出し は受け側のファイル名ですか、
またはディレクトリ名ですか
(F= ファイル、D= ディレクトリ)? 
```
とでてくるので

```コマンドプロンプト
d 
```

とだけ打てば複製される。助かる。

これをバッチ処理にしたい。
フォルダもカレントディクトリ（であってるのかな。毎回フォルダは変わる）にできるとなお良い。
無理だったら固定にする。

まず上記のコマンドプロンプトをテキストファイルで作り、
test.bat
として保存。

ダブルクリックで実行。

うごかなーーーい。うんともすんとも言わない。

そのそもどこで動かないのかもわからない。
どうしよう？といろいろ検索して
batファイルはコマンドプロンプトでも実行できると知る。
コマンドプロンプトで

```コマンドプロンプト
cd batファイルのある場所
```
```コマンドプロンプト
batファイル名
```
で実行したところ、
パスに日本語が含まれているので文字化けしてました、、、

そこで検索。
はじめ、パスを何かしらで囲むのかと思ったんですが違いました。

batファイルを
Shift JIS
形式で保存しあいいけないんですね。

Shift JIS
で保存したら動いたー！

次にトライするのは、カレントフォルダ。
できなかったら固定のフォルダでやります、、、、

- わかったこと
    - batファイルを作る時はコマンドプロンプトで実行して様子を見る
    - パスに日本語が含まれる場合は、Shift JIS で保存する

発見があったので記録します。
go-playground/validatorを用いてカスタムバリデーションルールを作る方法

# TL;DR
- go-playground/validatorはバリデーション用ライブラリ
- すでに存在するルールの他にカスタムバリデーションを作ることができる

# go-playground/validatorとは
https://github.com/go-playground/validator
にて公開されているバリデーションライブラリです。

> Package validator implements value validations for structs and individual fields based on tags.

Webアプリケーションフレームワークの一つである[gin-gonic/gin](https://github.com/gin-gonic/gin)のデフォルトバリデーターとて使用されています。（2019年8月8日時点）

構造体のフィールド値をtagに指定されたルールに基づいて検証します。例えば、構造体似次のようなタグを指定することでバリデーションルールを設定することができます。

```go
type User struct {
	FamilyName string `validate:"required"` // 必須項目
	GivenName  string `validate:"required,max=50"` // 必須項目 最大50文字
}

validate := validator.New()
u := Validator{}
err := validate.Struct(u) 
// invalidな場合は`error` interfaceを実装した`validator.ValidationErrors`型が返却されます。
```


使用できるタグとその使用例については次のドキュメントにて詳細を見ることができます。

https://godoc.org/gopkg.in/go-playground/validator.v9

go-playground/validatorでは単一のフィールドのみでなく複数のフィールドを利用したバリデーションルールも用意されています。次のような例を見てみましょう。

```go
type Trip struct {
	StartDate time.Time
	EndDate time.Time `validate:"gtcsfield=StartDate"` // StartDateよりも大きい(Greater than StartDate)
}
```

# カスタムバリデーションルールを作る
自前で独自のバリデーションルールを作成したいケースについて説明します。公式では次のURLで説明されています。

https://godoc.org/gopkg.in/go-playground/validator.v9#hdr-Custom_Validation_Functions

次のシグネチャを持つ関数を作成してValidatorに登録することで自前のルール関数を登録することができます。

```go
func(validator.FieldLevel) bool
```

たとえば、特定の文字列リストに合致するかどうかというルールを作るとする場合、次のような関数を作成することになります。

```go
func customFuncInList(fl validator.FieldLevel) bool {
	ls := []string{
		"list1",
		"list2",
		"list3",
		"list4",
	}
	for _, v := range ls {
		if v == fl.Field().String() {
			return true
		}
	}
	return false
}
validate := validator.New()
validator.RegisterValidation("in-list", customFuncInList) // 登録する
```


# go-playground/validatorを使ったエラーハンドリング
これまで紹介してきたライブラリをWebAPIアプリケーションで使用する場合の方法について次のスライドで解説しています。

[Go API Validation error handling](https://speakerdeck.com/hgsgtk/go-api-validation-error-handling)

# さいごに
go-playground/validatorについて使っていて使い方が忘れてしまう箇所について記事として残しました。
AtCoder Beginner Contest 128 D - equeue

# AtCoder Beginner Contest 128 D - equeue


https://atcoder.jp/contests/abc128/tasks/abc128_d

```python
import math
 
 
n, k = list(map(int, input().split()))
que = list(map(int, input().split()))
 
ans = 0
max_pop_cnt = min(n, k)
for pop_cnt in range(max_pop_cnt+1):
#  pop_cnt+1にしないと、pop_cntが0の場合は消えてしまう。
    for right in range(pop_cnt+1):
        for push_cnt in range((k - pop_cnt)+1):
            ans = max(ans, sum(sorted(que[:pop_cnt-right] + list(reversed(que))[:right])[push_cnt:]))
# reverseにした方がいい。-1で後ろからスライスをとると、0の場合に全部になってしまう。
print(ans)
```
Could not find or load main class, 今日のjava error(30)

計算物理学 Rubin H. Landau docker登録その２
https://qiita.com/kaizen_nagoya/items/a72a79de29a2b43b172b

```
# java Tune.japa
Error: Could not find or load main class Tune.japa
Caused by: java.lang.ClassNotFoundException: Tune.japa
```

# Reference
Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
### 文書履歴(document history)
ver. 0.01 初稿 　20190808
ver. 0.02 add URL　20240508
### 最後までおよみいただきありがとう4ざいました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
M5Stack 向け esp-idf の make が通ったよ

# 結論

Aug 8, 2019 に確認しました。
M5Stack 固有機能は LCD しか確認してません。

### モジュール構成

|module|version (tag)|
|---|---|
|Debian|10.0|
|Python|3.7|
|gcc|5.2.0|
|esp-idf|v3.2.2|
|arduino-esp32|1.0.2|

※ Docker image の python:3.7.4-slim-buster をベースにしてます。

### コンフィグ

あんまし精査してないですが、下記が無いと M5Stack がヘッダ不足でコケます。

- Arduino
  - FS
  - SD
  - SPI
  - SPIFFS
  - Wire
- Component
  - Bluetooth
  - Blueroid
KDD2019 Plenary Keynote Panel: Why, What & How we Democratize Data Science

[まとめページへのリンク](https://qiita.com/kotaaaa/items/4f144d660d504cc091cf)

#KDD2019 Plenary Keynote Panel: Why, What & How we Democratize Data Science
###### Democratization data science

<!-- (How the smart city is structured?)-->

###democratization of Data science ~ Anil Jain ~

- Disperse data science expertise 
- Science: Easily accessible
- Data access: Privacy issues, ownership, user consent, data integrity, function creep.

###### do package for everyone to be able to use it (data science)

- GAFA is monetizing the data
- Personally identifiable information 
- information that can be used to trace an individual's identity 
- GDPR also covers physical, physiological identity, location, online identifier
Privacy of anonymized data

- who can trust with data?
- Privacy vs Security 


##what is democratizing data science? ~Tina Eliasi-Rad

- democratizing data science is the notion that anyone, with little to no expertise, can do data science if provided ample data and user-friendly analytic tools.

data scientist cannot be automated. 

pertient questions 


- top-down 
 - experts provide tools 
 - No experts plug-and-chug without having the requisite skills and/or expertise.
- Bottom-up
 - you educate the nonexperts so they develop some of the skills and expertise that data scientists provide.

## every person can benefit from data by using data science ~ Dr. Yu Zheng ~

- Data sharing
 - copyright of data
 - protecting the privacy 
- advanced machine learning models
 - domain knowledge + data science
 - solve domain problem simply and directly 
- ecosystem 
 - No one can solve problems alone
 - based on the same foundation
 - everyone can contribute to and benefit from it 


## ~Eric Sears~

- Address the diversity crisis & transform power imbalances
- from ethics to justice accountability 
- public interest data science


##### memos (panel discussion)

 - put dataset on the platform to be available, (and models) 
 - for especially student to use it, 
 - we are unsure that model quality of large scale data, that has experimented on small data


<!-- 
Q, どうやってデータの民主化？ある国で進んだデータサイエンスを他の国に輸出するの？プロがいないのに？
C１, 数学とか，神経科学とか全員が民主化したいわけじゃない
C２, DS側の人間が伝統側の人から知恵をもらう，outdside に行くのは比較的簡単
-->

<!-- 
Q, 医療の現場では，倫理の問題も多く議論されている，KDDのコミュニティーはどう考えているか．（地震が３０m後に起こると予測できた！ひとはいろんな行動を取りうる）
C１, 
C２, 
-->
iPhone開発での画面遷移方法まとめ(Swift)

最近iPhoneアプリの開発を始めてみて、最初に画面遷移するだけでとてもハマったのでメモしておく。
個人的にiPhoneの画面遷移って鬼門な気がしてる。Androidは簡単なのに... :thinking:

### 画面遷移いろいろ

#### *同じStoryboard* のViewControllerへ

```swift
let next = self.storyboard!.instantiateViewController(withIdentifier: "Next1ViewController")
self.present(next, animated: true)
```

#### *別のStoryboard*のViewControllerへ

```swift
let storyboard = UIStoryboard(name: "Next", bundle: nil)
let next = storyboard.instantiateViewController(withIdentifier: "Next2ViewController")
self.present(next, animated: true)
```

#### NavigationControllerのあるStoryboardへ

```swift
let storyboard = UIStoryboard(name: "Navi", bundle: nil)
let next = storyboard.instantiateViewController(withIdentifier: "Next3ViewController")
self.present(next, animated: true)
```

#### NavigationControllerを持つViewControllerでNavigationControllerを使って画面遷移

```swift
let next = self.storyboard?.instantiateViewController(withIdentifier: "Next4ViewController") 
self.navigationController?.pushViewController(next!, animated: true)
```

#### TabbarControllerのあるStoryboardへ

```swift
let storyboard = UIStoryboard(name: "Tab", bundle: nil)
let next = storyboard.instantiateViewController(withIdentifier: "Next5ViewController")
self.present(next, animated: true)
```

#### TabbarControllerを持つViewControllerでTabbarControllerを使って画面遷移

※Storyboard上でAttribute InspectorでBarItemのtagに番号つけておく

```swift
self.tabBarController?.selectedIndex = 1
```

#### rootViewControllerを直接入れ替える

```swift
let storyboard = UIStoryboard(name: "Tab", bundle: nil)
let next = storyboard.instantiateViewController(withIdentifier: "Next5ViewController")
let appdelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.window?.rootViewController = next
```

たぶんこれくらい知ってれば大丈夫なはず。。。
React Router v5 + TypeScriptで認証(PrivateRoute)

# 概要

React Router公式の[Redirects (Auth)](https://reacttraining.com/react-router/web/example/auth-workflow)に記載されている例のPrivateRouteをTypeScriptにしたサンプル

ついでに認証情報をreduxからHooksで取得するよう変更。

# 実装

```tsx:PrivateRoute.tsx
import React, { Component } from 'react'
import { Route, RouteProps, Redirect } from 'react-router-dom'

import { useSelector } from 'react-redux'

import _ from 'lodash'

import { RootState, AuthState } from './reducers'

const PrivateRoute: React.FC<RouteProps> = props => {
  const auth = useSelector<RootState, AuthState>(state => state.auth)

  const isAuthenticated = auth.token !== null

  const rest = _.omit(props, ['component'])
  return (
    <Route
      {...rest}
      render={innerProps =>
        isAuthenticated ? (
          <Route {...props} />
        ) : (
          <Redirect
            to={{
              pathname: '/login',
              state: { from: innerProps.location }
            }}
          />
        )
      }
    />
  )
}

export default PrivateRoute

```
ウィンドウサイズに応じて倍率を自動調整する.js



# はじめに
こんな方に読んで欲しいです。

スタイルを作成する時に

- 色んなデバイスを考慮するのがめんどくさい
- レスポンシブなフレームワークを使っても、デバイスサイズによって改行位置とかが微妙にずれてきになる
- PCとSPでカラム数を変える必要がない
- 1カラムを想定している
- 解像度が高いPCだとコンテンツに対する余白の割合が多すぎて気になる

この記事で紹介する方法を用いると

- 固定幅のデザインを1つ作成するだけでOK
- どんなデバイスでも同じ見栄えになる

それでは…

# 仕組み

仕組みはっても単純です。
例えば幅1000pxのページをデザインしたとします。そしたらjsがウィンドウサイズに応じて適切な倍率を計算して設定してくれます。

- ウィンドウサイズが1000pxの時は何もしない
- ウィンドウサイズが2000pxの時は200%にする
- ウィンドウサイズが500pxの時は50%にする

値は極端ですが、イメージできたでしょうか。モバイル端末ではPCサイトで見る画面をそのまま縮小して表示されます。沢山カラムのあるサイトには向きませんが、1カラムのサイトであれば「小さ過ぎて拡大しなきゃ見えね～よ！」にはならなそうです。

4Kディスプレイを搭載したPCではどうなるでしょうか。計算しやすいように幅を4000pxだとすると、通常1000pxのページであれば、約3/4が余白になってしまいます。この仕組みを使えば余白のない全画面表示が可能になります。

さらにポイントは画面サイズではなく、ウィンドウサイズを見て倍率を調整できる点です。PCではブラウザを全画面表示しないで使うケースも多いと思いますが、現在のウィンドウサイズを識別して自動で拡大縮小します。勿論、ロード後にウィンドウサイズを変更したり、全画面表示に切り替えても都度拡大縮小処理を行ってくれます。

# ソース
```html:test.html
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>ウィンドウサイズに応じて倍率を自動調整する</title>
<style>
    body {
        width: 500px;
        transform-origin: 0 0;
        margin: 0;
    }
</style>
<p>私は一番もうそんな威圧ごとというもののためを射しなた。どうしても直接に話団もしばしばそのお話しないんくらいが得るがいるんからは推察ありたましのに、どうには上げたたですた。</p>
<script>
    var change_scale = {
        "container": 500,
        "percent": 1,
        "function": function() {
            "use strict";
            if (change_scale.percent === window.devicePixelRatio) {
                var scale = document.documentElement.clientWidth;
                scale = scale / change_scale.container;
                scale = "scale(" + scale + ")";
                document.body.style.transform = scale;
            } else {
                change_scale.percent = window.devicePixelRatio;
            }
        }
    };
    (function() {
        "use strict";
        if (!navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/i)) {
            if (window.devicePixelRatio !== 1) {
                alert("申し訳ございません。スタイルが崩れている可能性があります。恐れ入りますが、倍率を100%に変更後、リロードしてください。")
            }
        }
        change_scale.function();
    }());
    window.addEventListener("resize", function(event) {
        "use strict";
        change_scale.function();
    });
</script>

```
ただコンテナをクラウド上で動かすだけならAzure Container Instancesが簡単だよ

# はじめに

今やっているプロジェクトではAzureを使うことが決まっており、画面はJava（Springboot）で開発しコンテナでデプロイしようと思っていました。
AKSやWebApp on LinuxでもコンテナのデプロイはできますがACI(AzureContainerInstances)はもっと楽にデプロイすることができます。

レジストリへのデプロイにはJibを使い、AzureContainerInstancesにデプロイするまでの流れを紹介したいと思います。

# ソリューションの紹介

Azure Container Registry

* Azureのコンテナレジストリです。手動でデプロイする場合は↓の記事をどうぞ
* [AzureContainerRegistryにprivateイメージをpushしよう](https://qiita.com/uzresk/items/f6fa479186c51dccaba1)

[jib-gradle-plugin](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin)

* [これまで](https://qiita.com/uzresk/items/fb323d0b755f19bed389)はspotifyのdockerfile-maven-pluginを使って自分で用意したDockerfileをビルドしてECRへのデプロイまでをやっていました。
* jibはpluginを入れてちょっと設定をすればDockerfileがなくてもコンテナを作成し、Azure Container Registry,Elastic Container Registry,Dockerhub,Google Container Registryにデプロイすることができます。(base imageについては変更などが可能です）

[Azure Container Instances](https://azure.microsoft.com/en-us/services/container-instances/)

* AWSでいうFargateみたいなものでコンテナが稼働するインスタンスを用意せずとも割り当てたCPUやメモリの大きさに合わせて稼働した時間だけ課金されるようなサービスです。
* Fargateほど色々はできないようですが、これからの機能の拡充が期待できますね。
* 料金についてはFargateと比較すると、今日現在だとほぼ同じでした。
    * [Fargateの料金は月に何円ぐらいかかるのか](https://qiita.com/nishinoshake/items/a90c93675b2b9245ffb2)
    * 計算してみると1vCPU,2GB=4,965円、2vCPU,4GB=9,929円という感じで誤差の範囲ですね。

# Jibを使ってACRにpushする

pluginを追加します

```build.gradle
plugins {
    id 'com.google.cloud.tools.jib' version '1.4.0'
}
```

ACRのリポジトリを作成しimage名の部分を変更します。ユーザ名とパスワードはgradle.propertiesに記載しておきます。

* [[参考]AzureContainerRegistryにprivateイメージをpushしよう](https://qiita.com/uzresk/items/f6fa479186c51dccaba1)

```build.gradle
jib {
    to {
        image = 'xxxxxx.azurecr.io/web'
        auth {
            username = "${USERNAME}"
            password = "${PASSWORD}"
        }
    }
}
```

```gradle.properties
USERNAME=xxxx
PASSWORD=xxxx
```

あとはコマンドを打てば、コンテナを作ってACRにpushしてくれます。

```shell
$ gradlew jib
```

コンテナだけ作るには以下のコマンドを打ちます。（コンテナができたらdocker runで動作確認しておくのも良いでしょう）

```shell
$ gradlew jibDockerBuild
```

# Container Intancesへデプロイ

Azureにログイン後、CloudShellを起動して以下のコマンドを打つだけです。

```
az container create -g TEST-RG \
   --name poc-web \
   --image xxxxx.azurecr.io/web \
   --ip-address public \
   --registry-username xxxxx \
   --registry-password yyyyyyyyy \
   --ports 80 \
   --dns-name-label zzzzzzz \
   --environment-variables SPRING_PROFILES_ACTIVE=development 
```

* xxxx,yyyyyyはACRのユーザ名、パスワードを入力します。
* --dns-nameをつけておくと、名前でアクセスできるようになります。
    * http://zzzzzz.japaneast.azurecontainer.io　

# Container Instancesのその他の操作

ログを取得する

```shell
az container logs --resource-group TEST-RG --name poc-web
```

ログにアタッチする（コンテナの標準出力に繋がります）

```shell
az container attach --resource-group TEST-RG --name poc-web
```

Containr Instancesを削除する

```shell
az container delete -g TEST-RG --name poc-web 
```

# 監視

AzureMonitorを使った監視ができますが、CPU,メモリ、ネットワークのIn/Outくらいで細かい部分は見えないようです。今のところこれ以上のメトリクスを取るにはSideCarを使って監視していく感じになるのかな・・・とと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57686/db45bd65-76f5-fb13-4b3d-97bb40fa905b.png)


# まとめ

とにかく簡単にAzureにコンテナをデプロイするにはContainerInstancesですね。
ActiveRecordのsave()の挙動、あるいはcreate()とupdate()の挙動の違いについて

`update()`はattributesを引数に取れるので`save()`でも出来るよなーと思ってRails Consoleで確認したら出来るときと出来ないときがあったので確認した。

まずは`update`の実装がどうなっているかを公式ドキュメントの[update](https://apidock.com/rails/ActiveRecord/Persistence/update)で確認。

`update()`は以下の実装になっている。

```ruby
    # File activerecord/lib/active_record/persistence.rb, line 423
    def update(attributes)
      # The following transaction covers any possible database side-effects of the
      # attributes assignment. For example, setting the IDs of a child collection.
      with_transaction_returning_status do
        assign_attributes(attributes)
        save
      end
    end
```

内部的には `assign_attributes` してから`save`しているだけ。

ここで疑問として`save`って引数に更新対象渡せば更新してくれたと思うんだけど何故`assign_attributes`しているのか？と疑問に思った。

なので`save`の実装を確認。

`save()`は以下の実装になっており、この `create_or_update`で`*args`が有効になるのは更新時のみ。

```ruby
    # File activerecord/lib/active_record/persistence.rb, line 274
    def save(*args, &block)
      create_or_update(*args, &block)
    rescue ActiveRecord::RecordInvalid
      false
    end
```

```ruby
    # File activerecord/lib/active_record/persistence.rb, line 702
    def create_or_update(*args, &block)
      _raise_readonly_record_error if readonly?
      return false if destroyed?
      result = new_record? ? _create_record(&block) : _update_record(*args, &block)
      result != false
    end
```

なので`save()`で新規登録時に引数に `name: 'luccafort', message: 'こんにちわこんにちわ'`というのを期待しても保存はされず、更新時にのみ有効になる。
なので当初思い込んでいた`save()`で渡した引数が有効になる、は半分正解だけど半分不正解。

`save()`でも値を反映されてほしい場合は↓みたいにする必要があるってことでいいのかな？

```ruby

User.save() do |u|
  u.name = '名無しの権兵衛'
end
```

追記:
Twitterで「`save()`で新規登録するときは`create`を使っている」という指摘を受けた。
明示的に新規登録と更新は分けたほうがコンテクストが混在せずに良さそうだし、新規登録時の処理も`update()`と同じように引数を取るのでこちらのほうが勘違いせずに済みそう。

[create](https://apidock.com/rails/ActiveRecord/Base/create/class)の実装はこうなっているので明示的にするならこっちのほうが勘違いせずにすむのでこちらのほうが良さそう。

```ruby
      # File activerecord/lib/active_record/base.rb, line 504
      def create(attributes = nil, options = {}, &block)
        if attributes.is_a?(Array)
          attributes.collect { |attr| create(attr, options, &block) }
        else
          object = new(attributes, options)
          yield(object) if block_given?
          object.save
          object
        end
      end
```

この辺の違いをちゃんと認識してなかったので `update()` は引数渡すと更新してくれるけど `save()` はOKなときとNGなときがあるなーとざっくりした認識をしていたがようやくきちんと理解できた。

似たような勘違いをしている人がいたのでままあることなのか？と思いつつ、めちゃくちゃお世話になるメソッドの割にちゃんとわかってないの怖いなと思いましたまる

[Railsのfind_or_create_byのblockはcreateした際にしか実行されない](https://qiita.com/yimajo/items/068f4e6cb81297a8c642)
selenium/standalone-chrome-debugの最新版を使ってLaravel Duskを動かすと常にassertSeeがエラーを出す

# 背景

Laravel Duskを久々に起動するとassertSeeが常にエラーを吐き出す。

# 前提条件

Laravel DuskがDockerで起動できるように設定済み。
[こちら](https://qiita.com/ProjectEuropa/items/81368cae59f786cf6f0f)を参考にどうぞ。

## 問題

[stackoverflow](https://stackoverflow.com/questions/56459691/undefined-index-element-laravel-dusk?rq=1)を見るとSeleniumのDockerイメージが最新版だと破損しているらしいとのこと。

3.141.59-oxygenではfixされているとのことで、3.141.59-oxygenを使う。

以下の通りに。

``` docker-compose.yml

version: '3'
services: 
  selenium:
    image: selenium/standalone-chrome-debug:3.141.59-oxygen
```

~~テキトーに最新版使わずにバージョン指定しましょう~~

## 参考

[Undefined index: ELEMENT Laravel dusk
](https://stackoverflow.com/questions/56459691/undefined-index-element-laravel-dusk?rq=1)
Raspberry PiがGoogle Edge TPUアクセラレータによってAIに過充電

35ドルのRaspberry Piを使用した画像認識などのAIを使用したタスクの実行は、はるかに簡単になります。

Googleは、Piやその他の低電力コンピューターが訓練された機械学習モデルを実行する速度を劇的に加速するUSBスティックを明らかにしました。

Googleによると、Edge TPU Acceleratorを使用すると、デバイスは1秒あたり30フレームを超える高解像度ビデオで複数の最先端のコンピュータービジョンモデルを実行できます。

そのパフォーマンスのレベルは、Piがサポートしていない能力をはるかに超え、IntelのMovidius Neural Compute Stickのような既存のAIアクセラレータを使用して報告されたパフォーマンスのレベルを超えているようです。

Googleは、データセンタ用のTPU（Tensor Processing Unit）アクセラレータの構築で長年の経験があり、機械学習を処理するためのチップの設計方法を知っています。

注意点は、Raspberry PiモデルにあるUSB 2.0ポートによってEdge TPUアクセラレータがボトルネックになることです。 PiがUSBおよびイーサネット用の共有バスに依存していることにより、その減速はさらに悪化する可能性があります。

このスティックは、TensorFlow Liteフレームワークを使用して構築された機械学習モデルを高速化するために設計された、特定用途向け集積回路（ASIC）であるGoogle Edge TPUコプロセッサーを使用します。 USB Type-Cを介して接続し、Debian LinuxおよびAndroid Thingsオペレーティングシステムで実行されます。

![微信图片_20190724172943.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/1ebc8f4a-66b7-c0a5-126f-912164ce0275.jpeg)
- Googleから送信

機械学習モデルは強力なマシンまたはクラウドベースのインフラストラクチャを使用してトレーニングする必要がありますが、Edgeはこれらのトレーニングされたモデルを実行し、たとえば特定のメイクを見つけるためにデータから情報を推測するために使用できる速度を加速しますビデオの車のまたは音声認識を実行します。

画像認識などのAI関連のタスクは以前クラウドで実行されていましたが、Googleは機械学習モデルをPiなどの低電力デバイスでもローカルで実行するように推進しています。

近年、GoogleはAIY Projectsプログラムの下で、シングルボードコンピューター用のビジョンと音声認識キットの両方をリリースしました。 これらのキットで実行できるトレーニング済みの機械学習モデルには、顔/犬/猫/人間の検出器と汎用の画像分類器が含まれます。（AIYはその名前をCoralに変更しました。）

![微信图片_20190724172934.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/eb873a48-32e0-bbc2-e4e5-a08a00e57740.jpeg)
- Googleから送信

Googleはまた、Edge TPUコプロセッサーを搭載し、Raspberry Piとよく似たスタンドアロンボードをリリースしています。

クレジットカードサイズのEdge TPU Dev Boardは実際には40x48mmのPiよりも小さいですが、Piのように40ピンの拡張ヘッダーがあり、これを使用して自家製の電子機器に接続できます。

Edge TPU開発ボードには、NXP i.MX 8M Cortex-M4プロセッサ、1GBのRAM、8GBのeMMCフラッシュストレージが含まれます。 2つのUSB Type-C、USB 3.0 Type-Aホスト、micro-SDカードスロット、3.5mmオーディオジャック、2つのPDM MEMSマイク、フルサイズのHDMIなど、さまざまなポートを提供します。 MIPI-DSIディスプレイ用の39ピンFFCコネクタ、およびMIPI-CSI2カメラ用の24ピンFFCコネクタ。

![微信图片_20190531135353.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/82072a70-41b3-eb09-33b0-f64e3705f6ea.jpeg)
![微信图片_20190531135234_副本.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/bd3c2806-2e89-ca85-81e4-e519fa3620cb.jpeg)


Google Coral現在の外観，AIYはその名前をCoralに変更しました。海外代理店から購入：https://store.gravitylink.com/global
Three.jsとPanolensで360パノラマの作成方法

<img width="541" alt="Screen Shot 2019-08-08 at 15.46.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/95ed0dd3-6090-d050-494e-f698761decfe.png">


## はじめに
こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.html
 
## Copyrights・ コピーライト
Copyleft picture https://pixabay.com/photos/winter-panorama-mountains-snow-2383930/

## Objective・目的
Learning how to create a 360 panorama with info markers.
ツールチップ付きの360パノラマの簡単な例を学ぶこと。

## Tools・ツール
-[Panolens](https://pchen66.github.io/Panolens/)
-[Threejs](https://threejs.org/)


## Implementation ・ 実装

```html 
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">

  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      overflow: hidden;
      margin: 0;
    }

    #container {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <script src="//cdnjs.cloudflare.com/ajax/libs/three.js/105/three.js"></script>
  <script src="//cdn.jsdelivr.net/npm/panolens@0.11.0/build/panolens.min.js"></script>

  <div id="container"></div>


  <script>
    var panorama, viewer, container, infospot, infospot2;

    container = document.querySelector('#container');

    panorama = new PANOLENS.ImagePanorama('https://i.imgur.com/wTCPouq.jpg');


    infospot = new PANOLENS.Infospot();
    infospot.position.set( 1000, 100, -2000 );
    infospot.addHoverText( '千葉県' );
    
    infospot2 = new PANOLENS.Infospot();
    infospot2.position.set( 1000, 100, 2000 );
    infospot2.addHoverText( '神奈川県' );

    panorama.add(infospot , infospot2);

    viewer = new PANOLENS.Viewer({
      container: container
    });
    viewer.add(panorama);
  </script>

</body>

</html>

```

### demo ・ デモ
https://jsfiddle.net/gzxsefyq/


## 情報元

https://github.com/mrdoob/three.js/
https://pchen66.github.io/Panolens/
Symfony4のController用アノテーションで、paramConverterとEntityを使う

毎度忘れるので、メモ代わりに。要するに「[Symfonyマニュアルの＠ParamConverter](https://symfony.com/doc/4.0/bundles/SensioFrameworkExtraBundle/annotations/converters.html)」のざっくり訳になります。

> ArgumentResolverを利用する方法もあります→[アクション引数でログインしているユーザーの情報を取得する](https://qiita.com/polidog/items/804eac7230a24e81c944)

## 便利なアノテーション

SymfonyのControllerで使えるアノテーションに`@ParamConverter`と`@Entity`というのがあって、便利だなと言う話。

### 自動でエンティティに変換する

Symfonyの便利な機能に、ルートをアノテーション（`@Route`）で指定できます。

```php
use Symfony\Component\Routing\Annotation\Route;

class PostController 
{
    /**
     * @Route("blog/{id}", name="post-info")
     * @param Post $post
     */
    public function show(Post $post) {...}
```

さらに便利なことに、`{$id}`をプライマリキーとして使って、`$post`を渡してくれます。条件は、

- ルートの中に`{id}`が存在すること。これがプライマリキーになります。
- 引数にエンティティが存在すること。

### 複数のエンティティがある場合

次は`Post`と`Comment`の複数のエンティティをアノテーションで取得する方法です。これには`@Entity`アノテーションを利用して、2つめのエンティティの変換方法を指定します。

```php
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Symfony\Component\Routing\Annotation\Route;

class PostCommentController 
{
    /**
     * @Route("/blog/{id}/comments/{comment_id}")
     * @Entity("comment", expr="repository.find(comment_id)")
     * 
     * @param Post $post
     * @param Comment $comment
     */
    public function show(Post $post , Comment $comment) {...}
```

## @ParamConverterとは？

マニュアルのタイトルに有る`@ParamConverter`とは何でしょう？

最初の自動でエンティティに変換してくれる機能について、いろいろな設定をするアノテーションと理解するのが早そうです（多分、違う…）。

例えば、`{id}`ではなかったり、プライマリキーではなかったり、とかでしょうか。

```php
/**
 * @Route("/blog/{post_id}")
 * @ParamConverter("post", options={"id" = "post_id"})
 */
public function showPost(Post $post) {}
```

毎回のように間違えるのは、複数のエンティティに変換している場合に`＠ParamConverter`を使おうとしても、動かないことです。この場合は`@Entity`アノテーションを利用することになります。
vim-goでGoDef移動ができない

## 概要
普通のgoファイルでは問題なく`GoDef`ができますが、`go-mod`のパッケージ管理を利用しているコード上だと`GoDef`がうまく機能しないという問題が発生しました。

具体的には、関数ジャンプ`GoDef`を使うと、`vim-go: [searching declaration] dispatched`の表示が出て、永遠とCPUの負荷が増していきました。

## 開発環境

- go1.12.4 darwin/amd64
- VIM - Vi IMproved 8.1
- macOS Mojave 10.14.6

## 解決策
vim-goのプラグインに、下記の設定を追加してあげると、`go-mod`を利用したプロジェクトでも利用可能になりました。

```
let g:go_def_mode = 'godef'
```

## 参考
こちらのissueが参考になりました。

[GoDef unable to jump definition in other files in macOS · Issue #1687 · fatih/vim-go · GitHub](https://github.com/fatih/vim-go/issues/1687#issuecomment-369821370)

[GoDef no longer works when moved to go-mod · Issue #2149 · fatih/vim-go · GitHub](https://github.com/fatih/vim-go/issues/2149#issuecomment-466514914)
Android の setColorFilter() や setTint() がうまく動かない

※2017年に下書き保存していた記事の投稿

# 内容
Drawable の背景色を java コードから設定しているが、OS バージョンによってできるできないがあったので、OS バージョンによってメソッドを変えて対応した。

# 詳細
```
Drawable d = DrawableCompat.wrap(ContextCompat.getDrawable(getActivity(), R.drawable.round_icon_gray));
d.setColorFilter(ContextCompat.getColor(getActivity(), R.color.BG_WHITE_GRAY), PorterDuff.Mode.SRC_IN);
```

これだと、どうも Lolippo 以下で色の設定が効かない。

```
Drawable d = DrawableCompat.wrap(ContextCompat.getDrawable(getActivity(), R.drawable.round_icon_gray));
DrawableCompat.setTint(d, ContextCompat.getColor(getActivity(), R.color.BG_WHITE_GRAY));
DrawableCompat.setTintMode(d, PorterDuff.Mode.SRC_IN);
```
これだと、今度は Mashmallow 以上で色の設定が効かない。

ぐぐっても原因となりそうなものは見つからないし、だいぶハマったあとに気づいた。
`DrawableCompat.wrap()` でインスタンス作ってるから挙動が違うんじゃないか？？
その箇所を削除したら 4.4〜8.0 で setColorFilter() で色がつけられるようになった。
初歩的な見落としだった。。

```
Drawable d = ContextCompat.getDrawable(getActivity(),R.drawable.round_icon_gray);
d.setColorFilter(ContextCompat.getColor(getActivity(),R.color.BG_WHITE_GRAY), PorterDuff.Mode.SRC_IN);
```
conda環境でpython setup.py installが上手くいかないときの解決法

# はじめに
Pythonでプログラムを書いたことはあっても，テストコードを真面目に書いたり，パッケージを作成したりする機会がありませんでした．
インターンに向けて[パッケージ化の記事](https://qiita.com/Kensuke-Mitsuzawa/items/7717f823df5a30c27077)を参考にしながら色々勉強していざ自作したパッケージをインストールしてみようと`python setup.py install`を叩くと上手くconda環境にインストールされませんでした．
それの解決方法のメモです．

# 解決方法
```console
$ python setup.py install
```

と叩くのではなく，リポジトリの1つ上の階層へ移動してconda環境の`pip`を使ってやるといいっぽいです．

```console
$ pip install ./your-package
```

これでどこか他の場所へ移動して

```console
$ python
Python 3.7.3 (default, Mar 27 2019, 16:54:48)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import package_name
>>> package_name.function()
```

とかやると上手くいってるか確認できると思います．

# (補足)setup.pyを実行したとき
`python setup.py install`をした後にactivateになっているconda環境のpythonの`site-packages`の中を見てみると末尾が`egg`というやつがあった．
本当はディレクトリになってないといけない(？)けどバイナリファイルになっていた．

未知の分野すぎて何がダメで何が原因かよくわかっていないけど，初心者の壁感すごい．

(自分のpython環境の`site-packages`がわからない人は[ここ](https://qiita.com/chatrate/items/eb4b05cd1a6652529fd9)とかを参考にされるといいと思います．)

# 参考文献
[Install python packages to correct anaconda environment](https://stackoverflow.com/questions/22312665/install-python-packages-to-correct-anaconda-environment)
cherome develop toolbarでinput rangeが動かなくなる問題

# cherome develop toolbarでinput rangeが動かなくなる問題
input[range]がdevtoolで動かないことが発覚した。

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body style="height: 1px">
    <input type="range" class="input-range" value="100" min="0" max="200" data-unit="%">
</body>
</html>
```

![problem.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195504/6f77a853-8135-57b8-be42-db5c4ef8077c.gif)

## こういうcssを追加すれば一応動かせる
```css
        input[type=range] {
            -webkit-appearance: none;
            background: #5e5e5e;
            height: 100%;
            width: 100%;
        }
        input[type=range]::-webkit-slider-thumb {
            -webkit-appearance: none;
            background: #5e5e5e;
            height: 10px;
            width: 10px;
            border-radius: 50%;
        }
```

## 動かした例
こんな感じ

![solved.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195504/775d52af-0ef2-044a-7dad-a433ae79b482.gif)


## 全部のブラウザで挙動を統一させるときはこんな感じで
```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        input[type=range] {
            -webkit-appearance: none;
            background: #5e5e5e;
            height: 100%;
            width: 100%;
        }

        input[type=range]::-webkit-slider-thumb {
            -webkit-appearance: none;
            background: #5e5e5e;
            height: 10px;
            width: 10px;
            border-radius: 50%;
        }

        input[type=range]::-ms-tooltip {
            display: none;
        }

        input[type=range]::-moz-range-track {
            height: 0;
        }

        input[type=range]::-moz-range-thumb {
            background: #f00;
            height: 10px;
            width: 10px;
            border: none;
            border-radius: 50%;
        }
    </style>
</head>
<body style="height: 1px">
<input type="range" class="input-range" value="100" min="0" max="200" data-unit="%">
</body>
</html>
```
Alfrescoのファイルプレビュー機能で日本語が文字化けする問題の対処法

# 概要
OSSのコンテンツ管理システムである、「Alfresco」にて、ファイルプレビュー時に日本語フォントが文字化け（豆腐）してしまう事象が発生した為、その対処法を記述します。

#環境

- ホストOS
  - CentOS7.6
- Docker
  - 1.13.1
- Docker-Compose
  - 1.24.1
- 使用したAlfrescoのリポジトリ
  - https://github.com/Alfresco/acs-community-deployment
- リポジトリのデプロイ時に参考にした資料
  - https://community.alfresco.com/community/ecm/blog/2018/05/01/using-alfresco-201804-ea-in-a-simple-prod-environment
 
# 原因

ファイルプレビューに必要なPDFを生成している「LibreOffice」コンテナに日本語フォントが不足しているのが原因でした。

# 対処法

### ① フォントを保存しているディレクトリを永続化

本対処内容を永続的に反映させる為、フォントを保存しているディレクトリを永続化する設定を、docker-compose.ymlに記述します。


```yml:docker-compose.yml

#~~~~~~~~~~~~~~~~~~~~ 前略 ~~~~~~~~~~~~~~~~~~~~

    libreoffice:
        image: alfresco/alfresco-libreoffice:2.1.0-EA4
        mem_limit: 1g
        environment:
            JAVA_OPTS: " -Xms256m -Xmx512m"
        ports:
            - 8092:8090
#★★★★★★★★★★ 追記ここから ★★★★★★★★★★
        volumes:
            - libreoffice-fonts-data:/opt/libreoffice5.4/share/fonts/truetype/
#★★★★★★★★★★ 追記ここまで ★★★★★★★★★★

#~~~~~~~~~~~~~~~~~~~~ 中略 ~~~~~~~~~~~~~~~~~~~~

#★★★★★★★★★★ 追記ここから ★★★★★★★★★★
volumes:
    libreoffice-fonts-data:
        external: true
#★★★★★★★★★★ 追記ここまで ★★★★★★★★★★
```

### ②コンテナの起動

```console:command
docker-compose up -d
```

### ③rootでlibreofficeコンテナへログイン
※ コンテナIDは**「docker ps」**コマンドで調べることが出来ます。

```console:command
docker exec -it --user root {コンテナID} /bin/bash
```

### ④フォントのインストール
yumコマンドでフォントをインストールします。

```console:command
yum install -y ipa-gothic-fonts ipa-pgothic-fonts
```

### ⑤インストールされたフォントファイルのパスを特定、フォントファイルの移動
インストールしたフォントファイル**「rpm」**コマンドで調べ、libreofficeのフォントディレクトリへ配置します。
※フォントファイルは通常のゴシック体とPゴシック体の2つが存在するので、両方移動させます。

```console:command
rpm -ql ipa-gothic-fonts ipa-pgothic-fonts | grep gothic
mv {インストールしたフォントのパス}  /opt/libreoffice5.4/share/fonts/truetype/
```

### ⑥コンテナの再起動
コンテナを再起動すると配置したフォントが読み込まれるようになります。
※既にAlfrescoへアップロードしたファイルについては、文字化けしたままとなるので注意してください。

```console:command
exit                          ← libreofficeコンテナからログアウト
docker-compose down
docker-compose up -d
```

# 手順参考資料

- https://qiita.com/fukuham/items/1adafb06a4d6b9a272ae
- https://community.alfresco.com/thread/201768-preview-missing-chinese-characters
Laravel開発を後押しするプラグイン

# DBキャッシュ

- [dwightwatson/rememberable
](https://github.com/dwightwatson/rememberable)

# 帳票

帳票出力、読み込みにも対応

- [Maatwebsite/Laravel-Excel](https://github.com/maatwebsite/Laravel-Excel)

# Markdown
- [cebe/markdown](https://github.com/cebe/markdown)

# View関連

AdminLTE を簡単に導入する

- [jeroennoten/Laravel-AdminLTE](https://github.com/jeroennoten/Laravel-AdminLTE)

BootStrap3 フォームビルダー

- [dwightwatson/bootstrap-form](https://github.com/dwightwatson/bootstrap-form)

Breadcrumbs を簡単に導入する

- [davejamesmiller/laravel-breadcrumbs](https://github.com/davejamesmiller/laravel-breadcrumbs)

# SNS連携

- [laravel/socialite](https://github.com/laravel/socialite)

# Log

- [arcanedev/log-viewer](https://github.com/ARCANEDEV/LogViewer)
Nuxt×TypeScriptでfetch, asyncDataの引数に型を指定する

## Composition APIの場合

※2020/10/05追記

Vue 3の新機能、Composition APIをNuxt向けに調整したパッケージ `@nuxtjs/composition-api` を使用する場合は明示的な型の指定が不要になりました。

```ts
import { defineComponent } from '@nuxtjs/composition-api';

export default defineComponent({
  name: 'SampleComponent',
  async asyncData(context): Promise<void> {
    const { app, store } = context;

    // プラグインにもアクセスできる！
    app.$plugin.run();

    // VuexにDispatchできる！
    await store.dispatch('user/checkAuth');
  }
});
```

> [Introduction - Nuxt Composition API](https://composition-api.nuxtjs.org/)

## Nuxt 2.9 以降

Nuxt 2.9からTypeScriptが外部パッケージ化され、あたらしく`@nuxt/types`が利用可能になりました。

`@nuxt/types`は手動でのインストールは不要で2.9から追加された`@nuxt/typescript-runtime`または`@nuxt/typescript-build`をインストールすることで利用できるようになります。

あとは、`@nuxt/types`が提供する`Context`型を`context`へ指定することで型安全にコーディングできるようになります。

```ts
import { Context } from '@nuxt/types';
import { Component, Vue } from 'nuxt-property-decorator';

@Component
export default class SampleComponent extends Vue {
  /** Lifecycle */
  async asyncData(context: Context): Promise<void> {
    const { app, store } = context;

    // プラグインにもアクセスできる！
    app.$plugin.run();

    // VuexにDispatchできる！
    await store.dispatch('user/checkAuth');
  }
}
```

## Nuxt 2.8 以前

NuxtとTypeScriptを使う時、`fetch`と`asyncData`の引数 `context` の型がなくて困った経験ありませんか？

Nuxtではコアパッケージの1つである`@nuxt/vue-app`というパッケージが `context` の型を提供しています。

```ts
import { Context } from '@nuxt/vue-app';
import { Component, Vue } from 'nuxt-property-decorator';

@Component
export default class SampleComponent extends Vue {
  /** Lifecycle */
  async asyncData(context: Context): Promise<void> {
    const { app, store } = context;

    // プラグインにもアクセスできる！
    app.$plugin.run();

    // VuexにDispatchできる！
    await store.dispatch('user/checkAuth');
  }
}
```

これで、`context: any`や独自のインターフェースの定義が不要になります。

（ドキュメントのどこにも記載がないのはなぜなんだろうか・・・？）
[備忘録] nuxt-property-decorator使用時にwatchQueryプロパティを使用する

備忘録のためコードのみ
あとで直したい

#コード

```vuejs
<template>
  <article class="hoge-page">
    <div>
      {{hogehoge}}
    </div>
    <nuxt-link :to="/hoge?page=2">2ページへ</nuxt-link>
  </article>
</template>
​
​
<script lang="ts">
import { Component, Vue, Prop } from 'nuxt-property-decorator'
​
@Component({
  components: {},
  watchQuery: ['page']
})
export default class Hoge extends Vue {
​
  hogehoge:string = '初期値'
  mogemoge:num[] = []
​  
  //SSR時とnuxt-linkが押下時に実行される
  asyncData({ query }) {
    const pageNum = !query.page? 1 :query.page //クエリーがあればその数値を、なければ1を代入
    const data = hogehogeApi
      .fetch(pageNum)
      .then(res => {
        return {
          //上で定義したdataに上書きされる
          hogehoge: res.hogehoge,
          mogemoge: res.mogemoge
        }
      })
      .catch(e => {
        console.log(e)
      })
    return data 
  }
}
</script>
```
HerokuでPostgreSQLに接続できないとき

# 事象
- PostgreSQLに接続しようとして、`no pg_hba.conf entry for host "xx.xxx.xxx.xxx", user "xxx", database "xxx", SSL off`のようなエラーが返ってくる

## 対処
- 環境変数を追加しましょう。これでＳＳＬ接続になり解決します。
```
PGSSLMODE:require
```
[Vue.js] iOS Safari のPWAを常に最新の状態に保つようにする [Amplify]

# iOS Safari の PWA のキャッシュが強すぎる

キャッシュが強いというよりはリロードをしてくれないので変更を検知してくれません
（2019/08現在）

外からどうにかすることができないので中からなんとかするかSafariのUpdateを待つしかありません。

# 中から強制的にリロードする

```js
window.location.reload(true)
```

これを使えば内部でリロードを発生させることが可能。
setIntervalと組み合わせて1日毎にリロードさせるコードをApp.vueに記述することで一応実現可能

```js:App.vue
created () {
    setInterval(() => {
      window.location.reload(true)
    }, 24*60*60*1000)
  }
```

# デプロイされた時だけリロードする

毎日リロードすると新しいバージョンはロードされるが、

- **いらないリロードが発生してしまう**
- **Intervalの分だけ反映が遅れてしまう**

という欠点がある。

なので新しいバージョンがデプロイ成功時のみ反映するようにしたい

# Amplify Consoleのメール通知機能
現在、Amplify Consoleを用いてデプロイしています。
そこで何かしらデプロイ情報と紐付けられるものがないかと探してみたところ、メール通知機能があることに気付きました。
デプロイ成功時にあらかじめ登録しておいたメールアドレスに送信されるようになっています。

<img width="1017" alt="スクリーンショット 2019-08-08 15.02.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166345/66ad2bc1-89e0-c184-7f16-0c9afd67a94f.png">


アプリケーション側で受信メールを監視する仕組みがあれば必要な時にだけリロードすることを実現できます。

構成は以下の図の通りです。

<img width="629" alt="スクリーンショット 2019-08-08 14.54.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166345/358606fc-92ed-8072-8b6d-124ce47dfe08.png">


詳しくは書きませんが流れとしては

```
$ amplify function add

// 適当にfunctionを作成
// Expressを使って実装


$ amplify api add

// lambda functionを選択
```

LambdaではExpressを使ってAPI実装
それをAmplify側で叩けるようにAPIを追加する

これと同じようなことを以下のサイトでやられているのでそちらを参考にしてもらえると有り難いです。
余裕があれば書こうと思っています。

[[DevelopersIO] Amplify で お問い合わせフォーム を作ってみた](https://dev.classmethod.jp/etc/amplify-inquiry-form-101/)


# 終わりに
9月頃には完全に対応するという噂があるのでそれを期待しましょう
もっとスマートに実現できるよ！とかそもそも可能だよって場合は教えていただけると嬉しいです！
grunt + javascript を webpack + babel で動作するようにする


## 概要
babel(トランスパイラ)
webpack(モジュールバンドラ/ビルドヘルパー)で動くようにする

## 前提
 - node
    - v10.16.1
 - JavaScript
    - Pure JavaScript

webpack を導入したい
babel を導入したい

## 手順
### babel
#### インストール
```
$ npm install -D babel-cli babel-preset-env
```

### webpack
#### インストール
```
$ npm install -D webpack webpack-cli
```

#### webpack.config.js の生成
```
$ ./node_modules/webpack/bin/webpack.js init

# パスを通せば下記でよい
$ webpack init
```

下記が自動生成されたwebpack.config.js

```webpack.config.js
const path = require('path');
const webpack = require('webpack');

/*
 * SplitChunksPlugin is enabled by default and replaced
 * deprecated CommonsChunkPlugin. It automatically identifies modules which
 * should be splitted of chunk by heuristics using module duplication count and
 * module category (i. e. node_modules). And splits the chunks…
 *
 * It is safe to remove "splitChunks" from the generated configuration
 * and was added as an educational example.
 *
 * https://webpack.js.org/plugins/split-chunks-plugin/
 *
 */

const HtmlWebpackPlugin = require('html-webpack-plugin');

/*
 * We've enabled HtmlWebpackPlugin for you! This generates a html
 * page for you when you compile webpack, which will make you start
 * developing and prototyping faster.
 *
 * https://github.com/jantimon/html-webpack-plugin
 *
 */

module.exports = {
	mode: 'development',
	entry: './src/index.js',
  target: 'node',
	output: {
		filename: '[name].[chunkhash].js',
		path: path.resolve(__dirname, 'dist')
	},

	plugins: [new webpack.ProgressPlugin(), new HtmlWebpackPlugin()],

	module: {
		rules: [
			{
				test: /.(js|jsx)$/,
				include: [],
				loader: 'babel-loader',

				options: {
					plugins: ['syntax-dynamic-import'],

					presets: [
						[
							'@babel/preset-env',
							{
								modules: false
							}
						]
					]
				}
			}
		]
	},

	optimization: {
		splitChunks: {
			cacheGroups: {
				vendors: {
					priority: -10,
					test: /[\\/]node_modules[\\/]/
				}
			},

			chunks: 'async',
			minChunks: 1,
			minSize: 30000,
			name: true
		}
	},

	devServer: {
		open: true
	}
};
```

## 動かしてみよう
webpack を実行して、babelでコンパイルしたソースをバンドルする

```
$ ./node_modules/webpack/bin/webpack.js

# パスを通せば下記でよい
$ webpack
```

## 最後に
なし
## 次回はこれ！
なし
mysql2をgemインストールできなかった時の対処方法

# 現象
Railsのプロジェクトで`bundle install`しようとしたところ下記のエラーが表示された

```
（省略）

-----
Setting libpath to /usr/local/opt/mysql@5.7/lib
-----
creating Makefile

current directory: /Users/*****/Documents/develop/project/vendor/bundle/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/*****/Documents/develop/project/vendor/bundle/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/*****/Documents/develop/project/vendor/bundle/gems/mysql2-0.5.2 for
inspection.
Results logged to
/Users/*****/Documents/develop/project/vendor/bundle/extensions/x86_64-darwin-18/2.6.0-static/mysql2-0.5.2/gem_make.out

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2
```

# 原因
`libssl.dylib`というライブラリが見つからないため
※エラー内容には明記されていないのになぜわかる？というのは参考にさせてもらったサイト「mysql2 gemインストール時のトラブルシュート」を参照ください

# 対策
下記を実行してから`bundle install`

```
cd プロジェクトのディレクトリ
bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
bundle install
```

上記の`--local`はこのプロジェクトに限り設定を保存するという意味になります。
`--global`にするとシステム全体の設定として保存されるのでプロジェクトが変わっても適用されるようになります。

また、うまくいかない場合は、 `brew info openssl`を実行して下記の部分が合致しているか確認してください。

```
For compilers to find openssl you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl/lib"
```



# 参考
[mysql2 gemインストール時のトラブルシュート](https://qiita.com/HrsUed/items/ca2e0aee6a2402571cf6)
[Bundlerでビルドオプションを指定する](https://qiita.com/thunders/items/101c6b329830fb1fb27d)
[bundle config | Bundler日本語ドキュメント | Ruby STUDIO](http://ruby.studio-kingdom.com/bundler/bundle_config/)
Windows 10 Version 1803インストール時のエラー「0xc1900130」を解決する方法

## そもそも
持ち運びしやすいサイズの2017年発売のNECのノートPCを手に入れたのですが、バージョンが**Windows 10 version 1703**という、まあ古いバージョンだったんです。
（現在最新バージョンが**Windows 10 version 1903**）
で、Windows Updateしようという流れになったわけです。

##Windows Updateを開いて...
「更新プログラムをチェックしています」
「更新プログラムをダウンロードしています」
⇒どっちも長い長い...
そんなこんなで**version 1709**は問題なく終了。
次は**version 1803**。更新プログラムのダウンロードまではよかったけど、インストールで「Windows 10、バージョン 1803 の機能更新プログラム - エラー0xc1900130」と表示されてインストールができない...。

##エラー「0xc1900130」
ググってみると、同じ目に合っている人が多数いました。
そこで発見して試して上手くいったのが以下の方法。

##解決方法
コマンドプロンプトを管理者権限で起動し、このコマンドを入力します。

```bash
SC config wuauserv start= auto 
SC config bits start= auto 
SC config cryptsvc start= auto 
SC config trustedinstaller start= auto
```
この**SCコマンド**はWindows OSのサービスを確認・操作するためのWindowsの標準コマンドです。
（更新プログラムのインストールが上手くいかないときにWindows Updateに関連したサービスを停止したり再起動したりするとうまくいく可能性が大きいです）

以下の画像のように上記コマンドを1行ずつ入力してください。
![コマンドプロンプト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295943/9fa3cca0-4513-bf7c-df32-71e3b430a1d3.png)

コマンドを実行してPCを再起動した後、再度更新プログラムのインストールを試したところ、やっと上手くいって、無事インストールすることができました！！

ほとんどの人がこの方法で上手くいっていますが、PC環境により上手くいくかは差異があると思うのでその点はご自身の責任でお願いします。

##追記
**version 1803**のインストールがついに成功したわけで、さて次のバージョンに更新しようと思って更新プログラムのチェックをすると、「最新の状態です」と表示された。
いやいや、最新のバージョンは**version 1903**だからw
ってなった後の対処方法はまた次回。
起動中のコンテナのメモリを制限する

こんちは

デフォルトでDockerエンジンが採用するサイズが大きすぎて、
起動中のコンテナのメモリを制限したいことがあるかと思います。

Dockerは、起動中のコンテナでもリソースを変更することができます。

まずは、現在の統計情報を確認

```bash
$ docker stats
```

```bash
CONTAINER ID        NAME           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
88ef7f56bd68        api            0.00%               11.6MiB / 15.56GiB    0.07%               13.1kB / 5.51kB     0B / 0B             18
32143219204f        db             0.13%               454.2MiB / 15.56GiB   2.85%               14.4kB / 5kB        4.1kB / 3.26MB      22

```

apiコンテナに15Gも要らなさそうですね。

これを500mに変更するには、

```bash
$ docker update --memory="500m" 88ef7f56bd68
```
とします。

再度確認してみます。

```bash
CONTAINER ID        NAME           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
88ef7f56bd68        api            0.00%               11.6MiB / 500MiB    0.07%               13.1kB / 5.51kB     0B / 0B             18
32143219204f        db             0.13%               454.2MiB / 15.56GiB   2.85%               14.4kB / 5kB        4.1kB / 3.26MB      22

```

ちゃんと制限されていますね。

docker updateは他にもいろいろできます。
https://docs.docker.com/engine/reference/commandline/update/


以上、よきコンテナ生活を。
トリガーの実行順序

トリガーの実行順序
1. 元のデータをロード、また初期化される。
2. 新しいレコードのフィールド値がロードされ、古い値を上書きする。
3. すべてのbeforeトリガーが実行される。
4. 検証ルールを含むシステム検証が行われる
5. 重複ルールが実行される。
6. レコードデータをデータベースに保存されるが、コミットはされない。
7. すべてのafterトリガーが実行される
8. 割り当てルールが実行される
9. 自動応答ルールが実行される
10. ワークフロールールが実行される
11. ワークフローフィールどが更新されたら、レコードがリロードされる
12. before,afterトリガーが再度1度だけ実行する
13. エスカレーションルールが実行される。
14. レコードが積み上げ集計項目をもっていたりクロスオブジェクトワークフローの一部である場合は、
親レコードの該当項目の値も更新
15. すべてのDML操作がデータベースにコミットされる
16. 電子メールの送信など、コミット後のロジックが実行される