OmniAICreator/Qiita-1.07M huggingface dataset:
gulpを使ったファイル監視のメモ

# はじめに
簡単なWebアプリケーションを作成する際の、gulpと各プラグインの設定メモです。

# 使用するプラグイン

```json:package.json
  "devDependencies": {
    "browser-sync": "^2.18.13",
    "browserify": "^14.5.0",
    "gulp": "^3.9.1", 
    "gulp-sass": "^4.0.2",
    "vinyl-source-stream": "^1.1.0"
  },
```
学習環境の都合、今回はgulp v3系を使用しました。

## ざっくりプラグイン詳細
- browser-sync: htmlファイルの変更を監視して更新時にブラウザのオートリロードを行う
- browserify: Node.jsスタイルのコードをブラウザ上で動く形に変換、require機能使いたい
- gulp: タスクランナー 
- gulp-sass: sassをcssにコンパイル
- vinyl-source-stream: browser-syncに必要

# 設定の流れ
1. npmやyarnを使ってプラグインをインストール(設定済のpackage.jsonがあればinstallするだけ）
2. gulpfile.jsにgulpの設定を記述

## gulpfile.jsの内容

```javascript:gulpfile.js
//プラグインの読み込み
var gulp = require('gulp');
var browserify = require('browserify');
var browserSync = require('browser-sync').create();
var source = require('vinyl-source-stream');
var sass = require('gulp-sass');

// gulpタスクの作成
// jsのビルド
gulp.task('build', function(){
  browserify({
    entries: ['src/app.js']
  }).bundle()
  .pipe(source('bundle.js'))
  .pipe(gulp.dest('dist/'));
});
// ブラウザ同期
gulp.task('browser-sync', function() {
  browserSync.init({
    server: {
      baseDir: "./", // 対象ディレクトリ
      index: "index.html" //indexファイル名
    }
  });
});
// ブラウザの更新
gulp.task('bs-reload', function () {
  browserSync.reload();
});
// Sassをコンパイルする処理
gulp.task('sass', function() {
  return gulp.src('src/scss/*.scss') // コンパイル元ディレクトリ
    .pipe(sass({outputStyle: 'expanded'})) // アウトプットスタイル（開発中なので可読性重視）
    .pipe(gulp.dest('dist/css/')); // コンパイル先ディレクトリ
});

// Gulpを使ったファイルの監視
gulp.task('default', ['build', 'browser-sync'], function(){
  gulp.watch('./src/*.js', ['build']);
  gulp.watch('src/scss/*.scss', ['sass']);
  gulp.watch("./*.html", ['bs-reload']);
  gulp.watch("./dist/*.+(js|css)", ['bs-reload']);
});
```

これでjs/scss/htmlファイルの編集をすると自動的にjsのビルド、sassのコンパイル、同期されたブラウザの更新が実行され、効率よく開発ができる。
これまで都度都度Command+Rをやっていたので感動的です。

## 参考　ファイルツリー
```
.
├── dist
│   ├── bundle.js
│   └── css
│        └── app.css
├── gulpfile.js
├── index.html
├── node_modules
├── package-lock.json
├── package.json
└── src
    ├── app.js
    └── scss
│        └── app.scss
```
treeコマンドの存在を初めて知りました。手打ちするところでした。

# 参考URL
- gulpとBrowserifyでJSをビルドしてみた　https://qiita.com/seanchas_t/items/96fbb63e5fe36f94a42e
- ざっくりbrowserify入門　https://qiita.com/fgkm/items/a362b9917fa5f893c09a
- treeコマンド　https://qiita.com/koshihikari/items/0906cd8e97b931714efe
AtCoder Beginner Contest 003

###A - AtCoder社の給料

(i + 1)が駄目コーダの片鱗を見せてる気がする。

```py
I = int(input())
O = [(i + 1) * 10000 / I for i in range(I)]
S = int(sum(O))
print(S)
```

他のAC

ビット反転 → ビット反転のマイナス打ち消しにより (+1)を実現。
また * 5000 ではなく、指数5e3を使用して5000を表現。

```py
print(-~int(input())*5e3)
```

:writing_hand:メモ
e3 は10の3乗 = 1000
e4 は10の4乗 = 10000
e5 は10の5乗 = 100000
AzureでVirtual Machineを作るだけ

タイトルが575ですね。

私は学生なので当然100ドル/12ヶ月Azure for Studentsのサブスクリプションを持っているのですが、何もしないまま1ヶ月が経過しようとしていたので、流石に100ドルを虚無に変換するわけにはいかぬと思い、とりあえずテスト用に仮想マシンをつくってみることにしました。
初心者が見たままやれるように大部分を省略していますが悪しからず。

## 作成手順


タブごとに示していきます。

#### 0. Azureポータルから「Virtual Machines」に移動し左上の「追加」をクリックする

Azureの学生用サブスクリプションを得ることができてポータルにたどり着けないという人は多分いないと思いますが念の為。
ポータルは[こちら](https://portal.azure.com/#home)です。

### 基本タブ

#### 1. サブスクリプションを選ぶ

学生の皆さんは当然Azure for Studentsですね。Starterの方はよくわからない…

#### 2. リソースグループ

作ってなければ適当にここで新規作成してしまいましょう。名前はTestとかでいいです。

#### 3. 仮想マシン名

仮想マシンの名前を決めます。なんでもいいです。

#### 4. 地域

デフォルトの米国西部2だと選びたいスペックの仮想マシンが選べないっぽいので米国中南部とかにしておきましょう。

#### 5. 可用性オプション

デフォルトのままでいいです(テスト用なら冗長性とか必要ないので)。

#### 6. イメージ

Windowsなんて動かすとお金がかかるのでUbuntu Server 18.04 LTSあたりにしときましょう。
CUIの扱いにも慣れるからまあいいでしょう。

#### 7. サイズ

マシンスペックです。選択するところで一番コストが安いやつを選びましょう。
「Standard B1ls 1 vcpu、0.5 GiB のメモリ」なんて表示されるようにしてください。
サイズを選ぶときに下の「選択」ボタンを押し忘れないようにしてください。

#### 8. 認証の種類

SSHはめんどくさいのでパスワードにしておきましょう。
やりたくなったらあとで新しくVMを作ってSSH認証にすればいいです。
既存のPW認証VMをSSH鍵認証に変更することってできるんだろうか…？

#### 9. ユーザー名

ログイン時に訊かれるユーザー名です。なんでもいいです。

#### 10. パスワード/パスワードの確認

ログイン時に訊かれるパスワードです。なんでもいいです。

#### 11. パブリック受信ポート/受信ポートを選択

「選択したポートを許可する」を選んで、SSH(22)にチェックを入れましょう。
これをしないと後々アクセスできなくなります。

### ディスク

「次へ」ボタンを押すとこのタブが表示されます。

#### 12. OSディスクの種類
「Premium SSD」にしましょう。デフォルトの場合はそのままでいいです。

### 確認および作成

ここまで終わったらあとは別にいじらなくてもいいので、「確認および作成」ボタンを押してこのタブに移りましょう。
今までにしてきた設定がここで表示されるので、間違っていないかを確認した上で「作成」ボタンを押しましょう。

## 接続手順

#### 1. デプロイ完了を待つ

「デプロイが終わりました」と表示されるまでしばらく待ってください。終わったら出てくる「リソースへ移動」ボタンをクリックします。

#### 2. コマンドをコピーする

画面が移ったときにはすでに起動しているはずなので、上の方にある「接続」をクリックして、右に出てくるウィンドウ(?)の一番下にある「VMローカルアカウントを使用してログインする」のところにある```ssh```から始まるコマンドをコピーします。右端にある紙が2枚重なったようなアイコンをクリックするとそれだけでコピーできます。

#### 3. ターミナル/コマンドプロンプトを開く

ターミナル(WindowsならコマンドプロンプトかPowerShell)を開きましょう。
MacのターミナルはF4を押すかタッチパッドを4本指で摘むように操作すると出てくるLaunchPad内の「その他」に入っています。
Windowsの場合はWindowsキーを押しながらRを押すと出てくる「ファイル名を指定して実行」のフォルダに```cmd```と入力するとコマンドプロンプトが、```powershell```と入力するとPowerShellが起動します。
PowerShellはコマンドプロンプトよりも若干高機能ですが、ここで使う分にはほとんど差を感じることはないのでどちらでも好きな方を選んで構いません。

#### 4. コマンドを実行する

先程コピーしたコマンド(```ssh ユーザー名@IPアドレス```の形になってるやつ)を貼り付けて実行します。
質問(yes/noで終わっているやつ)が出てきたら```yes```と入力してください。
設定したパスワードの入力が求められるので入力しましょう。
入力中に画面は変化しませんが、入力はされています。入力後Enterを押してログインできます。間違っていた場合はもう一度入力欄が出てきます。

#### 5. 接続完了

待っていると、英語の文章が表示されたあとで、緑色で表示された```ユーザー名@仮想マシン名```の文字列が現れます。これで正常に接続が完了しました。いろいろコマンドを調べて遊んでみましょう。

#### 6. 切断および終了

コマンド入力のところで```exit```と入力するとログアウトすることができます。
終わったらブラウザに戻って、仮想マシンを終了させましょう。

## 少しわかる人向けの注意

- デフォルトではIPアドレスは動的に変化するため、起動するたびコマンドの内容が変わります。Azure側からIPを静的にする(固定する)ことができるので、やりたい方はやっておきましょう。※追記:IPを固定しておくとお金がかかるようです。いまいちわかっていませんので少し調べてみます。
- 上の手順に完全に従って仮想マシンを作った場合、ポートが22番(SSH)しか開いてないことになります。遠隔操作で遊ぶ分には問題ないと思いますが、「Webサーバーを建ててホームページを作りたい」などといった用途では、HTTPSなど、他のポートも開けることになります。
- 仮想マシンを終了させないと、サブスクリプションに紐づく100ドルを無駄に消費してしまいますので、気をつけましょう。

もし次回があったらSSH認証やるかもしれないです。
How To Consume CloudFlare API Using Python

This tutorial help to access cloudflare Rest API Using Python 3.The cloudflare providing rest api to handle many operation which can you done via cloudflare dashboard.The Cloudflare’s API exposes the entire Cloudflare infrastructure via a standardized programmatic interface.

https://www.restapiexample.com/python/how-to-cloudflare-api-access-using-python/
Confluence(に限らず)ドラッグアンドドロップでJiraのチケット番号を取得する

Confluence画面にJiraの画面からチケットのURLをドラッグアンドドロップしたら、チケット番号(ABC-1のような)を取得できるような機能を作りたくなった。処理対象のチケット番号を、手入力ではなく画面からポイっとできるようにできれば、色々使い道はあると思う。(この内容はConfluenceに依存するわけではない)

#作るもの
(とりあえずのテスト用) 以下のような画面を用意して、Drop Ticket Linkのテキストボックスに、JiraからURLを含む何かをドラッグアンドドロップすると、チケットのリンクが取り出せるというものを作ってみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/a7d9fd2d-62b5-2a85-6988-b50c0d9a23bd.png)

# HTML部分
2つのテキストボックスを作り、それぞれIDを`link`、`key`と振っておく。動作はJavascriptで記述するので、ここでは特別な設定はしていない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/dc3f99ec-92cd-1a80-2f28-d43dfa5e441c.png)

