OmniAICreator/Qiita-1.07M huggingface dataset:
Javascript基本集(6)~正規表現~

自分の学習用です:santa:

#正規表現とは
文字列の集合を一つの文字列で表現する方法で、
文字列に特定の文字が含まれているかを確認することや、特定の文字を取り除くなどの操作を行うための技術

**代表的な特徴**
・文字列の一部分を置換する
・文字列が制約を満たしているか調べる
・文字列の一部分を抽出する

##「RegExp」オブジェクト
正規表現の英名【Regular Expression】が由来となる。
JavaScriptで正規表現を扱えるようにするためには、まず**「RegExp」オブジェクト**を作成する必要がある。
RegExpオブジェクトを利用することで、正規表現による検索や置換など文字列操作を自在に扱えるようになる。

構文

```js
var reg = new RegExp( パターン, フラグ );//newでRegExpオブジェクトを生成して変数に代入
```
引数の「**パターン**」には一般的な正規表現を指定し、「**オプション**（g,i,mなど）」を指定する。

**パターン**
![FireShot Capture 224 - 【JavaScript】正規表現で文字列を検索する – 株式会社ライトコード - rightcode.co.jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580388/d2de00e6-fd76-f0ab-aa29-0e6c9608f7e3.png)
**オプション**
<img width="739" alt="スクリーンショット 2020-04-10 10.23.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580388/baebe016-0b7f-404e-69d3-e550d7d3fc7e.png">


正規表現の文字列指定には注意が必要であり、正規表現で一般的に使う「\d」「\w」などの**「\（バックスラッシュ）」はエスケープ処理と判断される**ため、対応策として「\\\d」や「\\\w」のように**２重で記述**する。 

```js
new RegExp('\\d\\d'); 
```
##メソッド一覧
###①RegExpオブジェクトから呼び出すメソッド

**execメソッド**
正規表現に合致する文字列を検索

```js
let string = 'abcdefgab';
let regexp = RegExp('[a-b]')
let result = regexp.exec(string);
console.log(result); // => [ 'a', index: 0, input: 'abcdefgab', groups: undefined ]
```
**testメソッド**
正規表現に合致する文字列が含まれているか判定する

```js
let string = 'abcdefgab';
let regexp = RegExp('[a-b]', 'g')
let result = regexp.test(string);
console.log(result); // => true
```

###②Stringオブジェクトから呼び出すメソッド　
**match メソッド**
正規表現に合致する文字列を検索できます。g オプションが有効の場合、合致する文字列の配列を返す

```js
let string = "ABCDEFGABCD"
let result = string.match(/[a-b]/gi);
console.log(result); // => [ 'A', 'B', 'A', 'B' ]
```
**searchメソッド**
正規表現に合致する文字列が最初にでてきた位置を取得する

```js
let string = "cdseabcde"
let result = string.search(/[a-b]/);
console.log(result); => 4
```
**replaceメソッド**
正規表現に合致する文字列を、別の文字列に置き換える

```js
let string = "123-4567";
let result = string.replace(/\d{3}-?d{4}/, '***-****');
console.log(result);
```
**splitメソッド**
正規表現に合致する文字列を区切り文字として、文字列を分割し。分割結果を配列として返す。

```js
let regexp = RegExp('[-\/\.]'); // '-', '/', '.' にマッチ
 
let string1 = '2019-04-10'
let result1 = string1.split(regexp);
console.log(result1) // => [ '2019', '04', '10' ]
 
let string2 = '2019/04/10'
let result2 = string2.split(regexp);
console.log(result2) // => [ '2019', '04', '10' ]
 
let string3 = '2019.04.10'
let result3 = string3.split(regexp);
console.log(result3) // => [ '2019', '04', '10' ]
```

##参考サイト
**正規表現リファレンス**
[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions)