```html
<form class="aui">
    <div class="field-group">
        <label for="text-input">Drop Ticket Link<span class="aui-icon icon-required">required</span></label>
        <input class="text" type="text" id="link" readonly="true">
    </div>
    <div class="field-group">
        <label for="text-input">Key</label>
        <input class="text" type="text" id="key" readonly="true">
    </div>
</form>

<script type="text/javascript">
...
</script>
```

## スクリプト部分
[MDNのドラッグアンドドロップの資料](https://developer.mozilla.org/ja/docs/DragDrop/Drag_Operations)を参考にドラッグオーバーした時に「リンク」に見えるようにする。ドロップしたら、URL形式か確認し、URLであればKeyに相当する部分を正規表現で抽出し、テキストボックスに表示する。ドラッグアンドドロップのAPIを使うので、会社で推奨の古いIEだと動かないかもしれないが、最近のChromeやFirefoxなら動くと思う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/34371f7a-3b1d-941a-3b6d-2c636b02381d.png)

```javascript
// HTMLとのつながり
const input = AJS.$('#link');
const output = AJS.$('#key');

// Jira URLの形(ここではlocalhost:10080/browse/{key})
const JIRA_URL = /localhost:10080\/browse\/(\w+-\w+)\?*\s*/;

// ブラウザによって、データタイプの表現が異なる。ChromeとFirefoxは以下で区別できる。
const SUPPORTED_TYPES= [
  'text/uri-list',
  'text/x-moz-url'
];

// テキストボックスにドラッグオーバーしたときの見た目の変化。
input.on( 'dragover', ( event ) => {
  event.originalEvent.dataTransfer.dropEffect = 'link';
  event.stopPropagation();
  event.preventDefault();
} );

// ドロップした時の動作
input.on( 'drop', function( event ) {
  let url = '';
  let key = '';

  // URLを含むか確認し、取得する
  const filtered = SUPPORTED_TYPES.filter( t => event.originalEvent.dataTransfer.types.includes( t ) );
  if( filtered.length ) {
    url = event.originalEvent.dataTransfer.getData( filtered[0] );
  }

  // 正規表現で該当するか確認し、インデックス1のKeyを取り出し、テキストボックスへ反映する。
  key = JIRA_URL.exec( url )[1];
  if( key ) {
    output.val( key );
  }

  event.stopPropagation();
  event.preventDefault();
} );
```

#動かした結果
動画ではないのでわかりにくいが、期待する動作になった。Chromeからのドラッグオーバー時は、Chromeのサムネイル表示と「リンク」のカーソルが表示された。(キャプチャしたらカーソルが消えてしまった)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/bf127c35-7c9e-af70-ac80-5661ddde483e.png)
ドロップしたら、キー(ここではSMP-1)がKeyテキストボックスに表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/05a79909-9e5e-f334-cd75-859423703e77.png)
Serverless Frameworkでdynamoのttlを設定するときはcloud formationを使う

## 経緯

QiitaやclassmethodでHitする記事だと `serverless-dynamodb-ttl` pluginを使うように紹介されているが、cloud formationに同一の機能が実装されたことによって現在このレポジトリはアーカイブされている。

> AWS CloudFormation supports now TTL, so this plugin for Serverless is useless. More information about how to use it in the AWS documentation.

repository
https://github.com/Jimdo/serverless-dynamodb-ttl

日本語の記事
https://dev.classmethod.jp/cloud/aws/enabling-dynamodb-ttl-with-serverless-framework-or-aws-sam/
https://qiita.com/sayama0402/items/28fe9b51b17c2bd66324

## Cloud formationで書こう

tableの定義部分に以下のように記載すればOK

```yaml
TimeToLiveSpecification:
  AttributeName: attr_name
  Enabled: true
```

全体の定義は以下の感じで書けばOK.

```yaml

    userTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: table_user
        AttributeDefinitions:
          - AttributeName: table_category
            AttributeType: S
          - AttributeName: id
            AttributeType: S
          - AttributeName: expired_at_unix_time
            AttributeType: N
        KeySchema:
          - AttributeName: table_category
            KeyType: HASH
          - AttributeName: id
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TimeToLiveSpecification:
          AttributeName: expired_at_unix_time
          Enabled: true
```

## 結論

pluginじゃなくて公式のcloud formation使おう。
Javascriptで特定文字列の存在確認は.text()メゾッドを使う。でも注意が必要

# 特定文字列の存在確認
javascriptで特定文字列の存在確認をするだけなら、速度的にtest()メゾットを使うのいいようです。
返り値はboolean

> あるパターンがある文字列内で見つかるかどうか調べたいときは、 test() を使用してください。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test

ただ注意が必要で、正規表現がグローバルフラグを持ってるかどうかで挙動が変わります。
lastIndexが加算されるので、繰り返しtest()メゾッドを利用する場合に、検索位置が変わりますので注意が必要です。

>regex がグローバルフラグを持つ場合、 test() は regex が所有する lastIndex の値を加算します。その後に続けて test() を呼ぶと、 lastIndex から続く str の 部分文字列を検索します (exec() も同様に lastIndex プロパティの値を加算します)。注目すべきは、別な文字列で検索しても lastIndex がリセットされないことです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/match


keyupイベントで、文字列のチェックをしていたときに、
正規表現にマッチする文字列があるにも関わらず、返り値がtrue/falseを繰り返すということが起こり
おかしいと思い調べたところ上記の仕様を知りました。
データをシャッフルしてクラスタリングで元に戻すやつ  Clustering Tips①