**伊藤淳一さんのQiita**
[初心者歓迎！目と手で覚える正規表現入門](https://qiita.com/jnchito/items/893c887fbf19e17d3ff9#comments)

**正規表現一覧（チートシート）サイト**
[murashun.jp](https://murashun.jp/blog/20190215-01.html)

**javascript向け正規表現学習サイト**
[Scriptular](https://scriptular.com/)

**視覚的・正規表現出力サイト**
[Regexper ](http://regexper.com/#%5Cd%7B2%2C5%7D%5B-(%5D%5Cd%7B1%2C4%7D%5B-)%5D%5Cd%7B4%7D)
PHPの拡張モジュールが読み込めなくてぴえん。した話

# Composerのインストーラーを実行したらエラー。。。
・PHPのZendを利用するため、Composerのインストール
　　問題なく実行できると考えていたけど、下記のエラーが発生
　　php -v  (cmdで実行)
　　　PHP Warning:  PHP Startup: Unable to load dynamic library 'C:\php\ext\php_mysql.dll'
　 - 指定されたモジュールが見つかりません。 in Unknown on line 0
　　　PHP Warning:  PHP Startup: Unable to load dynamic library 'C:\php\ext\php_mysqli.dll'
　 - 指定されたモジュールが見つかりません。 in Unknown on line 0

　　Google大先生にお聞きするも、php.ini の記述と実際のファイルのパスが
　違うんじゃねーの？？？の一点張り。
　　**~~それはもう100回は確認したよ！！！！！~~**
　　
　　その後、iniファイルの記述を絶対パスにしたり、システム環境変数いじったり、
　再起動したりを２時間くらいガチャガチャやりましたが、解決せず。

#結論
　　**PHP「"C:\Windows\"にないと読み込めないよ～～><」ということみたい。**
　　なので、php.iniで拡張モジュールとして読み込んでいるdllファイルたちを、
　"C:\Windows"へコピー。その後もう一度 php -v を試すとエラーが出なくなりました。

#補足
　　　普段はphpをapache2.4に置いて、ブラウザから実行していたんですけど、
　　そこではエラーが起きず普通に拡張モジュールを使用できていたので
　　Composerのインストールを実行するまで気づきませんでした。
　　　**もっと良い解決方法(C:\Windowsに置くのはダサい気がする)がありましたら、
　　教えていただきたいです！！！！！！**
　　環境
　　　Windows10
　　　PHP 7.x
　　　Apache2.4
IQ Bot カスタムロジック関連処理まとめ

紙業務の自動化をサクサク進められるAutomationAnywhereの[IQ Bot](https://qiita.com/IQBotter/items/fab5f59230ff38a98bbd)。

取得したデータの品質を上げたり、後続処理をやりやすい形に加工・成型するのに便利なカスタムロジックに関連する記事をQiitaでちょこちょこ書いているので、一覧にまとめてみます。

#カスタムロジックの関連記事まとめ

##カスタムロジックの基本

**[IQ Bot のカスタムロジック 基本のキ](https://qiita.com/IQBotter/items/67694b1b0d1376ede7e7)**
↑初心者も上級者もまずはここから！

**[他の言語をやっていた人が初めてPythonを触ったとき、びっくりするかもしれない５つのポイント](https://qiita.com/IQBotter/items/3381346c40ae3a67fa34)**
↑Javaなど、Python以外のプログラミング経験がある人は、これを読めばスムーズにカスタムロジックには入れるはず！

##やりたいこと別・コピペ用コード集

### 置換・除外系（パターンの決まった文字化けの補正、空欄埋め、形式変換、ノイズの除外）

**[置換の基本](https://qiita.com/IQBotter/items/b1e7a75439fede2171e6)**

**[数値だけ／英数字だけを取り出す（正規表現を使った置換）](https://qiita.com/IQBotter/items/b380ab96e5bf8b0b1e57)**

**置換・除外をループで効率化するシリーズ**
- [除外をループで効率化](https://qiita.com/IQ_Bocchi/items/46269089b99c6f322687)
- [置換をループで効率化](https://qiita.com/IQ_Bocchi/items/83ae1dedfc1de6962006)
- [差し替え（ｘｘという文字列が含まれていたらｙｙに差し替え）をループで効率化](https://qiita.com/IQ_Bocchi/items/39ce46ca227145629d39)

### 取得したい文字列が特定の選択肢の中にある場合（決済方法、都道府県名など）

**[選択肢の中から最も近いものを答えにする（ファジーマッチ）](https://qiita.com/IQ_Bocchi/items/6ef6f63acd16a7051a03)**

**[選択肢の文字列を含んでいたらそれを答えにする](https://qiita.com/IQ_Bocchi/items/0674415a9bd984cf4a1e)**

### テーブルに関する処理

**[テーブルに関する処理いろいろ](https://qiita.com/IQ_Bocchi/items/b24fad1aa6b19aa17267)**

### その他

**[印影の重なった社名の補正](https://qiita.com/IQ_Bocchi/items/107f0ec20110d618838d)**

**[日付によくある読み癖の補正](https://qiita.com/IQBotter/items/86cc4e503cb51effe19e)**

**[スプリット（口座情報から銀行名や支店名だけを取り出す）](https://qiita.com/IQBotter/items/127aa72bfaf2b2571190)**

**[固定値の代入](https://qiita.com/IQBotter/items/190523b837ef64ba5a38)**

コード集は今後も増やしていく予定なので、増やしたらまた追記します。

##コードの仕組みを詳しく知りたい人向け

**[テーブル項目に対するおまじないコードを詳しく解説](https://qiita.com/IQBotter/items/68d3260c8afed7d27902)**


#まとめ

カスタムロジックを使いこなせると、IQ Bot の使いこなしの幅がぐっと広がります。

以下の記事とあわせ、ぜひこちらのまとめのブックマークをお願いいたします。

https://qiita.com/IQ_Bocchi/items/36dbe9adc4b8e70437bf

https://qiita.com/IQ_Bocchi/items/8d28f12256037b5f9058
VFX入門~ShurikenシステムからVFXの詰まるところ解説してみた①~

初めまして、taxiです。

この記事は、Shuriken(UnityのParticleSystem)に使い慣れたエフェクターが、VisualEffectGraphになんとかなじむことを目的にした記事です。　
以前、VisualEffectGraphを使い始めようしたときに、いきなりNodeを操作する画面に飛ばされ、「これは何からいじったらいいんだ・・・。」「これはShurikenでいうと、どの機能のことだ・・・？」と結構詰まった経験があります。

そこで、今回の記事ではShurikenユーザーの方に向けて、**ShurikenからVisualEffectGraphに入る人ならここはつまりそうだな**というものを紹介していきたいと思います。

[Shurikenの初期設定項目]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558933/2ce51eab-6809-e58c-eacb-bee83142b334.png)


[VFXの初期Node]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558933/414a068f-d673-7e94-0699-e073533e3414.png)

全体で説明するShurikenの項目はこちらです。(今回は、SpeedとVerocityの関係を中心に扱っています。)
・Main module
・Shape
・Velocity over LifeTime
・Size by Speed
・Triggers
・Sub Emitters

また、これらを**「Shurikenの項目 → VisualEffectGraphの項目」**の形式で説明していきます。
 
**<font color="red">Main module</font>**
**「Looping チェックボックスなし → Single Burst」**
Spawn コンテキストは、その名の通り「エフェクト発生時」の数などを設定するコンテキストです。
デフォルトの状態では「Constant Spawn Rate」が設定されており、その名の通り一定の数のエフェクトを出し続ける状態のことです。
ShurikenでいうRoop状態です。

これをRoopさせたくない場合(爆発などの一瞬で終わる系のもの)は、Spawn コンテキスト から「Single Burst」を使うと、呼び出したときの一瞬のみエフェクトが発火します。
(また、これらはEmissionにもかかわってくるので後述します)

**「Start Speed → Set Velocity」**

Shurikenで扱っていたStart Speedは、VisualEffectGraphではすべてVelocityで管理されます。
Velocityは、Initialie コンテキスト、Update コンテキストの中で主に設定します。 
試しに、Initializeコンテキストの中で「Velocity」ブロックを検索してみましょう。
すると、非常に多くのVelocity関連のNodeが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558933/2ab75b1d-2992-39ca-411f-51410a7d566a.png)

VisualeEffectGraph 初見の時はここで「どれを使えばいいんだ・・・」となりました。
なので、基本的な動きの場合には一番シンプルな「Set Velocity」を使えばいいと思います。
試しに、Initilize コンテキストの中で、「Set Velocity」を使ってみましょう。
**「Set Velocity Random」Nodeを削除し、「Set Velocity」Nodeを追加しさらに、数値を(X = 1, Y = 0, Z = 0)に設定します。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558933/affc8b6e-e1d7-d51a-f1b3-16d6c017b95e.png)

すると、エフェクトが発生されると、発生されたエフェクトごとに、X軸に対して1の速度が設定されます。

![velocity.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558933/cd22192d-df14-04d0-b1e1-30ec258959cd.gif)

また、徐々に加速させたい場合は、Update コンテキストの中で、「Add Velocity」Nodeを使います。また、数値を(X = 1, Y = 0, Z = 0)に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558933/aad844bb-6243-dddb-2f78-9f7f70bb90fa.png)

すると、以下のような速い流れのエフェクトとなります。

![add.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558933/0fe2d895-efe3-63c5-c365-dec1b1e3b105.gif)

Update コンテキストの中では、毎フレームNodeの影響が及ぼされ、かつ、「Add Velocity」は、先ほどの「Set Velocity」とは違い、速度を「追加」していくNodeなので、このような結果になります。

**最後に**
思ったよりも長くなりそうなので、今回はこの辺りでまでにしておきます。
次回は、TriggersやSub Emittersのあたりを紹介できたらと思います。
【JavaScript】非同期処理とはなんぞや

## はじめに
JavaScriptの初心者を脱出して最初に躓くのは恐らく**非同期処理**な気がします。
自分も見事につまずいているので、記事にまとめながら勉強していきます。

## 非同期処理とは
処理を待たずにどんどん処理を進めていきます。
遅いやつを待ってあげるような優しい奴ではありません、非情です。

```js
const fs = require('fs');

const file1 = fs.readFile('file1.txt')
const file2 = fs.readFile('file2.txt')
const file3 = fs.readFile('file3.txt')

console.log(`file1: ${file1}, file2: ${file2}, file3: ${file3}`)

```

動きません。

readFileは非同期処理です。file1君が処理を終えるのを待っているほどfile2君の気は長くありません。
それはfile3も同じです。結果として誰も成功できない。これが非同期処理です。

## 解決策
この誰も待ってくれない問題を解決する方法として**コールバック**があります。

```js
const fs = require('fs');

fs.readFile("file1.txt", function (err, hoge) {
    fs.readFile("file2.txt", function (err, fuga) {
        fs.readFile("file3.txt", function (err, foo) {
            console.log(`file1: ${file1}, file2: ${file2}, file3: ${file3}`)
        });
    });
});
```

これならみんな終わるのを待ってくれる優しいやつになります。
しかし、今回は処理が３つなのでまだマシですが、これが5,6,...と増えると、俗にいう**コールバック地獄**に陥ります。

## async awaitの登場
こんなコールバック地獄を解決してくれるのが**async await**です。

```js
const fs = require('fs');
const util = require('util');
// fs.readFileをPromise化
const readFileSync = util.promisify(fs.readFile);

async function readFiles(){
    var file1 = await readFileSync("file1.txt")
    var file2 = await readFileSync("file2.txt") 
    var file3 = await readFileSync("file3.txt") 
    console.log(`file1: ${file1}, file2: ${file2}, file3: ${file3}`)
}

readFiles()
```

asyncをつけられた関数は非同期処理を宣言し、Promiseを返すようになります。
awaitは、Promiseの処理が終わるまで**待つ**ようにするための処理です。
本来であれば、Promiseの処理がthenとcatchでチェーンしていきますが、awaitを使用することにより簡潔に書くことができますね。

## ちなみに

最初のコードは readFile を readFileSync にすることで解決できます。

```js
const fs = require('fs');

var file1 = fs.readFileSync("file1.txt")
var file2 = fs.readFileSync("file2.txt") 
var file3 = fs.readFileSync("file3.txt") 

console.log(`file1: ${file1}, file2: ${file2}, file3: ${file3}`)
```

async awaitを使いたかったので、util.promisifyを使用して無理やりasync awaitに組み込みました。

## おしまい
JavaScript、まだまだ難しい部分がたくさんありますね。
非同期処理の概要を掴む際の参考になれれば幸いです。
何か指摘事項等ございましたら、コメントやTwitterなどでお願いします。

[Twitter](https://twitter.com/hcr1s)
AWS Lambdaにpsycopg2でPython3.6からPostgreSQL へ接続

# Postgresインストール
非インストール版Zipファイルをダウンロード
https://www.enterprisedb.com/download-postgresql-binaries

```text:command
initdb -D C:\pgsql\data -U xxxx
pg_ctl -D C:\pgsql\data  -l logfile start
```
```text:createtable
psql.exe -d postgres -p 5432 -U xxxx
create database xxxxxx;
create table xxxxxx ........ ;
```
# ビルド環境準備
## pip更新
```
pip install --upgrade pip
```
## 必要なライブラリ
```text:CentOS
$ yum install postgresql-devel
```
```text:Debian/Ubuntu
$ apt-get install libpq-dev
```
```text:MacOS
$ brew install postgresql
```

# Lambdaデプロイパッケージ作成
```text:psycopg2をインストール
cd sample
pip install psycopg2==2.7.1 -t ./
```

```text:sampleフォルダー構成
lambda_function.py
psycopg2/
```
これを圧縮してZipファイルとしてLambdaにアップロードすることで完了。
PythonGUIによる簡易営業ツール作成:原価率計算

#PythonGUIによる簡易営業ツール作成:原価率計算
仕入金額(仕切金額)と販売金額(納入金額)を入力して、原価率を自動で計算します。
原価率を1から引くと利益率になります。

```
import tkinter as tk
root=tk.Tk()
root.geometry('300x200')
root.title('マージン')
def btn_click():
    x=float(txt_1.get())
    y=float(txt_2.get())
    z=txt_3.insert(0,x/y)
lbl_1 = tk.Label(text='仕切')
lbl_1.place(x=30, y=70)
lbl_2 = tk.Label(text='納入')
lbl_2.place(x=30, y=100)
lbl_3 = tk.Label(text='原価率')
lbl_3.place(x=30, y=130)
txt_1 = tk.Entry(width=20)
txt_1.place(x=90, y=70)
txt_2 = tk.Entry(width=20)
txt_2.place(x=90, y=100)
txt_3 = tk.Entry(width=20)
txt_3.place(x=90, y=130)
btn = tk.Button(root, text='実行', command=btn_click)
btn.place(x=140, y=170)
root.mainloop()
```
【cakephpエラー】Your requirements could not be resolved to an installable set of packages.


cake使おうとして出たエラーのメモ。


```
composer self-update && composer create-project --prefer-dist cakephp/app:^3.8 cms
You are already using composer version 1.10.4 (stable channel).
Creating a "cakephp/app:^3.8" project at "./cms"
Installing cakephp/app (3.8.0)
  - Installing cakephp/app (3.8.0): Loading from cache
Created project in /Users/miyamoto/Projects/sample/cakephp_sample/001HelloWorld/cms
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - cakephp/cakephp 3.8.9 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.8 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.7 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.6 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.5 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.4 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.3 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.2 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.10 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.8.0 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - Installation request for cakephp/cakephp 3.8.* -> satisfiable by cakephp/cakephp[3.8.0, 3.8.1, 3.8.10, 3.8.2, 3.8.3, 3.8.4, 3.8.5, 3.8.6, 3.8.7, 3.8.8, 3.8.9].

```

php入れ直しでいけた。


```
brew install --force php@7.3
brew link --force php@7.3
brew link --overwrite --dry-run php@7.3
```
急速なテレワークの普及とその影について～シャドーITとは～

# 簡単に自己紹介
私はSG・FE程度の資格しか持たないただの学生です。
と、前置きして予防線を張っておきます。（取得したの何年前だっけ...）

つまり、あまり専門的な事は知りません。現場で直面したこともありません。
この記事ではもっと浅い部分。
シャドーITを知ってもらうという事を念頭にガバ知識を披露すべく書いていこうと思います。

是非、間違っているところなどはコメントで指摘してください。


# シャドーIT is 何？

ところでシャドーITって聞いたことありますか？

影のITっていうんだから犯罪に使われるようなものを指しているんだなぁとか、
テレグラムとかの事を指しているんだなぁとか、
そもそも何？

と、感じる方も一定数いるかとは思います。
ただ、Qiita読んでる方の中には少なそうですが...。

シャドーITとは言ってしまえば、

個人が勝手に仕事に利用しているITサービス全般を指します。

IPAによれば
>「シャドーIT とは、「IT 部門の許可を得ずに、従業員又は部門が業務に利用しているデバイスやクラウドサービス」(平成 28 年度 春期 プロジェクトマネージャ試験 午後Ⅱ 問題より）のことである。」

と定義されています。


# そんな小難しい話分からねぇ！

今まで、事務作業ばかりで急にテレワーク！zoom！シャドーIT！なんて言われても
「は？」
と思う方もいるかもしれません。
簡単に具体的事例で説明していきたいと思います。

# やっていい事、悪い事

| 利用するサービス | やっていい事例 | 悪い事例 |
|:-----------------|:------------------|:------------------|
|クラウド保存サービス(Googleドライブ等)|IT部門の責任者がルールを決め、使用を促しているので、ルールに従って使う|USBとか持ち運ぶの面倒なので、クラウドサービスを使うのとは指示されてないし、Googleドライブに保存する|
|スマートフォン|個人所有のスマートフォンを業務使用するガイドラインに則って使用する|貸与されているスマートフォンの個人的利用は認められていないが、どうせバレないのでソシャゲやSNSをする|
|ビデオ会議ソフト(Skype、Zoom等)|急遽、テレワークをすることになったので、IT部門の責任者が作成したマニュアルに従ってWebサービスを用いたテレビ会議を行う|急遽、テレワークをすることになったので部門独自の判断でガイドラインを作成し、IT部門責任者の許可を取らずテレビ会議を行う|

適当にありそうな事例を3点ほどあげましたが、つまり

**IT部門の責任者の許可を取るまでサービスを使うな**

という事です。
また、禁止事項は意味がある禁止なので破らないようにしましょう。

~~逆に意味もない禁止事項がある場合はIT部門の責任者が能力のなさを晒していると思って嘲りましょう。~~

# まとめ

勝手に便利なサービスが目の前にあるからと言って使わないようにしましょうね。
大手の会社になればなるほど会社はクラッカーの脅威に晒されていると言われています。
実際、防衛装備などを開発する企業などはよく狙われているようです。

使いたければ、布教する。
便利さを知ってもらえれば、人間は便利な道具を使いたがります。
ただ、新しいよくわかんない道具は使いたがりません。
上手く布教すれば、個人で使っているツールをきっと会社全体でも使ってもらえるはずです。



では、学校のオンライン授業のサーバーを大量アクセスで落としてやりましょうかね！
【作成途中】プログラミング初心者がIotに挑戦してみた

プロトアウトスタジオという、プログラミングスクールではなく、プロトタイピングをアウトプットするというスクールに参加し始めた人の記事です。

第3回授業の宿題、「LINEbotとIoTを繋げる」については、obnizのボタン操作内容をLINEbotに出力させるまでで時間切れとなりました。。

```js

'use strict';

// obniz呼び出し
const Obniz = require('obniz');
var obniz = new Obniz("自分のID");  // Obniz_ID に自分のIDを入れます

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;

const config = {
    channelAccessToken: 'xxxxx',
    channelSecret: 'xxxxx'
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

// obniz接続
obniz.onconnect = async function () {
  obniz.display.clear();
  obniz.display.print("obniz meets LINE Bot!");
    //↓obnizの操作をトリガーにLINEに出力する
  obniz.switch.onchange = async function(state) {
        if (state === "push") {
          // 押されたとき
          console.log("pushed");
          // ディスプレイ処理
          obniz.display.clear();  // 一旦クリアする
          obniz.display.print("pushed");  // pushed という文字を出す
          var replyText ='ボタンが押されたよ';
          console.log(replyText);
    
          await client.pushMessage('Ud0e928eaf56d8ac9f4091fd3da585c00', {
            type: 'text',
            text: replyText,
             });
        };
    　//↑obnizの操作をトリガーにLINEに出力する
    };
}

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let mes = '';
  
  //↑LINEに入力した文字をobnizに出力するまで
  mes = 'obnizに表示するよ';
  client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
  console.log(event.message.text);

  obniz.display.clear();  // 一旦クリアする
  obniz.display.print(event.message.text);  // LINEで入力されたテキストをobnizに出力する
  //↑LINEに入力した文字をobnizに出力するまで
};


app.listen(PORT);
console.log(`Server running at ${PORT}`);
```
obnizの情報をLINEbotに渡して出力させるまでの導線はできているので、今後はボタン操作ではなくobniz側のセンサー検知結果等を渡せるようにします。
デプロイ後にjsが動かない件

###環境
**サーバサイド**
ruby 2.5.7
rails 5.2.4
**本番サーバ環境**
AWS(EC2,RDS,EIP)

###出たエラー
デプロイ後プリコンパイルをしたのにRailsアプリケーションのエラーが出て正しくページが表示されなかったため、確認。

```:ターミナル
$ sudo tail -f log/production.log
```
上記のコマンドでRailsのエラーログを表示。
タララララーっとエラーが出てきた中に下記のようなエラーを発見

```:ターミナル
（略）
F, [……] ActionView::Template::Error (The asset "〇〇.js" is not present in the asset pipeline.):
（略）
```
（jsがうまく読み込めてないのだな…）
下記の作業を行う。

```:ターミナル
$ vi config/environments/production.rb 
```
↑これの最後の行のendの前に

**config.assets.precompile += ['〇〇.js’]**

を入れる。

rails再起動

```:ターミナル
$ kill $(cat tmp/pids/puma.pid)
$ rails s -e production
```

jsが読み込まれましたとさ:relaxed:


おしまい
Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#14(移行)

Google Cloud Platform (GCP)のサービスで正式名称や略称はともかく、読み方がわからずに困ることがよくあるのでまとめてみました。


クラウド コンピューティング サービス  |  Google Cloud
https://cloud.google.com/?hl=ja



## まとめルール

まとめルールについては下記を参考ください。

Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#1(AI と機械学習/AI ビルディング ブロック) - Qiita
https://qiita.com/kai_kou/items/fa930eef23470c2f8f0b


## Amazon Web Services (AWS)のまとめはこちら！

Amazon Web Services (AWS)サービスの正式名称・略称・読み方チートシート - Qiita
https://qiita.com/kai_kou/items/cb29d261c8acc49fd22a

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #1 (コンピューティング) - Qiita
https://qiita.com/kai_kou/items/a6795dbab7e707b0d1a6


## 概要について

サービス一覧ベージの概要を引用しています。

プロダクトとサービス  |  Google Cloud
https://cloud.google.com/products?hl=ja#product-launch-stages


間違いや、こんな呼び方あるよーなどありましたらコメントお願いします！


## Migration - 移行

### GOOGLE BIGQUERY DATA TRANSFER SERVICE

BigQuery 用のフルマネージド データ インポート サービス。

- 正式名称: GOOGLE BIGQUERY DATA TRANSFER SERVICE
- https://cloud.google.com/bigquery/transfer
- 読み方: グーグル ビッグクエリ データ トランスファ サービス
- 略称: なし
- 俗称: なし


### CLOUD DATA TRANSFER

ネットワーク経由でデータを転送する、デベロッパー向けのコマンドライン ツール。

- 正式名称: CLOUD DATA TRANSFER
- https://cloud.google.com/products/data-transfer
- 読み方: クラウド データ トランスファ
- 略称: なし
- 俗称: なし


### Cloud Foundation Toolkit

Google Cloud をすぐに使い始めるのに最適なテンプレート。

- 正式名称: Cloud Foundation Toolkit
- https://cloud.google.com/foundation-toolkit
- 読み方: クラウド ファンデーション ツールキット
- 略称: なし
- 俗称: CFT
    - 参考: [cloud\-foundation\-toolkit/dm/templates at master · GoogleCloudPlatform/cloud\-foundation\-toolkit](https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/tree/master/dm/templates)


### Transfer Service

オンラインやオンプレミスのソースから Cloud Storage へ大規模なオンライン データ転送を行います。

- 正式名称: Transfer Service
- https://cloud.google.com/storage-transfer-service
- 読み方: トランスファ サービス
- 略称: なし
- 俗称: なし


### Migrate for Anthos

オンプレミスまたは他のクラウドにある VM を GKE のコンテナに直接移行します。

- 正式名称: Migrate for Anthos
- https://cloud.google.com/migrate/anthos
- 読み方: マイグレート フォー アンソス
- 略称: なし
- 俗称: なし


### Migrate for Compute Engine

特定の目的に合わせて設計された、エンタープライズ規模の Google Could へ移行します。

- 正式名称: Migrate for Compute Engine
- https://cloud.google.com/migrate/compute-engine
- 読み方: マイグレート フォー コンピュート エンジン
- 略称: なし
- 俗称: なし


### Transfer Appliance

大量のデータを Google Cloud に転送するためのラックマウント可能なストレージ サーバー。

- 正式名称: Transfer Appliance
- https://cloud.google.com/transfer-appliance
- 読み方: トランスファ アプライアンス
- 略称: なし
- 俗称: なし


### VM Migration

VM の移行は、Google Cloud を使い始める迅速かつ効果的な方法です。

- 正式名称: VM Migration
- https://cloud.google.com/vm-migrate
- 読み方: ブイエム マイグレーション
- 略称: なし
- 俗称: なし
ngrokでバーチャルホストを指定して公開する方法


15分はまったので備忘録的にまとめます。

`ngrok http api.example:3000`

というバーチャルホストに外部からアクセスさせたく、公開したもののうまくいかず
やり方を探していたら下記の通りみつかりました

<img width="429" alt="Screen Shot 2020-04-10 at 8.33.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160764/d1b43a7b-ce79-aadd-209a-97e7bdbee0e9.png">

もし `api.example` の `3000` ポートにアクセスさせたい場合は

`ngrok http -host-header=api.example 3000`

こちらのようになりますね。

これで実機からローカルのサーバーにAPIリクエストを送ってデバッグできます :relaxed:
ソースコードハイライトで遊ぶ

マウスオーバーすると識別子がハイライトされるようになったと聞いてやってみた。

```c
int a;
int b; // <--- Mouse Over Here !!!
int data[] = {
a,a,b,b,b,b,a,a,
a,b,a,a,a,a,b,a,
b,a,b,a,a,b,a,b,
b,a,b,a,a,b,a,b,
b,a,a,a,a,a,a,b,
a,b,a,a,a,a,b,a,
a,a,b,a,a,b,a,a,
a,a,b,b,b,b,a,a
}
```

雑にドット絵を描くときvimのシンタックスハイライトで似たようなことをしています。
MagicaVoxelのインストール方法［mac版］

# 0.もくじ
1. ダウンロード
2. インストール

# 1.ダウンロード

### [https://ephtracy.github.io]()にアクセス
<img width="1904" alt="スクリーンショット 2020-04-10 7.09.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/8ec88f58-c65f-be85-24e9-ca2b51c4f028.png">

### 『0.99.4』をクリック
<img width="1904" alt="スクリーンショット 2020-04-10 7.14.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/c687bcd3-db3f-768f-fcd2-9424ef7425e6.png">

### 『MagicaVoxel-0.99.4.2-alpha-macos.zip』をクリック
<img width="1904" alt="スクリーンショット 2020-04-10 7.15.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/0417ce06-21a4-7dcf-0ab9-8f5eb78c9232.png">

### ダウンロード完了！！

# 2.インストール

### Finderを開く
<img width="91" alt="スクリーンショット 2020-04-10 7.18.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/f3a6530a-ac40-60d5-8c7a-cf6d9b3ad7b8.png">

### ダウンロードフォルダを開き『MagicaVoxel-0.99.4.2-alpha-macos.zip』をクリックして解凍する
<img width="882" alt="スクリーンショット 2020-04-10 7.22.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/0b0e761f-f18d-f741-4150-31b6fe094692.png">

### 解凍してできたフォルダにダブルクリックで移動
<img width="882" alt="スクリーンショット 2020-04-10 7.27.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/25ad512c-b778-4c95-4cb2-380d845b4f26.png">

### MagicaVoxelを一度デスクトップに移し、元のフォルダに戻す。
MagicaVoxelのバグでMac版のソフトウェアは一度別のフォルダに移してから、元に戻す作業が必要です！
![pen.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/45668c34-dbce-ac42-9244-199b2c785f7a.gif)



### 『MagicaVoxel』をcontrolキーを押しながらクリックして開くを選択
![スクリーンショット 2020-04-10 7.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/bddee917-0bc3-4493-68b6-a6b7376e0b3b.png)


### 『開く』をクリック
<img width="590" alt="スクリーンショット 2020-04-10 7.56.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/686c9469-1fb8-517a-1603-356ffe8837b4.png">

### 完了！！
<img width="1118" alt="スクリーンショット 2020-04-10 8.00.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/414f8b61-8883-83d5-684c-452337246b04.png">

### フォルダごとアプリケーションに移すと、Launchpad(アプリケーション一覧)から簡単に開けるようにできます！
![application.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/13fbe08f-dccb-0cac-331a-72bcb42599ac.png)

<img width="1792" alt="スクリーンショット 2020-04-10 8.04.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134712/8dc52aa7-d887-6ac8-d74b-d4c0c8810807.png">
[C#] 拡張メソッドは、引数無しデリゲート型として関数に渡せない

わかる人にとっては、当たり前といえば当たり前だが、
地味に時間を使ってしまったので、備忘録としてメモしておく。

```csharp
static class TestExt
{
  public static bool IsTrue(this bool source) => source;
}
bool Func(Func<bool> func) => func();
bool IsTrue_Func() => true.IsTrue();
```

拡張メソッドは、ぱっと見、引数無しのデリゲート型（引数無しの関数）に見えるので、
以下のような呼び出しをしてしまったところ、コンパイルエラーとなった。
（拡張メソッドを引数無しの関数ポインタ的な取り扱いの感覚でコーディングしてしまった）

```csharp
//Func(true.IsTrue);
```

よくよく考えれば、上記のような拡張メソッドは以下の関数と同等であると考えれば
エラーとなるのも納得できる。

```csharp
//拡張メソッドは、以下と同等の為、引数無しデリゲート型として渡せないと思われる。
//Func(TestExt.IsTrue(true));
```
なので、下記の様にすれば問題はない。

```csharp
//以下は可能
Func(() => true.IsTrue());
Func(IsTrue_Func);
```

追記：
また、紛らわしい内容だったかもしれないので捕捉しますと、
当然、以下の内容で回避できます。

（@htsignさんのコメントより）

```csharp
bool Func(Func<bool, bool> func) => func(true);

Func(TestExt.IsTrue);
```

が、以下の様には渡せません。

```csharp
//Func(true.IsTrue);
//おそらく以下のように取り扱われているから？
//Func(TestExt.IsTrue(true));
```

元々、気軽に以下の様に渡そうとしていたので、
回避策はあるにせよ、もう少し上手くコンパイラが立ち回ってくれたらな
という身勝手な思いをつづってみた次第でございます。

```csharp
//Func(true.IsTrue);
```
JetBrains IDE を diff ビューアーとして使う

PhpStorm などの JetBrains IDE ではコマンドライン インターフェイスを使うことができます。そしてコマンドラインから diff ビューアーを使うことができます。

[公式ヘルプ](https://pleiades.io/help/phpstorm/command-line-differences-viewer.html) 

これは便利だ、と思って使ってみたところうまく動作しませんでした。
Mac の場合、利用するためには、いくつかの注意が必要です。

[コマンドラインインターフェイス](https://pleiades.io/help/phpstorm/working-with-the-ide-features-from-command-line.html) で説明されている設定をすることが必要です。手作業でスクリプトを作成した場合は問題ありませんが、Toolbox アプリで生成したシェルスクリプトを使うと期待通りに動作しません。

```
The file diff does not exist.
```

みたいなことを言われます。
Toolbox アプリで生成したスクリプトを確認してみます。

```
$ which phpstorm
/usr/local/bin/phpstorm

$ cat /usr/local/bin/phpstorm
#!/bin/sh
# Generated by JetBrains Toolbox 1.16.6319 at Fri Apr 10 06:30:46 2020

open -a "(中略)/PhpStorm.app/Contents/MacOS/phpstorm" "$@"
```

このスクリプトのオプションをヘルプ記載のものと合わせます。

```
open -na "(中略)/PhpStorm.app/Contents/MacOS/phpstorm" --args "$@"
```

以上で、実行できるようになりました。でも単純にヘルプの前半に記載しているスクリプトを書くほうが楽ですね。

```
#!/bin/sh

open -na "PhpStorm.app" --args "$@"
```

もう一点、注意点があります。ファイル名は相対パスで指定するとちゃんと開いてくれません。

```
phpstorm diff ./test.php ./test2.php
```

では、起動してすぐに終了します。

```
phpstorm diff ~/Documents/test.php ~/Documents/test2.php
```

のように絶対パスで指定します。
IBM i (旧AS400）の自己学習メモ０６　CLプログラム（Control Language） Part5　DCLF/RCVFでファイル操作

# 自己学習メモインデックス

[IBM i (旧AS400）の自己学習メモ　インデックス](https://qiita.com/You_name_is_YU/items/3964849e7803c8eaf767)

# 概要

CLプログラムによるファイル操作をやっていきます。
事前に、以下記事の動作確認用ファイルが作成済みであること。
[IBM i (旧AS400）の自己学習メモ０８　QTEMPにサクッと開発テスト用の一時ファイル作成（DDSを使わない１カラムテーブル）](https://qiita.com/You_name_is_YU/items/f6550ffb9fc474e933cd)

# DCLF/RCVFのサンプルプログラム

MSGIDで指定されているCPF0864は、RCVFコマンドで１レコードずつ読み込む際、End of Fileに到達すると発生するもので、そのメッセージを検知して、CLプログラムを終了させる処理を入れています。

```shell
 FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
        *************** Beginning of data ******************************************************************
0001.00              PGM                                                                                    
0002.00              DCLF       FILE(QTEMP/SAMPLE)                                                          
0003.00  READ:       RCVF                                                                                   
0004.00              MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(END))                                       
0005.00              SNDPGMMSG  MSG(&SAMPLE)                                                                
0006.00              GOTO       CMDLBL(READ)                                                                
0007.00  END:        ENDPGM                                                                                 
        ****************** End of data *********************************************************************
```

# 出力結果

```shell-session
sample data 1
sample data 2
sample data 3
```
【Rails6, haml】クラス名にindexをつける方法【each_with_indexまたはeach.with_index】

#やりたいこと
eachメソッドで並べるデータそれぞれのクラス名に番号を付けたい。
具体的には
  user_name_1
  user_name_2
  user_name_3
のような感じ。

#開発環境
ruby 2.6.5
rails 6.0.0


#コード例

```haml:hogehoge.html.haml
- @products.each.with_index do |product, index|
  %tr.results__table-row
    %td.results__table-row__name
      = product.standard_name
    %td{class: "results__table-row__price_#{++index}"}
       = (product.price).to_s(:delimited)

```

この部分ですね。

```haml
%td{class: "results__table-row__price_#{++index}"}
```

普通、hamlだとクラス名は`.hogehoge`としますが、
式の展開があるから？ `{class: "hogehoge"}`となっています。

文字列の中での展開なので、`#{~~}`はいつも通りですね。

したがって、

```haml
%td{class: "hogehoge_#{++index}"}
```
となります。

#ちなみに
each_with_indexの時はindexは０から始まり、
each.with_indexの時はindexは１から始まりますよ〜
【JSch】リモートFTPサーバー内でファイルをコピーするサンプル。

stackoverflowの下記の記事を参考にさせていただきました。
https://stackoverflow.com/questions/19869446/copy-a-file-on-remote-server-from-one-directory-to-other-using-jsch/25686815

````JSchSample.java
package hello;

import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpProgressMonitor;

@SpringBootApplication
public class Application {

	private static final Logger log = LoggerFactory.getLogger(Application.class);

	public static void main(String[] args) {
		SpringApplication.run(Application.class);
	}

	@Bean
	public CommandLineRunner demo() {
		return (args) -> {
			log.info("JSch Start");
			
		};
	}


	public void cp (String source, String target) throws Exception {
	    log.info("COMMAND: cp " + source + " " + target);

        String host = "172.20.10.2";
        int port = 22;
        String user = "user";
        String password = "パスワード";

        JSch jsch;
        Session session = null;
	    Channel upChannel = null;
	    Channel downChannel = null;
	    ChannelSftp uploadChannelSftp = null;
	    ChannelSftp downloadChannelSftp = null;
	    try {
	        jsch = new JSch();
	        session = jsch.getSession(user, host, port);
	        //known_hostsのチェックをスキップ
	        session.setConfig("StrictHostKeyChecking", "no");
	        session.setPassword(password);
	        session.connect();        

	        upChannel = session.openChannel("sftp");
	        downChannel = session.openChannel("sftp");
	        upChannel.connect();
	        downChannel.connect();
	        uploadChannelSftp = (ChannelSftp) upChannel;
	        downloadChannelSftp = (ChannelSftp) downChannel;
	        SftpProgressMonitor monitor = null; //???
	        InputStream inputStream = uploadChannelSftp.get(source);

	        downloadChannelSftp.put(inputStream, target, monitor);
	    } catch (JSchException e) {
	        log.error("Auth failure", e);
	        throw new Exception(e);
	    } finally {
	        if (upChannel == null || downChannel == null) {
	            System.out.println("Channel is null ...");
	        }else if (uploadChannelSftp != null && !uploadChannelSftp.isClosed()){
	            uploadChannelSftp.exit();
	            downloadChannelSftp.exit();
	            uploadChannelSftp.disconnect();
	            downloadChannelSftp.disconnect();
	        }else if (!upChannel.isClosed()) {
	            upChannel.disconnect();
	            downChannel.disconnect();
	        }
	        session.disconnect();
	    }
	}
}
````
skype for businessで別会社のユーザを会議に参加させる方法＋テレワーク活用Office365ツール（2020年4月時点）

安倍首相の緊急事態宣言を受けて生活が大きく変化しました。
会社も在宅勤務を推奨しており、出張も原則禁止。
その中で、顧客に不足を感じさせないように対応するため、
対応方法に四苦八苦しています。

#テレワークになってから活躍しだしたOffice365ツール
私の会社ではOffice365を利用していますが、
テレワークなってから活躍しだしたツールを3つ紹介します。

**１位　Skype for Business**
NO.1はなんといってもSkypeです。
社内はもちろん、別会社や顧客のと間の
オンライン会議でも大活躍しています。
一応、Teamsもあるのですが、
環境的な制約があってオンライン会議には
社内でもあまり使っていません。
Skypeは相手側がWebブラウザさえ使用できれば、
それ以外に何の準備も必要ないことが大きいです。
Microsoftさんは、Teamsに統合してSkypeは廃止する方針のようですが、
今回のコロナ対応の中で活躍してくれたツールとして、
私の心には残ると思います。

**２位　Yammer**
社内ではYammerが大活躍しています。
ほとんどの社員がテレワークとなり、初めてのことで戸惑っています。
解らないことが発生して、インフラ部門に聞いても、回答が返ってこず・・・
そんな中、色々な社員がYammerで実施できたことを投稿し始めました。
全社員がみれるので、とにかくYammerで分からないことは検索し、
何か新しい発見があれば投稿するような形になっています。
Office365ではTeamsがあるのですが、
こちらはプロジェクトで限られたメンバで
使用しているイメージで、いつもはこちらがメインになります。
しかし、このコロナ対応時期ではYammerが真価を発揮した感じです。

**２位　Microsoft Stream**
３位はStreamです。
今までなら解からないことがあれば、
社内で聞きにいけていましたが、
テレワークではそうはいきません。
ただし、メールやチャットでいちいち答えるのも大変です。
結果、画面操作方法を録画して
Streamにアップすることにしました。
これが、とても簡単で、解りやすい。
社内ツールとかの操作も録画しておけば、多くの人が閲覧できます。
ちなみに、この録画で活躍しているのもSkypeです。
ですから、Skypeは断トツ１位となります。

#Skype for Businessで別会社のユーザを会議に参加させる方法
ここからは、知っている人には釈迦に説法と思いますが、
知らない人のために接続方法を共有しておこうと思います。
自分の会社のSkype for Businessに別会社のユーザを参加させるための方法です。

###前提条件
①自分のPCにSkype for Businessがインストールされている
②別会社のユーザのPCでWebブラウザが利用可能
③自分と別会社間でインターネット通信が可能

###手順
①Skype for　businessで「今すぐ会議」を選択して会議室を作ってください。

②会議室画面で画面右下の以下のボタンをクリックします。
![Skypeボタン.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561572/7dc4f831-a0ee-7931-f26e-27ff61c898ef.jpeg)
③「会議参加情報」を選択してください。
![Skype.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561572/31fd6ad6-90ca-ac52-fef9-570abb47ab3e.jpeg)
④会議室のリンクが表示されます。「情報をすべてコピー」を選択してください。
![skype001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561572/21132219-7fad-91df-2458-356431b05f9c.jpeg)
⑤リンク情報を別会社のユーザにメール等で送付してください。

⑥別会社の方がWebブラウザにリンクを入れると会議に参加できます。

⑦なお、別会社の方が初めてアクセスする場合、以下の画面が表示されます。
「Skype会議アプリ（Web)をインストールして参加する」を選択します。
これは初回のみです。ユーザ権限でインストール可能です。
![SKYPE接続.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561572/e68f8479-c910-8863-7a9d-8a0ced1253f5.jpeg)

接続できれば、あとは普通のSkype会議と同じです。

この記事が誰かのお役に立てれば幸いです。
【Spring Boot】Spring Bootでwebアプリを開発、独立したTomcatサーバーへwarを配置する場合の注意点

####Spring Boot開発で、warのみ別APサーバーへ配置した経験がなかったので、調べた内容をメモしておきます。

以下、@TEBASAKIさん投稿の下記記事から抜粋させていただきました。
[Spring Boot解説第4回\(開発環境編：warファイル作成\)](https://qiita.com/TEBASAKI/items/7a22c8b6ac6eb5f1c304)
※Spring bootのバージョンにより、build.gradleの記述方法が異なる様なので注意ください。

####1. プログラム修正
- ApplicationクラスへのSpringBootServletInitializerの継承追加。
- SpringApplicationBuilderメソッドのオーバーライド。

####2. build.gradleの修正

- Spring bootでwebアプリを開発する際、単純にビルドしてできたwarには、組み込みTomcatが含まれてしまう。これを回避する定義を追加する。


####3. Gradleタスク（war）実行

- Gradleタスク（war）を実行して、warを作成する（{ProjectName}\build\libs に生成される）。

####4. Tomcatへの配置
- webappsフォルダにwarを置くだけ（自動で展開される）。
初心者によるプログラミング学習ログ 286日目

#100日チャレンジの286日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
286日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>286日目　1h<br>・昔つくったポートフォリオ改造（ほぼ書き直し）<br><br>寝落ちした・・・<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1248338389062975489?ref_src=twsrc%5Etfw">April 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
[GAS] GoogleAppsScriptを使ってメールとチャットワークに定期的にリマインダを送る

業務上、毎週確認したいことがあり、メールで定期的にリマインダを送りたいな、と思いました。

以下を参考にすると、10分ちょっとで実現できました。

【初心者向けGAS】面倒なことはライブラリに任せよう！その概要と追加の方法
https://tonari-it.com/gas-library/


加えて、チャットワークでも送りたいな、と思いました。

これは以下の記事で。

【初心者向けGAS】Chatworkのマイチャットにメッセージを送る最も簡単な例
https://tonari-it.com/gas-chatwork-send-message-mychat/

```JavaScript
function myFunction() {
  let MailData = SpreadsheetApp.getActiveSheet();
  let Mail_To = MailData.getRange("A2").getValue();
  let Mail_Title = MailData.getRange("B2").getValue();
  let Mail_Body = MailData.getRange("C2").getValue();
  let token = MailData.getRange("I2").getValue();    //チャットワークのtokenをセル"I2"に配置した場合
  MailApp.sendEmail(Mail_To, Mail_Title, Mail_Body); //メールに送る
  sendChatwork(Mail_Body,token); 
}

function sendChatwork(body,token){
  const cw = ChatWorkClient.factory({token: token});
  cw.sendMessageToMyChat(body);
}
```

Slackに送りたい方はこちら
https://qiita.com/chihiro/items/c7b11abc78f5d806c3a8

以上で完了です。便利ですね。
XAMPPでのinnodb_strict_mode=OFF設定

レンタルサーバーもPHPが7.3が当たり前になってきてくれたのでXAMPPを新しくしたらDBに不具合が出たのでちょっと調べた記録。

XAMPP
10.4.8-MariaDB

あれこれ文句を言われているXAMPPですが、Windows環境で使ってる分には大変気楽に設定（もほぼ必要無いけど）出来て良い物です。

ですが今回少し古いMySQLからのmysqldumpでのバックアップがXAMPP環境で戻せなかった（エラーが出た）ので解決しました。

エラーの内容は・・・

```
ERROR 1118 (42000) at line 657: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
```

って奴です。

要するにTEXT型やBLOB型のカラムが多いとテーブル管理サイズを超えてしまうのでエラーになってるって言う事です。
これ自体は実際は調べるとまず最初にinnodb_strict_modeをOFFにする事が出てくるのに気がつきます。

XAMPPですので
```xampp/mysql/bin/my.ini```
に対して
```innodb_strict_mode=OFF```
を加える物なのです。

XAMPPコントロールパネルからは何事も無くMySQLは起動します。

しかし実際にMySQLにログインして見てみても・・・

```
MariaDB [(none)]> SHOW VARIABLES LIKE 'innodb_strict_mode';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_strict_mode | ON    |
+--------------------+-------+
1 row in set (0.001 sec)
```

そう、この「MariaDB」がガン？であり実際調べても情報が見つかりにくかったです。

結果だけ書きます

先ほどの```My.ini```に対しての付け加え方が

```
[mariadb]
innodb_strict_mode=OFF
```

と[mariadb]ブロックを作成してそこに記載するする必要があったんですね。
他の設定をしていたら既に[mariadb]ブロックが有るかもしれませんのでそこに続けて書けば良いと思います。

その後再起動させ、MySQL(MariaDB)にログイン後コマンドを叩くと・・・

```
MariaDB [(none)]> show variables like 'innodb_strict_mode';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_strict_mode | OFF   |
+--------------------+-------+
1 row in set (0.001 sec)
```

良かった。ちゃんと変更されました。

その後mysqldumpでのバックアップもエラーも出ずにちゃんとインポートできました。

実際XAMPPがいつからかMySQLではなく互換のMariaDBになっていたのは知ってましたが設定まで変わるところがあるとは思ってませんでした。
特に初心の方とかは悩んでしまうかもしれませんので今回記録に残しておきます。
カメラ座標（NDC）

###カメラ画角のボックス
カメラの空間はNDC(normal device coordinates)と呼ばれ、カメラから見てX,Y軸は0～1、Z軸はマイナスを使ってカメラの距離を表す
ボックスの中心が基点のままなので{0.5, 0.5, 0}にオフセットしてスケールを掛けれるように左端を基点に変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615517/f342f2c5-03b6-3b6d-9824-56e9e3ae124c.png)

```c#:wrangle
vector offset = {0.5, 0.5, 0}; //カメラの縦と横が0-1に対してカメラの中心を基点（0.5,0.5）に
vector cameraScale = set(ch("camera_X"), ch("camera_Y"), 1);
if (@group_near)  @P = set(@P.x, @P.y, ch("near")*-1); //near(Z軸)の距離
if (!@group_near) @P = set(@P.x, @P.y, ch("far")*-1);  //far (Z軸)の距離
vector xformpos = @P *  maketransform(0,0, offset,{0,0,0},cameraScale,{0,0,0}); //縦と横の大きさ
@P = fromNDC(chs("camera_path"), xformpos); //カメラの空間にボックスを変換
```

###カメラ外のポイントを削除
カメラ外のポイントやプリミティブを削除するとエミッターのパーティクル数を減らせるなど作業の軽量化に役立つ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615517/146caacd-8449-401e-c65e-f8deaf2bafd7.png)

###一度もカメラ（アニメーション）に入っていないポイントを削除
キャッシュが重い時に手っ取り早く軽くする方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615517/8a397cdb-fda3-0823-e4f5-e8174f526830.png)


```
i@insideCamera = @Frame; //　カメラ内のポイントにフレーム数を設定
vector offset = {-0.5, -0.5, 0}; //カメラの縦と横が0-1に対してカメラの中心を基点（0.5,0.5）に
vector xformuv = @uv *  maketransform(0,0, offset,{0,0,0},{1,1,1},{0,0,0}); // カメラスケールをUVに適用
if ( xformuv.x < ch("camera_X")*-0.5 || xformuv.x > ch("camera_X")*0.5 ) i@insideCamera = 0; // 左右の画角外を後で削除できるように目印
if ( xformuv.y < ch("camera_Y")*-0.5 || xformuv.y > ch("camera_Y")*0.5 )  i@insideCamera = 0; // 上下の画角外を後で削除できるように目印
if ( @uv.z >= ch("far") || @uv.z  <= ch("near"))  i@insideCamera = 0; // 手前と奥の範囲外を後で削除できるように目印
```
[HIPファイル](https://github.com/DefultVFX/houdini/blob/master/cameraNDC.v2.hipnc)
ブラウザでAngularやReactを実行できるヤツだー！


はこです！こんにちわ！
今日は
**『ブラウザでさっくりとAngular/Reactを動かして確認したいんだよなー！できれば最新版（あるいは特定の版）で！』**
とか
**『StackOverFlowに質問を投げたりQiitaに書くときに問題が再現する最小で実行可能なサンプルを…！』**
とかの要望に使えるやつの話をします！
つまりブラウザで動きトランスパイルもしてくれるエディタの話です！


よさげな順に並べときます。


### StackBlitz
![sdk-github-project - StackBlitz 2020-04-10 03-35-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34573/0bf64d46-7dbb-a70f-1e9f-7d77b38372cc.png "sdk-github-project - StackBlitz 2020-04-10 03-35-21.png")

https://stackblitz.com/

Angular, React, Ionic, TypeScript, RxJS, Svelte
あとは Kendoとかも対応してる。

各プラットフォーム向けの対応がしっかりしてる＆軽くて早いのでオススメ。



GitHub同期は `https://stackblitz.com/github/[ユーザー名]/[リポジトリ名]` の形式。
GitHub同期わからん？上のURLと指定すると github参照してnpm installもして実行するんだよ！
実際に動くサンプルは [これ](https://stackblitz.com/github/gothinkster/angular-realworld-example-app)。
[このリポジトリ](https://github.com/gothinkster/angular-realworld-example-app) を参照して動いてる。



### CodeSandbox
![todomvc - CodeSandbox 2020-04-10 03-42-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34573/4307017c-8603-c9c3-946f-eb9805d5ad00.png "todomvc - CodeSandbox 2020-04-10 03-42-21.png")

https://codesandbox.io/

StackBlitzより対応フレームワークが多い(Vueとか)
StackBlitzより重い気がする。

対応フレームワークが多い分、各フレームワーク向けのカスタマイズが足りない気がする。
たとえば、Angularだとデフォで app.component.ts を開いてくれないとか、デコレータの使用についてLintに怒られたりとか。

GitHub同期はちょっと面倒でブランチ指定しなきゃいけないっぽい

https://codesandbox.io/s/github/reactjs/redux/tree/master/examples/todomvc

### NG RUN

![Angular demo runner 2020-04-10 03-32-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34573/c3972fd3-24b7-856f-361d-e0713e10f711.png "Angular demo runner 2020-04-10 03-32-08.png")

https://ng-run.com/about



Angular専用のオンラインエディタ。

ちなみに公開してるgithubのAngularプロジェクトなら、URL指定すると実行できる。
意味わからん？[こんな感じ](https://ng-run.com/github/alexzuza/clean-ng-cli813) にURL `https://ng-run.com/github/[ユーザー名]/[リポジトリ名]` 

すごいなー・・・。
これはなぜ完全に無償？

TODO: お金払わせてくれの画像

よく見るとFirebaseの無料枠で頑張ってる？のかな？


### Plunker
![starters: Starter templates for Plunker 2020-04-10 03-46-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34573/c4317a81-7b21-71a3-bab0-0a07bf2d8a81.png "starters: Starter templates for Plunker 2020-04-10 03-46-51.png")

https://plnkr.co/
老舗。
2020年に使うことは特に無いのでは…


### その他

#### Visual Studio Online

https://visualstudio.microsoft.com/ja/services/visual-studio-online/

ブラウザ上から VS Code相当のものが使えるやつ。
詳しくはこちらの Qiita記事で [Visual Studio Onlineで、ブラウザ上からVS Codeを使う【Public Preview】](https://qiita.com/suzuki_sh/items/7bf0465e727f56d1baf3)。
よくわからんがフルタイムで月$50 ってのはキツそう。夢はあるけど。




#### jsDo.it
https://jsdo.it/
![jsdo.it - Share JavaScript, HTML5 and CSS 2020-04-10 03-19-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34573/0dbb5f41-8756-734e-df2b-a9f7ddbd1af5.png "jsdo.it - Share JavaScript, HTML5 and CSS 2020-04-10 03-19-34.png")

R.I.P 
<img width="60" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34573/3d9cde75-4016-95d6-89d7-96c0d7d8afe9.png">
【CSS】background-image: urlは本番環境では画像が映らない

これローカルでは映っていたけど、いざ本番環境で見てみると何も映っていない...って方絶対いると思うのでその方と備忘録として

#何故本番環境では映らない？
これには海より深く山より高い...わけでもなく色々あってファイル名が変わっているからなんです。

##何故ファイル名が変わるのか
RailsではデフォルトでAsset Pipelineのdigestと言う機能があるんですけど普段はいい奴なんです。調べてもらえればわかります。ただいい奴すぎてファイルを更新するごとにファイル名が変わっちゃうんです。
で、ファイル名が変わると言うことはurlの後ろに書いてた画像のパスが違ってくるんです。
簡単に言うとa.pngがa1.pngになっちゃう感じ。
これじゃあ指定してた画像持って来れねぇわ。

##回避方法
もちろん回避方法は用意されていて結論から言うと

```
background-image: image-url(同じディレクトリなら画像のファイル名または画像のパス);
background: image-url(同じディレクトリなら画像のファイル名または画像のパス);
```

このどちらかで本番環境でも表示されるようになります。

もう一つ回避方法があってこちらは検証してないですが参考までに
もしかしたらMacだけかも

##違う回避方法

```terminal
$ vim config/environments/production.rb
```

```config/environments/production.rb
config.public_file_server.enabled =      #before

config.public_file_server.enabled = true #after
```

これでいけるみたいです。

ではこれにて
CakePHPのvirtualFieldSeparatorを変更する

## はじめに
- **これはバッドノウハウです**
- 諸々の事情で**どうしてもこれしか方法がない！**という場合の最終手段です
- CakePHP3.x以降では仮想プロパティに置き換えられたため、この方法は使えません  
※参考 [afterFind イベントやバーチャルフィールドはありません](https://book.cakephp.org/3/ja/appendices/orm-migration.html#afterfind)

## TL;DR
- virtualFieldSeparatorが含まれるテーブルカラム名があると結果セットが想定通りにならない
- virtualFieldSeparatorを変更することで想定通りの結果セットを得られる
- 正しい対応方法はテーブルカラム名を修正できるならする、カラム参照しているコードも修正する（なのでバッドノウハウ）

## 結論
```php
$db = $this->getDataSource();
$db->virtualFieldSeparator = "___";
$res = $db->query("
  SELECT hoge_table.id, hoge_table.item__1, fuga_table.item_2 
  FROM hoge_table 
    LEFT JOIN fuga_table ON hoge_table.id = fuga_table.id
  WHERE hoge_table.id = 100"
);

var_dump($res);
/*
[0] => Array
  (
    [hoge_table] => Array
      (
        [id] => 100
        [item__1] => hoge
      )
    [fuga_table] => Array
      (
        [item_2] => fuga
      )
  )
*/
```


## virtualFieldSeparatorとは
- CakePHP2.xに実装されたvirtual fieldという機能で使用する
- SELECT句で別名定義したカラムを結果セットの配列で任意のテーブルへ含めるための命名ルール`テーブル名__カラム名`の`__`のことです

例えば、以下のクエリではfieldsにSQL関数を書いた場合、モデル名の下にSQL関数の結果が入ります

```php
$res = $this->query("SELECT id, CONCAT(item1, item2) as item FROM hoge_table WHERE id = 100")

var_dump($res);
/*
[0] => Array
  (
    [hoge_table] => Array
      (
        [id] => 100
      )
    [0] => Array
      (
        [item] => hoge
       )
   )
*/
```

virtual fieldの命名ルールを使うと`hoge_table`以下にまとまります

```php
$res = $this->query("
  SELECT id, CONCAT(item1, item2) as hoge_table__item 
  FROM hoge_table 
  WHERE id = 100"
)

var_dump($res);
/*
[0] => Array
  (
    [hoge_table] => Array
      (
        [id] => 100
        [item] => hogefuga
      )
  )
*/
```

以下のようなカラム名の場合、意図せずvirtual fieldの命名ルールに該当してしまい、想定と異なる結果セットとなってしまいます

```php
$res = $this->query("
  SELECT id, item__1 
  FROM hoge_table 
  WHERE id = 100"
)

var_dump($res);
/*
[0] => Array
  (
    [hoge_table] => Array
      (
        [id] => 100
      )
    [0] => Array
      (
        [item__1] => hoge
       )
   )
*/
```

カラム名が変更できれば`item__1`を`item_1`などに変更するのが一番いい対応方法になります。
とはいえ、稼働中のソフトウェアであればDBのカラム変更は影響範囲も大きく、場合によっては稼働停止してメンテナンスする必要があるかもしれないため、場合によってはカラム変更が現実的にできない場合もあるでしょう。

次善策としてはカラムに別名をつける、が挙げられそうです

```php
$res = $this->query("
  SELECT id, item__1 as item_1 
  FROM hoge_table 
  WHERE id = 100"
)

var_dump($res);
/*
[0] => Array
  (
    [hoge_table] => Array
      (
        [id] => 100
        [item__1] => hoge
       )
   )
*/
```

別名で回避できるならそうしたいところですが、対象カラムが多いと参照箇所も比例して多くなり、コードの修正やテストに時間がかかることが予想されます。
このような事象が問題と認識されずに開発が進み、リリース間近になってレビューで指摘されて修正時間がない、というような状況で特定の機能だけは想定通りの結果セットでないと設計上問題がある、のような特殊な状況においてはvirtualFieldSeparator自体を一時的に変更することで他機能への影響なしで対応することができます。

本記事では"__"(デフォルト値、アンダースコア2個)から"___"(アンダースコア3個)に変更することでvirtual field命名ルールを変更しています。
virtualFieldSeparatorの変更はこのセッションでのDB Connection closeまで有効となり、他セッションでには影響しません。

```php
$db = $this->getDataSource();
$db->virtualFieldSeparator = "___";
```

このような反則的な対応をしないようにDB設計やソースレビューを細分化するなどで早期発見して本来あるべき対応方法になるようにすることが大切だと骨身に染みました。
Rollup + TypeScript で @rollup/plugin-sucrase にしたら 10倍 速くなった

Sucrase 神すぎる。

超適当な例ですが、 `@rollup/plugin-typescript` に比べて10倍速くなりました。
ソースコードはこちら。https://github.com/acro5piano/rollup-typescript-compare

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103885/b7b3c14e-8fc3-073e-e45a-08b9b209f570.png)

別プロジェクトで使い始めましたが、そっちでもめっちゃ速いです。
Zoomのショートカットキー一覧 (Mac)

Zoomのショートカット一覧です。

##ミーティング
|説明 |Mac |Windows|
|:-----------------|:------------------|:------------------|
|ミーティングに参加|Command(⌘)+J||
|ミーティングの開始|Ctrl+Command(⌘)+V||
|ミーティングの終了|Command(⌘)+Q|Alt+Q|
|ミーティングをスケジューリング|Command(⌘)+D||
|画面共有を開始（直接共有）|Control(^)+Command(⌘)+S|Alt+S|
|自分のオーディオのミュート/ミュート解除|Shift(⇧)+Command(⌘)+A|Alt+A|
|ホスト以外の音声をミュートに設定（ホストのみ）|Shift(⇧)+Command(⌘)+M|Alt+M|
|ホスト以外の音声をミュート解除に設定（ホストのみ）|Shift(⇧)+Command(⌘)+U|Alt+M|
|プッシュして通話|Space||
|ビデオを開始/停止|Shift(⇧)+Command(⌘)+N|Alt+V|
|画面共有の一時停止/再開|Shift(⇧)+Command(⌘)+T|Alt+T|
|ローカルレコーディングを開始/停止|Shift(⇧)+Command(⌘)+R|Alt+R|
|クラウドレコーディングを開始/停止|Shift(⇧)+Command(⌘)+C|Alt+C|
|レコーディングの一時停止/再開|Shift(⇧)+Command(⌘)+P|Alt+P|
|スピーカー/ギャラリービューに切り替え|Shift(⇧)+Command(⌘)+W|Alt+F1(スピーカービュー) Alt+F2（ギャラリービュー）|
|ギャラリービューで前ページのビデオ参加者を表示|Shift(⇧)+P|PageUp|
|ギャラリービューで次ページのビデオ参加者を表示|Shift(⇧)+N|PageDown|
|参加者パネルの表示/非表示|Command(⌘)+U|Alt+U|
|ミーティング中チャットパネルの表示/非表示|Shift(⇧)+Command(⌘)+H|Alt+H|
|招待|Command(⌘)+I|Alt+I|
|手を挙げる/下げる|Option (⌥)+Y|Alt+Y|
|リモート制御を開始|Control(^)+Shift(⇧)+R|Alt+Shift+R|
|リモート制御権限を取り消す/放棄|Control(^)+Shift(⇧)+G|Alt+Shift+G|
|全画面モードを開始/終了|Shift(⇧)+Command(⌘)+F|Alt+F|
|最小化ウィンドウに切り替え|Shift(⇧)+Command(⌘)+M||
|フローティングミーティングコントロールの表示/非表示|Shift(⇧)+Option (⌥)+Command(⌘)+H||
|アクティブスピーカーの名前を読み取る|Command(⌘)+2||
|ミーティングコントロールを常に表示|Control(^)+]||

##チャット
|説明 |Mac |Windows|
|:-----------------|:------------------|:------------------|
|ジャンプして他のユーザーとチャット|Command(⌘)+K||
|スクリーンショット|Command(⌘)+T||
|チャットディスプレイサイズを大きくします|Command(⌘)++||
|チャットディスプレイサイズを小さくします|Command(⌘)+-||

##全般
|説明 |Mac |Windows|
|:-----------------|:------------------|:------------------|
|現在のウィンドウを閉じる|Command(⌘)+W||
|ポートレート/ランドスケープビューに切り替え|Command(⌘)+L||