この記事は[古川研究室 Workout_calendar](https://qiita.com/flab5420/private/aee38a24be700d146817) 8日目の記事です。
#クラスタラベルで元データを並び替える
シャッフルされたデータをクラスタリングしてみると元に戻るんでしょうか。データにクラスタ構造があって、変なことしてなければ戻ります。動作検証に使えますね。
クラスタリングで得られるのはクラスタラベルです、`np.argsort()`を使って並び替えれば元に戻るかどうかを確認できます。並び替えはこんな感じです`X[np.argsort(clustering.labels_)]`
<img width="351" alt="スクリーンショット 2019-07-22 23.48.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75707/b927c662-f42c-6efb-dd08-b0db869ffef4.png">
元はこのようなデータでした。
<img width="350" alt="スクリーンショット 2019-07-22 23.49.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75707/f2598dc9-e954-a266-ef12-171d1bd250c3.png">

データの生成はこんな感じです。

```python
# toy data poisson
lm=1.0
n_node=100
n_cluster=4
adj = np.random.poisson(lm, (n_node, n_node))
adj_max = np.max(adj)
n_menber = n_node // n_cluster
mod = n_node % n_cluster
for s in range(n_cluster):
  s = s * n_menber
  e = s + n_menber
  adj[s:e, s:e] = adj_max * 5
  if mod != 0:
    adj = adj[-mod:, -mod:] + np.ones((mod, mod))

X = np.random.permutation(adj)
```

k-meansでやってみましょう。adjがシャッフル前のデータ、Xがシャッフル後のデータです。

```python
kmeans = KMeans(n_clusters=4, random_state=0)
kmeans_X = kmeans.fit(X)
sns.heatmap(X[np.argsort(kmeans_X.labels_)])
```
はい、元に戻りました。
<img width="348" alt="スクリーンショット 2019-07-23 0.06.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75707/ccbe2cbd-45a8-d541-a0ec-8f71e215a195.png">

スペクトルクラスタリングでもやってみます。分解するんで正規化しておきます。
<img width="349" alt="スクリーンショット 2019-07-23 0.22.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75707/613e0e34-7cb9-fc2e-e1cb-9a2e4f15e9da.png">

```python
adj_n = np.array([np.abs(v - np.mean(vec))/np.std(vec)  for vec in adj for v in vec]).reshape((100, 100))
X_n = np.random.permutation(adj_n)

sp_clustering = SpectralClustering(n_clusters=4, random_state=0)
sp_X = sp_clustering.fit(X_n)
sns.heatmap(X[np.argsort(sp_X.labels_)])
```
似たようなかんじですね、もどりました。
<img width="352" alt="スクリーンショット 2019-07-23 0.23.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75707/b0022d50-f0c0-fef8-0a49-b8a05227a724.png">

#コード
本記事は人工データつくるときに得られたTipsでした。ここで[コード](https://colab.research.google.com/drive/1DNGaN-IAFU06_D8cfvfzzKz4d4AgdIfq)を共有してます。Colabなんですぐ動かせます。adjとあるように隣接行列からBoWを生成するっていうコードでした。似たような状況で人工データを作りたい方はつかってください。
【XAMPP】PHP開発環境構築

##前提的なこと
###スキル
- サーバーサイドプログラミング歴ゼロ
- phpの知識ゼロ（業務でサーバーサイドエンジニアがHTMLに組み込んであるのを見かけるくらい）

###動機
とりあえずコンタクトフォームくらい作らなやばいと思い、業務の空き時間にググりながら作成。
本記事はその際の開発環境構築の備忘録です。

###やること
XAMPPをインストールしphpファイルをローカルで起動。

##XAMPPのインストール

###XAMPPのサイトからダウンロード

サイト：https://www.apachefriends.org/jp/index.html
自分はMacなのでOS X向けをインストールします。


![スクリーンショット 2019-07-23 0.28.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275686/5b827a0b-0b3b-ac18-e93a-ed8348cc720f.png)

インストールしたら、起動します。
会社のPCがWindowsだったんですが、Macとは結構UI違うんですかね？

とりあえず、StatusがStartなっているのを確認したら、下の画像で黒く塗りつぶしてるところにIPアドレスが記載されているのでそこにブラウザからアクセスします。
![スクリーンショット 2019-07-23 0.36.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275686/4906aa6d-5a33-5585-4499-1daf184c7d35.png)

アクセスして下の画像のように表示されたら、正常に起動できています。
![スクリーンショット 2019-07-23 0.41.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275686/aed415d8-c817-83b0-39ef-3a2f0e177d20.png)


次回の記事でコンタクトフォーム作成していくのですが、その際はApacheしか使わないです。
GeneralからStartすると全サービス起動しているんですかね？
Servicesからだと1つずつ起動できそうです。

##プロジェクトフォルダの配置場所
ドキュメントルート(/Applications/XAMPP/htdocs)以下に設置する。
接続時は、IPアドレス以下に、htdocs以下のパスを書き接続。
って思ったんですが、ディレクトリが見当たらない。

###変更あったらしい
参考：https://uzulla.hateblo.jp/entry/2017/10/26/001132

とりあえず、VolumesのMount押してExplore押したらディレクトリが出た。
おそらくそこのhtdocsに配置することになるかと...
![スクリーンショット 2019-07-23 0.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275686/f51493db-2b61-b091-dc8b-f0324bd726b8.png)
Ajaxで取得したモーダルコンテンツをキャッシュしてリクエストを節約

# モーダルコンテンツをキャッシュしてリクエストを節約
何かしらのデータの詳細画面を、Ajaxとモーダルを利用して表示することがあると思います。
その際、1のモーダルを開く->閉じて2のモーダルを開く->再度1のモーダルを開く、といったように、
同じデータのモーダルをなんども見るときに、毎回リクエストを飛ばすのは色々と非効率だと思うので、
キャッシュするようにしたのでメモ。

なお、Laravelでは、`request()->view()`で簡単にviewを返すことができるので
それを利用しています。(トレンドは、jsonを返すのでしょうが。。。)
https://laravel.com/docs/5.8/responses#other-response-types

---
- Laravel
- jQuery
- blade

---

リスト画面

```html:list.blade.php
<table>
  <tbody>
    @foreach ($arr as $k = $v)
      <tr>
        <td>
          何かしらのリスト
          下のようなボタンがある。
        </td>
        <td>
          <button type="button" class="open-modal" data-id="1">詳細を見る</button>
        </td>
      </tr>
    @endforeach
  </tbody>
</table>

{{-- モーダルコンテンツのラッパー --}}
<div id="modal">
</div>
```

レスポンスで返すview

```html:modal_contents.blade.php
<div id="modal_contents">
  {{dd($modalContents)}}
</div>
```

モーダル操作
1. モーダルを閉じるときに`$('$modal_contents')`のクローンを配列にキャッシュ
　※クローンを取る理由は、モーダル内で操作が行われ開いた時の状態とは変化している可能性のあるシステムであったため。
　※モーダルの変化がない場合は、responseを取得した時点でキャッシュしてもいいと思います。
2. モーダルを開くときに、キャッシュされてれば、それを利用し、なければリクエストを投げる

```javascript:modal.js
// モーダル開く
let openedModalContents = []; // キャッシュ用の配列
let currentId;
let canOpenModal = true;
$('.open-modal').on('click', function () {
    // ダブルクリック制御
    if (canOpenModal === false) {
        return false;
    }
    canOpenModal = false;

    let that = $(this);
    currentId = that.data('id');

    // キャッシュされていない場合
    if (openedModalContents[currentId] === undefined) {
        let modalContents = fetchModalContents(currentId);

        modalContents.then(function (response) {
            insertModalContents(response);
            $('#modal').addClass('is-active');
        }, function (error) {
            alert(error);
        });

        // キャッシュされている場合
    } else {
        insertModalContents(openedModalContents[currentId]);
        $('#modal').addClass('is-active');
    }

    canOpenModal = true;
});

// モーダル閉じる
$('.delete').on('click', function () {
    // キャッシュする
    let currentModalContents = $('#modal_comtents').clone();
    openedModalContents[currentId] = currentModalContents;
    $('#modal.is-active').removeClass('is-active');
});

/**
 * モーダルコンテンツを取得
 * @param {*} id
 */
function fetchModalContents(id) {
    return new Promise(function (resolve, reject) {
    $.get('api/modalContents/', {'id': id})
        .done(function (data) {
            resolve(data);
        })
        .fail(function (e) {
            reject('データの取得に失敗しました。');
        });
    });
}

/**
 * モーダルコンテンツをラッパーに挿入
 */
function insertModalContents(modalContents) {
    let modalContentsWrapper = $('#modal');
    modalContentsWrapper.html('');
    modalContentsWrapper.html(modalContents);
}
```
サーバーサイドの実装。モデルは適当です。

```php:ModalController.php
public function passModalContents(Request $request) { 
    $modalContents = Model::findOrFail($request->id);

    return response()
        ->view('modal_contents', compact('modalContents'))
        ->header('Content-Type', 'text/html');
}
```

ルーティングは省略
Maven 構成問題 が解決できない

[Spring Bootで「HelloWorld」まで](https://qiita.com/kf91122/items/632208e6f8a36628704f)
の続き。
# エラーを解消できない
動かす上では今のところ支障なさそうなんですが...
このエラーが解決できなくてもやもや
（画像が雑なのは気にしない気にしない）
![Maven構成問題エラーが解決できない.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/69b92e34-1bf5-0350-5cf3-f15e0fb60afb.png)

# 解決方法
SpringBootのバージョンかなーとか
Maven依存関係、色々入れてくれてるけどどこかにおかしいのかなーとか
考え見渡すもわからず...

「One IT Thing」さんのサイトに対策が書いてありましたーーー！
https://one-it-thing.com/2002/

同じくmaven-jar-pluginの最新版を見に行くも、変わらず3.1.2が最新
https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-jar-plugin
![maven-jar-plugin.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/65fdfaa1-0500-40a5-f60e-c5aab2a1bbfb.png)

というわけで、3.1.1にして無事エラー解消

# (おまけ)Mavenの依存ライブラリっていつダウンロードしてるの？
Pleiadesのバージョンとか関係なく、プロジェクトの[Maven]＞[プロジェクトの更新]を行ったタイミングで最新版を持ってきているのかな？

「maven-jar-plugin」の場所を探してみると...
ありました！
%ユーザのホームディレクトリ%/.m2/repository/ の下
![marven-jar-plugin.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/2e33b848-73ce-1000-010d-1aea5d9dee18.png)

3.1.1の更新時間がついさきほどなのでやっぱり[プロジェクトの更新]時か、実行時かな？
と思ったら違いました！

```xml:pm.xml
	<properties>
		<java.version>1.8</java.version>
		<!-- 追加 -->
		<maven-jar-plugin.version>3.1.0</maven-jar-plugin.version>
	</properties>
```
試しにpom.xmlを3.1.0に変更して保存(=ワークスペースビルド)のタイミングで取りに行ってくれたみたい。
![marven-jar-plugin2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/08f9b248-eb34-b9d7-137b-646d5c33bd52.png)
一瞬のできごと。
Mavenについても勉強していかなければですね。

# (おまけ)Springのバージョン確認
このプロジェクトを構成しているライブラリを確認
spring-boot：2.1.6
coreやwebやwebmvcなどいわゆるspring：5.1.8
![springバージョン確認.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281353/237cb2bc-06e0-c4c9-2a5e-1b1dcf9a6a2d.png)

おそらく。
IPアドレスのクラスを覚える

##IPアドレスのクラスが覚えられない
CCNAを勉強中ですが、なかなか覚えられず避けていたので今日覚える！

##先頭ビットで覚えていく
####クラスA
・大規模ネットワーク
・先頭ビットが**「0」**
・**0**0000001~**0**1111110(1~126)
・01111111(127)はループバックアドレスで除外

####クラスB
・比較的大規模ネットワーク
・先頭ビットが**「10」**
・**10**000000~**10**111111(128~191)

####クラスC
・中規模ネットワーク
・先頭ビットが**「110」**
・**110**00000~**110**11111(192~223)

####クラスD
・マルチキャスト用
・先頭ビットが**「1110」**
・**1110**0000~**1110**1111(224~239)

##プライベートアドレスも覚えられない
####クラスAのプライベートアドレス
・10.0.0.0～10.255.255.255


####クラスBのプライベートアドレス
・172.16.0.0～172.31.255.255



####クラスCのプライベートアドレス
・192.168.0.0～192.168.255.255



##まとめ
クラスはビットで見ていったら簡単に覚えることができました
プライベートアドレスに関しても
クラスA、クラスCのものは社内ネットワークや自宅などのネットワークでよく見る形だったので
覚えなきゃいけないのは実質クラスBのものだけだとわかりました
覚えるのめんどくさいと避けているものでも、整理してみると案外スッキリして覚えやすくなりますね
二分探索(python)

# 二分探索(python)

二分探索は、sort済みの配列の中にある値が存在するか調べるアルゴリズム。
調べる配列をステップごとに半分にしていくことで効率的に探索する。

探索が終了するまで以下の手順を繰り返すことで、$O(\log n)$のオーダーで見つけることができる。

1. 配列の真ん中の要素mと比較し、探している要素eと一致した場合には探索終了。一致しない
場合は2に進む。
2. m < eの場合、mより右側の要素の配列で1の操作をする。e < m の場合mより左側の要素の配列で1の操作をする。


```python
def bisect(array):
    target_num = int(input())
    left = 0
    right = len(array)
    mid = (right + left) // 2
    while left <= right:
        if array[mid] == target_num:
            return(f'found! index is {mid}')
        if array[mid] <= target_num:
            left = mid + 1
            mid = (right + left) // 2
        else:
            right = mid - 1
            mid = (right + left) // 2
    return('not found')
```


再帰を使ったバージョン。


```python
def bisect_recur(array, target_num):
    left = 0
    right = len(array)
    mid = (right + left) // 2
    if array[mid] == target_num:
        return(f'found! index is {mid}')
    elif array[mid] < target_num:
        bisect_recur(array[mid+1:], target_num)
    elif array[mid] > target_num:
        return bisect_recur(array[:mid], target_num)
```
P/Invokeのref(またはout)引数にnullを渡す

P/Invokeメソッドで`ref`(または`out`)引数がオプションの場合、null値を渡すために`IntPtr`版のオーバーロードを追加するのがダルるかったのですが、回避方法を知ったのでメモ。(ただし、unsafeは必要)

詳しくは++C++; // 未確認飛行 C さんの[参照渡しとポインターの相互変換](https://ufcpp.azurewebsites.net/study/csharp/sp_ref.html?p=4#as-pointer)を見てください。
っていうかほぼパクリです。

# TL;DR
- C# 7から、参照戻り値が使える。
- Unsafe.AsRefメソッドで、null値を参照に変えられる。

# 例

下記のようなP/Invokeメソッドを考える。

```csharp
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
static extern bool GetDiskFreeSpaceEx(
  string lpDirectoryName,
  out ulong lpFreeBytesAvailableToCaller,
  out ulong lpTotalNumberOfBytes,
  out ulong lpTotalNumberOfFreeBytes
);
```

`System.Runtime.CompilerServices.Unsafe` パッケージをプロジェクトに追加して、ユーティリティ関数を用意する。

```csharp
unsafe static ref T NullRef<T>()
{
    return ref Unsafe.AsRef<T>(null);
}
```

下記の様に呼び出す。

```csharp
GetDiskFreeSpaceEx("C:", out NullRef<ulong>(), out var lpTotalNumberOfBytes, out NullRef<ulong>());
```

# 追記

[NuGet Gallery | System.Runtime.CompilerServices.Unsafe 5.0.0](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/5.0.0)から、`Unsafe`クラスで`NullRef`メソッドが提供されている。

```csharp

    public static class Unsafe
    {
        public static ref T NullRef<T>();
    }
```
NuxtをApp Engineにデプロイする時のapp.yaml（Nuxt on Google App Engine)


Nuxt.jsで作ったプロジェクトをApp Engineにデプロイする際に `too many files` エラーが発生しました。
内容は10000ファイル以上のデプロイはNGというエラーでした。

下記で対応できます。
skip_filesに注目。node_modulesや.gitなどをデプロイ対象から外すことでそもそもApp Engineに載せる必要のないファイルを除外しましょう。

```app.yaml
runtime: nodejs10

instance_class: F2

handlers:
  - url: /_nuxt
    static_dir: .nuxt/dist/client
    secure: always

  - url: /(.*\.(gif|png|jpg|ico|txt))$
    static_files: static/\1
    upload: static/.*\.(gif|png|jpg|ico|txt)$
    secure: always

  - url: /.*
    script: auto
    secure: always

env_variables:
  HOST: '0.0.0.0'
  NODE_ENV: 'production'

skip_files:
  - functions/
  - node_modules/
  - public/
  - src/
  - .browserslistrc
  - .gitignore
  - babel.config.js
  - pakage.json
  - postcss.config.js
  - README.md
  - tsconfig.json
  - tslint.json
  - yarn.lock*
```

## 参考文献
https://ja.nuxtjs.org/faq/appengine-deployment/
networkxで苦労した点（attr_dictが使えない）

networkx 2.x（最新）を使ってる際に経験したエラー。
ウェブ情報によると、nodeへの属性付与はattr_dicを使えばいいのだけれど。
例えば、nodeに下記のような辞書で表せる属性を付与したい場合

    d={}
    d={time:2010,
      graphics:{
                y:100
               }
        ・・・
     }


[マニュアル](https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.DiGraph.add_node.html)によれば
attr_dic = d とすればＯＫ。
しかし、使ってみると、

* d['~~']　＝　●●　など、辞書が１階層ならばすんなり受け付けてくれるが、
* 辞書の中に辞書が入ってる場合はエラーになってしまう。
 

自分の使っているnetworkxが2.3なのを確認し、

[このへん](https://stackoverflow.com/questions/40674597/networkx-add-node-seems-to-ignore-attributes-parsed-as-dictionary)や[このへん](https://networkx.github.io/documentation/stable/release/release_2.0.html)
を参照すると、どうやら attr_dic が廃止になった模様。
どうすればいいんだと途方にくれて４時間ほど過ぎたところ、最終的に

    for nod in nodes:
        try:
            d ={}
            d['time'] = dit['time'][nod.replace("_"+str(year),'')]
            d['graphics'] ={}
            d['graphics']['y'] = yps
            temp_G.add_node(nod,time=d['time'],graphics = d['graphics'])
            temp_G.add_node(nod)
            nx.set_node_attributes(temp_G, d)
            
        except:
            ～～

のように、配列っぽく入れてあげれば意図どおりに属性を付与してくれた。
後から見ると当たり前にみえる。（[]を下位の層まで使って入れてあげてるだけ）
TimeMachineのバックアップドライブをクローンして移行（macOS Mojave）

後で追記しますが、とりあえず忘備録として書いておく。

# 背景
今までTimeMachineによるバックアップに使っていたHDDの挙動が怪しくなってきたので、新しいSSDにTimeMachineバックアップデータを移行したかった。が、やたら難しくて1ヶ月ほどハマった。  

# TL;DR
ファイルベースでのコピーはハマる。ddコマンドとディスクユーティリティを使って、ブロックレベルでHDDをクローンすべき

# 準備
環境はmacOS Mojave（10.14.5）で、移行元のドライブはUSB接続で外付けの2TB HDD、移行先の新しいドライブは1.92TBのUSB-C接続のSSDです。HDDは2TBの容量をもつ単一のパーティションで運用しており、900GBほどがバックアップデータで消費され、1TB弱の空き領域があるという状況。ファイル数は正確には数えてないですが1000万個ぐらいのオーダーのはず。

後で述べますが、空き領域を含めてドライブ（正確にはパーティション）をブロック単位でコピーするので、TimeMachineのデータがあるパーティションのサイズよりも移行先パーティションの容量が小さい場合、TimeMachineに使っているパーティションを分割して移行先に収める必要があります。

macのディスクユーティリティを開き、TimeMachineバックアップに使用しているドライブを右クリック選択、上部メニューから「パーティション作成」をクリックして、TimeMachineデータのサイズに合わせた適当な新規パーティションを作成します。ここで作ったパーティションは、データの移行が終わったらディスクユーティリティを使って消せます。
例；2TBのHDDのうちTimeMachineが500GBの容量を消費していた場合、TimeMachineパーティションとして510GBぐらいの容量を残す形で、1490GBの新規パーティションを作成する。こうすれば2TB未満のサイズのHDDやSSDにもデータをコピーできる。

# 方法
1. diskutilコマンドでパーティションを見つける
2. ddコマンドでTimeMachineバックアップドライブのディスクイメージを作成する。  
容量が異なるドライブ間での移行の場合、ディスクユーティリティで書き戻さないとパーティションテーブルが壊れて厄介なことになるので、面倒でも一度ディスクイメージとして書き出す。
if=がソース、of=が出力先。例としては次の通り。  
`sudo dd if=/dev/rdisk3s2 of=/Volumes/NEW_SSD/backup_image.img bs=32m`  
disk名の先頭にrをつけると、シーケンシャルアクセスになる代わりにキャッシュを介さなくなるので、ddによるコピーのようなシーケンシャルなアクセスの場合には高速化できる。bs（バッファサイズ）は適当に32MBにしました。
ここでstatus=progressオプションはサポートされていないので、つけるとエラーが出る。そこでddの進捗を見るには、ddが走っているターミナル上でcontrol + Tキーを押す。ddの進捗確認によく使われるkillallコマンドを使う方法だと、普通にddプロセスがkillされるので注意
3. ディスクユーティリティを使って、作成したディスクイメージを新しいドライブに書き戻す
もしも、ディスクイメージが検証できませんでしたなどと怒られた場合は、作成したディスクイメージを普通にfinderから一度開いて、その状態で再トライするとできました（詳細不明）

# うまくいかなかった方法
基本的にファイルレベルのコピーは時間がかかりすぎる && macのシステムファイル周りのセキュリティがガチガチなためにコピーできず、ハマります（体験談）

- finderでコピー
    - 公式には推奨されている
    - 時間がかかりすぎてダメ（一晩立ってもコピーが進まない）
    - セキュリティが厳しい一部のファイル（システムファイルなど）がコピーできない（うろ覚え）
- cpコマンドでコピー
    - ファイルが多すぎて時間がかかりすぎる
        - ファイルを管理するハッシュテーブルを時々リサイズしているためにやたら遅いという話
    - sudoつけていてもシステムファイルをコピーできない（Operation deniedなどと言われるはず）
- rsyncコマンドでコピー
    - ファイルが多いためメモリ消費が多すぎる。16GBのRAMではとても無理
    - cpと同様に権限の問題
- ディスクユーティリティでクローン
    - 謎のエラーで実行できず。
        - 開始直後、「元のマウント状態を復元中に問題-69842が起きました。」と怒られる
- ddコマンドでディスクイメージを作成後、普通にddを使って書き戻す
    - 書き込み自体は完了するが、パーティションテーブルが壊れて、macから破損ディスクと認識される

# 参考にしたページなど
- [（Apple公式） Time Machine：2 台のバックアップドライブ間でバックアップデータを転送する方法](https://support.apple.com/ja-jp/HT202380)
- [（ddに関して）ディスクのクローンを作成](https://qiita.com/sira/items/0e7cc588276b8bec35ac)
jcmd で GC を起こさせる

仕事でメモリリークの原因を調べるなどしている際に教えてもらった。
忘れないようにメモ。

### PID 取得

まずは、GCを起こしたい Java プロセスの PID を調べるところから。
話はそれからだ。

```sh
$ jps
# 同一マシン上で動く Java の PID がワラワラとでてくる。
```

### GC を起こさせる

対象の PID を指定して実行する。

```sh
$ jcmd <PID> GC.run
```

VisualVM でモニタリングしてたんだけどメモリの使用率がガツンと落ちた。
【golang環境構築】とりあえずhello worldまで

## 参考にさせて頂いた記事
- https://qiita.com/okatai/items/a6f966d2075d69d21e74
- https://qiita.com/Esfahan/items/30f801dc6e5bada9ba54

## 環境
OS:macOS Mojave
シェル:zsh

## 環境構築手順
### 手順1:goのインストール
Homebrewで入れる

```
$ brew update
$ brew install go
```

### 手順2:workspace作成
どうやらworkspaseを作成しそこにpathを通さなければいけないらしい

```
$ cd workspace
$ mkdir -p go/{src,bin,pkg}
```

.zshrcに以下を追加
* `/usr/local/bin/go` の場所は `$ which go` で確認する

```
export GOPATH=$HOME/workspace/go
export GOROOT=/usr/local/opt/go/libexec
export PATH="$PATH:$GOROOT/bin:$GOPATH/bin"
```

### 手順3:hello worldを書く

```
$ cd ~/workspace/go/src
$ mkdir hello
$ cd hello
$ vim hello.go
```

```go:hello.go
package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}

```

```
$ go build
$ ./hello
hello, world
```



以上、とりあえずhello worldまで。
次回から色々と環境を整えたい。
Node.js の Cluster モードでは、アプリを Stateless にしていないとエラー

# 事象

下記のようなコードを書き、本番のみエラーになった。

```typescript:app.ts
import * as express from 'express'

const app = express()

let count = 0

app.get('/health', (_req, res) => {
  count++  
  res.send('ok')
})

app.listen(3000)
```

からの

```
pm2 start app.js -i 2
```

# 原因

pm2 では `-i 2` オプションを付けると、クラスタ化された状態で Node.js のサービスを起動してくれる。

ゼロダウンタイムデプロイが手軽にできるので、非常に便利だが、上記のようなコードは動かなくなる。上記の例では、3回目以降のリクエストが止まる。

# 対策

アプリを Stateless にすれば良い。

工数は増えるが、 Redis などに格納すべき。
rails tutorial memo ④

.superclassで探ると自明だがrailsは全てがobjectでできている
=>objectとはメッセージのやりとりが行える "foo".size  "foo"がobject  .sizeがメッセージ
何も継承しないclassを作成した場合はデフォルトでobjectクラスを継承する


irb     ==> Ruby codeが動く　rails codeは動かない
rails C ==> Ruby codeもrails codeも動く

puts = print + \n
？で終わるメソッドの返り値は True or False
【Processing】曲の波形を表示してみた【Java】

#はじめに
Processingで音楽ファイルを読み込み、波形を表示させる何かを作りました。
遊びで作ったものなので、荒いコードになっていますがご了承ください。

以下が作ったものになります。
よかったらTwitterのフォローお願いします。
<blockquote class="twitter-tweet"><p lang="et" dir="ltr">Wokka!!! Wokka!!! Wokka!!! <a href="https://t.co/NT0XM798vB">pic.twitter.com/NT0XM798vB</a></p>&mdash; もぐら猫@python (@I4MK3) <a href="https://twitter.com/I4MK3/status/1153308809374289921?ref_src=twsrc%5Etfw">July 22, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#Tree
dataファイルを作成し、その中に使用したい音源を入れてください。
音源はmp3の拡張子のみ使用できます。(m4aなどは再生できなかったのでmp3でしか多分無理)


```Terminal:Terminal
$ tree soundwave
soundwave
├── data
│   └── Wouldn't_Change_It.mp3
└── soundwave.pde
```

#コード
Minimのライブラリのインストールが必要です。
ライブラリのインストール方法は、各々調べてください。

```java:soundwave.pde
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
import ddf.minim.signals.*;
import ddf.minim.spi.*;
import ddf.minim.ugens.*;

AudioPlayer player;
Minim minim;

String title = "Wouldn't_Change_It.mp3";
int amp = 150;
float effect = 0; //波形にエフェクトをかける
float line = 0;
float left;

void setup(){
  size(1025,900);
  colorMode(HSB);
  minim = new Minim(this);
  player = minim.loadFile(title,1024);
  player.play();
}

void draw(){
  translate(0, 350);
  //if (0.4 < abs(left)) {
  //  background(100,100,200);
  //}
  //else {
  //   background(0,255,0);
  //}
  background(0,255,0);
  for(int i = 0; i < player.left.size()-1; i++){
    line = abs(player.left.get(i));
    left = player.left.get(i);
    line(i+effect, 100 + left*amp, i, 100 + player.left.get(i+1)*amp);    // Lチャンネルの波形
  }
  stroke(line*400,line*1000,500); //線の色
  strokeWeight(line*4); //線の太さ
}
```

#コードの説明
色指定は、全てHSBを使用しています。
effect変数は、数値を入れることで波形にエフェクトがかかります。
コメントアウトの部分は、波形が一定の大きさになった場合に背景色が指定の色に変わります。
コメントアウトを外す際は、else文直下のbackground(0,255,0);を消すなりしてください。
stroke()は、400の部分を大きくすると音が大きくなった際に、波形に赤みが増し減らすと赤みが減ります。
strokeWeight()は、4を大きくすることで音が大きくなった時の線が太くなります。

#感想
勉強や開発にのみコードを書いていましたが、私利私欲で意味もなく好きにコードを書くのも楽しいなと思いました。
皆さんの作品も見たいので何か面白いもの作ったよーって方は、この記事にリンクを貼り付けたり、Twitterにリプライなどを送って教えてください！

因みに、上記に埋め込んだTwitterの投稿にあるWokka!!! Wokka!!! Wokka!!!と言うのはR6Sというゲームのプロゲーマーで、Wokkaという方です。その方が投稿している動画のエンディング曲を波形に取ったので「Wokka!!! Wokka!!! Wokka!!!」と呟きました笑笑
Markdown

Qiitaの投稿や、GitHubのREADME.mdなど、何かと使用する機会があったのでMarkdown記法についてまとめました。
QiitaもGitHubも独自に拡張されていますが、まずは共通の記法を覚えたいと思います。


## 記法
※MarkdownからHTMLの生成はPreprosで行ったものを一目で理解しやすいよう整形しました。

### 段落
空行で区切ると、段落```<p>```になります。

```
test

test
```
↓

```
<p>test</p>
<p>test</p>
```






###改行
行末に半角スペース2つを入れます。

```
test  
test
```
↓

```
<p>test<br>test</p>
```

### 強調
#### 斜体
「*」1つで囲みます。(「_」でも可)

```
*斜体*
```
↓

```
<p>
<em>斜体</em>
</p>
```

#### 太字
「*」2つで囲みます。(「_」でも可)

```
**太字**
```
↓

```
<p>
<strong>太字</strong>
</p>
```
#### 斜体+太字
「*」3つで囲みます。(「_」でも可)

```
***斜体+太字***
```
↓

```
<p>
<strong>
<em>斜体+太字</em>
</strong>
</p>
```


### コード
バッククォートで囲みます。

```
`
*{
  all:initial;
}
`
```

```
<p>
<code>
*{
  all:initial;
}
</code>
</p>
```


### リスト
#### 順序無しリスト
-(ハイフン) を行頭に付けます。

```
- test1
- test2
- test3
```
↓

```
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
```

#### 順序ありリスト
数字. を行頭に付けます。


```
1. test1
2. test2
3. test3
```
↓

```
<ol>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ol>
```

### 見出し
行頭に#を付けます。

```
# test
## test
### test
#### test
##### test
###### test
```
↓

```
<h1>test</h1>
<h2>test</h2>
<h3>test</h3>
<h4>test</h4>
<h5>test</h5>
<h6>test</h6>
```

### リンク

```
 [タイトル](http://example.com)
```
↓

```
<p><a href="http://example.com">タイトル</a></p>
```


### 画像

```
![代替テキスト](http://example.com/img/test.jpg "タイトル")
```
↓

```
<p>
<img src="http://example.com/img/test.jpg" alt="代替テキスト" title="タイトル">
</p>
```



### 引用
通常の引用は行頭に>
二重引用は行頭に>>

```
>test

>>test
```
↓

```
<blockquote>
<p>test</p>
</blockquote>

<blockquote>
<blockquote>
<p>test</p>
</blockquote>
</blockquote>
```

### 空白

```
test
&nbsp;test
&ensp;test
&emsp;test
&thinsp;test
```
↓

```
<p>test<br>
&nbsp;test<br>
&ensp;test<br>
&emsp;test<br>
&thinsp;test</p>
```


### 整形
半角スペース4個もしくはタブを付けます。

```
    test
```
↓

```
<pre>
<code>test</code>
</pre>
```

### 水平線
アンダースコア、アスタリスク、ハイフンなどを3つ以上連続して記述します。(記号の間にはスペースを入れる事が出来ます)

```
test
_ _ _
test  
* * *
test  
- - -
test
```

```
<p>test</p>
<hr>
<p>test  </p>
<hr>
<p>test  </p>
<hr>
<p>test</p>

```
rails tutorial memo ①②③章

個人的な備忘録です

Rubyをinstall==>rib gemも同梱されている
　　　　　同様にrails install==>bundle同梱されている
　　　　　またrailsの正体はgemの集合体でこれをフレームワークという

Bundle install==>差分を更新
　　　　update==>0から導入し直す
            Bundle exec==>gemを全て読み込んでから実行する	

rails_5.1.0_new ver指定

リソース間の紐付け
　　　　　デフォルトと上書き方法について14章で行う
　　　　　ex))  A has_many B のとき
　　　　　AのidはBのA_idカラムに紐付くため、Bにこのカラムが必要
git関連
　　　　　git add ==> git status 　　はじめは意識しても良いかも
　　　　　git checkout ＊＊＊          ＊＊＊branchに移動
　　　　　git checkout -b ＊＊＊  　　　＊＊＊というbranchを作成し移動
　　　　　git branch　　　　　　　　　　branch一覧表示　現在地に＊マーク
　　　　　git merge ＊＊＊　　　　　　　　＊＊＊branchをmasterに上書き保存

リファクタリング
     <%= yield(:＊＊＊) %>  ==>  <% provide(:＊＊＊,AAA)%>
       :＊＊＊にAAAを代入する　　application.html.erbなどview母体の引用に使われる
　　　<%= render "***" %>  ==>　_＊＊＊.html.erbから引用して出力
       様々なviewで使用する partial化という
Visual Studio Codeを日本語表記にする方法

HTML/CSS/JavaScriptのコードを書くにあたり、「VS Code」を使用しています。
前回は[Visual Studio Codeのインストール方法](https://qiita.com/RisaWatanabe417/items/077d8b29d6e4852337be)を記事にまとめました。

インストールされた状態では、基本的には英語表記になっており、日頃から英語表記に慣れている方にとっては当たり前ですし、使い難いと思うこともないでしょう。

日本人なんだから日本語表記の方が使いやすいと単純に思ってしまう私のような考えの人もいるはずです。
今回は「VS Code」を日本語表記に変更する方法をまとめてみました。

# 「VS Code」を日本語表記に変更しよう
「VS Code」を日本語表記にする流れとしては以下の通りです。

1. 拡張機能を開く
1. Japanese Language Pack for Visual Studio Codeをインストール

「VS Code」の拡張機能の中に日本語表記に変更するものがあるので、それをインストールするだけで日本語表記に変更できます。

## 拡張機能を開く
「VS Code」の拡張機能は画面左側にある四角のアイコンをクリックすると開けます。
<img width="766" alt="コメント 2019-07-22 111119.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/b2dfd952-4a53-7a05-3aad-b8655caaf3b3.png">
検索の欄に「japan」と入力すると一番上に日本語表記にしてくれる拡張機能が出てきます。
日本語表記にしてくれる拡張機能は「Japanese Language Pack for Visual Studio Code」です。

`Install` をクリックすればインストールが実行されます。

インストールが完了したら、「VS Code」上で`Ctrl` +`Shift` +`Pキー` をコマンド入力します。
<img width="765" alt="コメント 2019-07-22 111515.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/c579f6af-0b23-d38a-af13-e9fca57c909e.png">
コマンド入力をすると画面上部にコマンドパレットが出てきます。
選択肢の中から「Configure Display Language」をクリックします。
<img width="766" alt="コメント 2019-07-22 111603.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/90339d0e-e083-084c-1482-af1646249844.png">
次に日本語を意味する「ja」をクリックします。
<img width="764" alt="コメント 2019-07-22 111644.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/6c9cb3f8-5774-50a2-d5d3-cb44ee12de28.png">
画面上にメッセージが表示されるので`Restart` をクリックすれば終了です。
<img width="767" alt="コメント 2019-07-22 111708.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/0b95b9e7-4273-a351-716a-b24ebeff4722.png">
すぐに「VS Code」の言語表記が切り替わり、日本語表記になりました。

# まとめ
「VS Code」の拡張機能で日本語表記に変更する方法をまとめました。

一からPCをセットアップする際に参考にするため、自身の備忘録としてまとめています。

慣れれば英語表記でも戸惑うことはないのでしょうが、個人的には日本語表記の方が使いやすいので日本語表記に変更して使用しています。
日本語でも英語表記でも使える機能はまったく変わらないので、自分の使いやすいようにカスタマイズしていこうと思います。
Visual Studio Codeインストール方法(Windows)

HTML/CSS/JavaScriptのコードを書くにあたり、「VS Code」を使用しています。
本日は、「VS Code」のインストール方法を記事にまとめてみました。

一からPCをセットアップする際に参考にするため、自身の備忘録としてまとめています。

# 公式HPからインストールしよう
こちらが[Visual Studio Codeの公式HP](https://code.visualstudio.com/)です。
<img width="946" alt="コメント 2019-07-22 092823.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/92da13c7-8aad-91cb-ca78-7374d8b67619.png">
今回はWindows10でインストールした画面を表示しております。
インストールする場合は、公式HPの`Download for Windows` をクリックします。
<img width="379" alt="コメント 2019-07-22 092906.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/07ebc7a4-8d11-2547-aadb-39d05bef9eb2.png">
クリックすると、「使用許諾契約書の同意」の画面が表示されます。
`同意する(A)` を選択し`次へ(N)>` をクリックします。
<img width="380" alt="コメント 2019-07-22 093105.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/304a804b-e1d4-df7e-3c50-213ec9bee713.png">
「インストール先の指定」の画面では、インストールするフォルダ先を確認し`次へ(N)>` をクリックします。
<img width="380" alt="コメント 2019-07-22 093241.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/1be7ad8c-287e-77b1-d7ab-8c13454e4f70.png">
「プログラムグループの指定」の画面では、違うディレクトリを選択する場合は変更してから`次へ(N)>` をクリックしてください。
<img width="379" alt="コメント 2019-07-22 093351.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/e6596764-2d3a-74f3-28b6-ac1b09a28299.png">
最後に「追加タスクの選択」画面が表示されます。
デフォルトで`PATHへの追加(再起動後に使用可能)` にチェックがついています。
このチェックがついていると`code` コマンドで「VS Code」を起動させることができるようになります。
特に変更する必要はないので、そのまま`次へ(N)>` をクリックします。
<img width="380" alt="コメント 2019-07-22 093432.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/c301a030-1c58-cf97-f81e-3ccf1e11dcde.png">
こちらの画面で`インストール(I)` が表示されるのでクリックします。
<img width="380" alt="コメント 2019-07-22 093555.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/b4178a3e-d7ac-6992-caee-c99c45ffeafc.png">
インストールが正常に終了すると`完了(F)` が表示されますので、クリックして画面を閉じます。
<img width="767" alt="コメント 2019-07-22 093647.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463391/0a492b16-768e-2da4-6dfb-91573c8076fc.png">
画面を閉じると、自動的にインストールされた「VS Code」が起動します。
「VS Code」がきちんと立ち上がれば、インストール完了です。

# まとめ
「VS Code」のインストール方法は以上です。
そこまで手順は複雑ではなく、基本的にはデフォルトで選択されている項目のままでインストールできました。
インストールしたままだと英語表記となります。
慣れれば英語表記でも戸惑うことはないのでしょうが、個人的には日本語表記の方が使いやすいので日本語表記に変更する方法もまとめてみました。

[Visual Studio Codeを日本語表記にする方法](https://qiita.com/RisaWatanabe417/items/3ff8904ef4d8eb3fa390)
【ServiceNow】Workflowをつくろうぜ、みんなさ。

# はじめに
ServiceNowを業務に乗っけるときに避けては通れない「**Workflow**」
これを学んでみました。

# 内容
- Workflowとは
- Workflowの作り方
- WorkflowにActivityを追加
- Activityの編集

## 1)Workflowとは
承認などの業務に対して、その発生プロセスを自動化させるためのツール。下記画像が実物。
![RoutineChange.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/e1b009ef-20f3-13a6-1847-63f89686f17d.png)

### Workflowの使い時
- 承認:Approvals
- SLA作成
- Task生成
- Event作成
- Email通知

## 2)Workflowの作り方
アプリケーションメニューの**Workflow > Workflow Editor**で下記画面が生成。
![app_store_learnv2_automatingapps_madrid_workflow_images_wf_wfeditoranatomy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/78f21538-5b63-09f4-49a5-c2c497651570.png)
ここでいろいろ作っていく。
#### Checkoutの必要性
Workflowはcheckoutという手順を挟んで編集可能。理由は既存のユーザなどへの影響があるため、直接の編集ができない設定となっている。
下記、ハンバーガーからcheckout
![app_store_learnv2_automatingapps_madrid_workflow_images_wf_checkout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/a64a1388-439b-1ec8-3be7-b7cf65cf0018.png)

そのなかで右の＋ボタンで作成できる
![app_store_learnv2_automatingapps_madrid_workflow_images_wf_createwfeditor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/c6e218cc-e475-74a5-b9fc-53bb154021a2.png)

名前、対象テーブル、トリガー条件を記載すると下記のものが生成される
![app_store_learnv2_automatingapps_madrid_workflow_images_wf_wftemplate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/88f98d38-a021-70ca-92b2-993e0d39e50c.png)
以上で、Workflowの作成は完了。

## 3)WorkflowにActivityを追加
Activityをドラッグアンドドロップで追加できる。
![app_store_learnv2_automatingapps_madrid_workflow_images_wf_addactivity1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/38549dd1-ab89-c748-17d7-76d4f9629a41.png)

## 4)Activityを編集する
追加したActivityは編集できる。設定項目はタスクごとに異なる。
承認タスクであれば、承認者情報が必要。
メール通知であれば、受信者・タイトル・内容が必要。
![app_store_learnv2_automatingapps_madrid_workflow_images_wf_approvalusercfg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/6f58e1c6-539f-011b-1491-13ecb51ba726.png)

上記で編集の概要が終了。バリエーションでいろいろ増やせる。
EdgeRouter X (ER-X) で ndppd を動かす

EdgeRouter X (ER-X) で、ndppd で NDP Proxy (Buffalo や NEC のルーターで ND プロキシと呼ばれているやつ) を実現させる。これにより、ひかり電話がなく `/64` な IPv6 が割り当てられる環境 [^1] で、IPv6 を LAN 内に割り当てる。

[^1]: ひかり電話を契約していると `/64` よりも小さい Prefix でくるらしく、これ分割して `/64` などにして、EdgeRouter からの RA で LAN 内に引き込めるらしい? (未確認)

手元の PC で ndppd を clone してくる。

```sh
git clone https://github.com/DanielAdolfsson/ndppd.git
```

ここから、ndppd を ER-X で動かすために、ndppd のバイナリを用意する。ER-X はリトルエンディアンな MIPS を搭載しているので、Mac や Windows の X86_64 な環境でコンパイルして、EdgeRouter へコピーしても動かない。

ER-X でソースを clone して コンパイルまでできたら楽だが、ER-X はメモリもストレージも貧弱なので g++ のビルド環境を導入できなさそう。

今回は Mac の Docker 上の Ubuntu へ mips コンパイラを入れて、そこでスタティックリンクでビルドしたものを ER-X にコピーすることにした。


```sh
docker run -v $PWD/ndppd:/ndppd -it --rm ubuntu
# clone してきた ndppd を docker コンテナにマウントして起動
```

ubuntu に入ったら apt を更新して、 `g++-mipsel-linux-gnu` と `make` をいれる。前者一つ入れれば、ビルドに必要なものはすべて揃う。不要なものも入ってきそうだけど、ひとまずビルドさえできればいいので..

```sh
apt-get update -y
apt-get install -y g++-mipsel-linux-gnu make
```

ndppd に同梱の Makefile を編集して `g++` のかわりに`/usr/bin/mipsel-linux-gnu-g++` をつかってコンパイルするように。 `CXX` を書き換えてもうまく行かなかったので、直接書き換えた。

ひとまず mipsel でコンパイルできれば良いと思って、Makefile を強引に書き換えた。こんな感じ:

```diff:Makefile
diff --git a/Makefile b/Makefile
index 00ca22b..fe5bd52 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,11 @@
 ifdef DEBUG
 CXXFLAGS ?= -g -DDEBUG
 else
-CXXFLAGS ?= -O3
+CXXFLAGS ?= -O3 -static
 endif

-PREFIX  ?= /usr/local
-CXX     ?= g++
+PREFIX  ?= /ndppd/local
+CXX     ?= /usr/bin/mipsel-linux-gnu-g++
 GZIP    ?= /bin/gzip
 MANDIR  ?= ${DESTDIR}${PREFIX}/share/man
 SBINDIR ?= ${DESTDIR}${PREFIX}/sbin
@@ -13,7 +13,7 @@ PKG_CONFIG ?= pkg-config


 OBJS     = src/logger.o src/ndppd.o src/iface.o src/proxy.o src/address.o \

ifdef WITH_ND_NETLINK
   LIBS     = `${PKG_CONFIG} --libs glib-2.0 libnl-3.0 libnl-route-3.0` -pthread
@@ -37,13 +37,13 @@ ndppd.conf.5.gz:
        ${GZIP} < ndppd.conf.5 > ndppd.conf.5.gz

 ndppd: ${OBJS}
-       ${CXX} -o ndppd ${LDFLAGS} ${OBJS} ${LIBS}
+       /usr/bin/mipsel-linux-gnu-g++ -o ndppd -static ${LDFLAGS} ${OBJS} ${LIBS}

 nd-proxy: nd-proxy.c
-       ${CXX} -o nd-proxy -Wall -Werror ${LDFLAGS} `${PKG_CONFIG} --cflags glib-2.0` nd-proxy.c `${PKG_CONFIG} --libs glib-2.0`
+       /usr/bin/mipsel-linux-gnu-g++ -o nd-proxy -Wall -Werror ${LDFLAGS} `${PKG_CONFIG} --cflags glib-2.0` nd-proxy.c `${PKG_CONFIG} --libs glib-2.0`

 .cc.o:
-       ${CXX} -c ${CPPFLAGS} $(CXXFLAGS) -o $@ $<
+       /usr/bin/mipsel-linux-gnu-g++ -c ${CPPFLAGS} $(CXXFLAGS) -o $@ $<

 clean:
        rm -f ndppd ndppd.conf.5.gz ndppd.1.gz ${OBJS} nd-proxy

```

Docker の ubuntu には vim などが入っていないから、Mac で書き換えてもいい。終わったら make

```sh
make

<中略>

file ndppd && % du -h ndppd
ndppd: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=8
76400b1bee62008acfb23259d1079577a8f8cec, not stripped

3.1M    ndppd
```

できた。スタティックリンクしたのでなかなか大きい。

あとはこれを scp を使って EdgeRouter に持っていく。
git reset --hard HEADしても残っているファイルを消す

探している時に検索にかからない事が多いのでメモ。

```shell
# 確認
git clean -nd

# 実際に消す
git clean -fd

# gitignore されているファイルも消す場合
git clean -xfd
```

今居る階層以下が対象になるので、すべてのディレクトリを対象にする場合はそのリポジトリの根っこに移動する必要がある。
CodeMirrorでJavaScriptのフォーマットをするときにはjs-beautifyを使おう

## CodeMirrorでJavaScriptのフォーマットをするときにはjs-beautifyを使おう
結論から言うますと、こちらのリポジトリで公開されているスクリプトが便利です。
https://github.com/beautify-web/js-beautify

CodeMirrorのコードフォーマットは現在機能していないようなので、こちらのjs-beautifyを使ってコードを整形するのが良さそうです。僕も実際にそうしています。
この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Python3の標準入力について

AtCoderやpaizaで使用する（Python3の）標準入力についてメモ

## １行１単語の取得

```
<入力データ>
12345

<記述コード>
str = input()
print(str)

<出力データ>
12345 (データ型：str)
```

int型データとして取得したい場合は`int(input())`と書く。
`input()`だとstr型として取得してしまう。

```
<入力データ>
12345

<記述コード>
str = int(input())
print(str)

<出力データ>
12345 (データ型：int)
```
## １行複数単語（スペース区切り）を取得

```
<入力データ>
apple orange

<記述コード>
a, b= input().split()
print(a)
print(b)

<出力データ>
apple
orange (データ型：str)
```

int型データとして取得する場合は`map(int, input().split())`と書く。

```
<入力データ>
123 456

<記述コード>
a, b= map(int, input().split())
print(a)
print(b)

<出力データ>
123
456 (データ型：int)
```

## １行複数単語（スペース区切り）を取得　（リストとして）

```
<入力データ>
apple 123

<記述コード>
lists = list(input().split())
print(lists)

<出力データ>
['apple', '123'] (各要素のデータ型：str)
```

各要素をint型データとして取得する場合は`list(map(int, input().split()))`と書く。

```
<入力データ>
123 555

<記述コード>
lists = list(map(int, input().split()))
print(lists)

<出力データ>
[123, 555] (各要素のデータ型：int)
```

## １行目に単語数 n、２〜（n+1）行目１単語を取得

```
<入力データ>
3
apple
123
orange

<記述コード>
num = int(input())
lists = [input() for i in range(num)]
print(lists)

<出力データ>
['apple', '123', 'orange'] (各要素のデータ型：str)
```
リストの各要素をint型データとして取得する場合は`input()`を`int(input())`と書く。

```
<入力データ>
3
123
555
777

<記述コード>
num = int(input())
lists = [int(input()) for i in range(num)]
print(lists)

<出力データ>
[123, 555, 777] (各要素のデータ型：int)
```
【Nuxt】ボタンクリックでクリップボードに文字列をコピーする

# はじめに
Nuxt.jsでボタンクリックでURLとかテキストとかクリップボードにコピーしたい。
[nuxt-clipboard2](https://www.npmjs.com/package/nuxt-clipboard2)っていうのが[clipboard.js](https://clipboardjs.com/)をNuxt.jsでnpmから使えるようにしてくれるみたいなので導入についてメモっとく。

例として、３つくらいボタンを用意してクリックするとそれぞれ「ボタン１」「ボタン２」「ボタン３」みたいのがクリップボードにコピーされるクソアプリを考えます。

# nuxt-clipboard2をインストール
普通にnpmからインストール。

```
$ npm install --save nuxt-clipboard2
```

あとは`nuxt.config.js`に登録しておきます。

```js:nuxt.config.js
//
  modules: [
    'nuxt-clipboard2'
  ],
//
```

# ボタンを押すと「Hello World」をコピー
まずボタン1つあるページ。

```vue:pages/sample.vue
<template>
  <div>
    <button type="button">Button</button>
  </div>
</template>
```

よしボタンが１つできた。

クリックしたら「Hello World」の文字列がクリップボードにコピーできるようにしてみます。

```vue:pages/sample.vue
<template>
  <div>
    <button type="button" @click="onCopy">Button</button>
  </div>
</template>

<script>
export default {
  methods: {
    onCopy() {
      this.$copyText("Hello World")
    }
  }
}
</script>
```

Buttonに`@click="onCopy"`の属性を追加。これで`onCopy()`のメソッドを呼び出しました。
`onCopy()`メソッドでは`this.$copyText()`というのを使ってます。`nuxt-clipboard2`のメソッドっす。`()`のとこでテキストを定義することでそのテキストをクリップボードにコピーさせることができます。

ボタン１をクリックして、どっかにペイストすると...お、「Hello World」がでてきた。

# 押すボタンによって違った文字列をコピー
最後にボタン３つ用意してそれぞれ別の文字列をクリップボードにコピーさせるようにします。

```vue:pages/sample.vue
<template>
  <div>
    <button type="button" @click="onCopy('Click on Button1')">Button1</button>
    <button type="button" @click="onCopy('Click on Button2')">Button2</button>
    <button type="button" @click="onCopy('Click on Button3')">Button3</button>
  </div>
</template>

<script>
export default {
  methods: {
    onCopy(msg) {
      this.$copyText(msg)
    }
  }
}
</script>
```
まず`onCopy`に`msg`の引数を追加しました。それで`this.$copyText(msg)`として引数をクリップボードにコピーするようにします。

あとはボタンを複製してそれぞれの`@click="onCopy('xxx')`の`xxx`部分を変えることでクリックするボタンによってクリップボードにコピーされる文字列を変えることができます。

ふんふん。Button１をクリックすると「Click on Button1」、Button2をクリックすると「Click on Button2」、Button3をクリックすると「Click on Button3」がクリップボードにコピーされるようになったな。

# ボタンを押すとinput fieldに入力してる文字列をコピー
```vue:pages/sample.vue
<template>
  <div>
    <input type="text" v-model="message" />
    <button type="button" @click="onCopy(message)">Button</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ""
    }
  },
  methods: {
    onCopy(msg) {
      this.$copyText(msg)
    }
  }
}
</script>
```
比較的そのまま。`data()`で定義した`message`をinputの方では`v-model`でバインドしておき、`@click`の方では`onCopy()`の引数にいれてあげるだけです。

うんうん。テキストフィールドに入力した文字列がクリップボードにコピーされるようになったぞ。

# さいごに
めちゃ簡単に導入できた。前jsだけでやろうとしたとき結構大変だったのでびっくり。

# Reference
- [nuxt-clipboard2 - npm](https://www.npmjs.com/package/nuxt-clipboard2)