OmniAICreator/Qiita-1.07M huggingface dataset:
repo コマンドの manifestファイルにほぼローカルファイルを指定する

# repo コマンドの manifestファイルにほぼローカルファイルを指定する

## 背景

Google が Android の開発用に作成した [repo](https://source.android.com/setup/develop/repo) というツールがあります。

```
repo init -u リモートURL -b ブランチ名 [-m manifestファイルのファイル名]
```

ローカルにあるマニフェストファイルを指定したい場合でも、`-u` オプションは必須なので省略することができません。
通常は別途マニフェストファイルを管理するためのリポジトリを用意する必要があり、面倒です。

`-u` オプションを省略すると以下のようなエラーなります。

```
$ repo init -m default.xml
Downloading Repo source from https://gerrit.googlesource.com/git-repo
fatal: manifest url (-u) is required.
```

ネットで検索すると `local_manifest.xml` というファイル名にすればいい、とか情報があったのですが、うまくいきませんでした。

https://stackoverflow.com/questions/15926159/repo-using-local-manifest-does-not-work の情報をもとに回避策を思いついたので共有します。
上記の方法自体では、別にリポジトリを作らないといけないので面倒なので、それを改善しています。

## 解決方法

### 大前提

正確にいうと、ローカルファイルとは言えないのですが、マニフェストファイルの管理用に別のリポジトリを用意しないというように解釈です。

* manifestファイル以外の必要なファイルがあり、それを git で管理している。(or する予定である)
* manifestファイルの管理を、既存のリポジトリにコミットして、相乗りする。

### 具体的な方法

```
repo init -m default.xml -u $(git rev-parse --show-toplevel) -b $(git rev-parse HEAD)
repo sync -j4
```

### 注意

上記の repo コマンドを実行する前に `default.xml` をコミットしておく必要があります。
これは実際は、manifestファイルとしてローカルファイルを指定しているわけではないからです。

### 解説

1. プロジェクト全体を管理する git リポジトリを作ります。
2. manifestファイルに加えて、必要なファイルを登録します。
3. repo はそのリポジトリをローカルに clone したリポジトリの中で実行する。
3. repo init で `-m` には、自分が今いるリポジトリの絶対パスを指定します。
4. repo init で `-b` には、自分が今いるリポジトリのブランチ名を指定します。

`git rev-parse --show-toplevel` を git リポジトリの中で実行すると、git リポジトリの最上位ディレクトリを絶対パスで返します。
`git rev-parse HEAD` を git リポジトリの中で実行すると、現在のコミットハッシュを返します。

ポイントは、`-m` にリモートのリポジトリを指定するのではなく、ローカルのリポジトリを指定することです。

## 参考URL


* https://source.android.com/setup/develop
* https://source.android.com/setup/develop/repo
* https://source.android.com/setup/build/downloading
* https://qiita.com/fuuuuumin65/items/12310745a0d3c2319fe1
* https://stackoverflow.com/questions/15926159/repo-using-local-manifest-does-not-work
* https://qiita.com/Alice1017/items/ad061f33c8d42d52e079

repo の manifest ファイル関連のリンク

* http://wazalabo.com/pdf/2014android-manifest-howto.pdf
* https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.md
riverpodでProviderScopeを使った時のトラブルシューティング

ProviderScopeをoverrideする際に、`Cannot override providers on a non-root ProviderContainer/ProviderScope` とエラーが出た時は、以下のように`ScopedProvider`を使うと解決します。

https://github.com/rrousselGit/river_pod/pull/49#issuecomment-658603800 より引用

```dart
final itemIndex = ScopedProvider<int>(null);
...
ListView(
  children: [
    ProviderScope(
      overrides: [
        productId.overrideAs(0)
      ],
      child: Item(),
    ),
    ProviderScope(
      overrides: [
        productId.overrideAs(1)
      ],
      child: Item(),
    ),
  ],
),
...
// inside Item
Widget build(context) {
  final itemId = useProvider(productId);
}
```

`ScopedProvider`ははじめて知ったのですが、Scopedな（一部分で使われる、動的に作られる）Providerということがわかりやすくなって良いアップデートだと思います。

riverpodはアップデートが頻繁なので時々困ることもありますね・・
webpackerでJquery導入 

久しぶりの投稿になります。
Rails6.0から標準となったwebpackerを使ってJqueryを導入する方法について記事を書きたいと思います。webpackerを使ったJqueryの導入方法に関しては他に記事があったのですが、自分のような初心者には少し説明不足で、少しハマってしまったので、今回はそこを補って記事を書いていきたいと思います。
まず、「webpackerとは」というところと「なぜwebpackerを使うのか」を簡単にながらまとめさせてもらいます。

## 環境
ruby 2.7.1p83
rails 6.0.3.4

## webpackerとは
WebpackをRuby on Railsで使うためのGemパッケージのこと

## webpackとは
JavaScript、CSS、画像などの静的ファイルを１つにまとめて管理するためのモジュールバンドラの1つ。最近のモダンなJavaScriptフレームワークのモジュールバンドラとしてはデフォルトスタンダードになっている。

## モジュールバンドラとは
複数のモジュールの依存関係を解決し、一つにまとめる(バンドルする)ツールのこと

## モジュールとは
１つのJavaScriptファイルに長い処理を書くと可読性が悪くなるため、一般にページごとに複数ファイルに分割を行う。この分割されたJavaScriptファイルやSassファイルのことを「モジュール」と呼ぶ

## なぜモジュールバンドラが必要なのか
- 可読性が高くなり、保守しやすくなる
→ 機能やページごとにJavaScriptファイルが分かれていることでコードが読みやすくなる

- JavaScriptファイルなどがひとつにまとめられ依存関係が解決されていることで読み込みが早くなる
→ ブラウザとサーバの間はHTTP1.1のプロトコルで通信しており、一度に処理できるリクエストの数は限られている。リクエストの数が増えるとパフォーマンスに影響を与えるため、モジュールは一つにまとめて送信したほうが高速になる

- ES6非対応の古いブラウザでも解釈できる形(ES5)に自動で変換してくれる
→ JavaScriptがモジュール化したのがES6(2015年)からであるので、それ以前のブラウザでは読み込むことができない。これをwebpackはES5に変換してくれる。
<br>

それでは、実際に導入方法を書いていきます。
## 導入方法
まずはterminalからyarnを使ってjqueryをインストールします。

```bash:terminal
$ yarn add jquery
```
以下ファイルに設定などを追記していきます。

```javascript:config/webpack/enviroment.js
const { environment } = require('@rails/webpacker')

// 追記
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
// ここまで

module.exports = environment
```

```javascript:app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery') #追記
```
今回は「toppage.js」というファイルを作り、読み込ませました。

```javascript:app/javascript/packs/application.js
require("jquery")
require("toppage.js")
```


```javascript:app/javascript/toppage.js
console.log("hogehoge")
```
ブラウザで確認すると、出力できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583698/9790a4dd-6d79-aac2-14ab-5deea5484411.png)

ここまで読んでくださりありがとうございました。
同じような初心者のお役に立てれば幸いです。

## 参考
https://qiita.com/masahisa/items/eaacb0c3b82f4a11fc13
https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker
https://ics.media/entry/12140/
地面でボールがバウンドした回数を表示する


![バウンド例.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/5d06b126-f30d-f763-136d-cdff00fb9df5.gif)

動画はこちら
https://youtu.be/8T7Gy67bL6w

地面に下記スクリプトがアタッチされます。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class count : MonoBehaviour
{
    //===== 変数定義エリア start =====
    private int boundCount;
    public Text boundCountText;
    //===== 変数定義エリア end =====

    //===== 初期処理 start =====
    void Start()
    {
        
    }
    //===== 初期処理 end =====

    //===== 主処理 start =====
    void Update()
    {
        
    }
    //===== 主処理 end =====

    //===== ボールがぶつかったときに加算される処理 =====
    private void OnCollisionEnter(Collision collision)
    {
        boundCount++;
        boundCountText.text = boundCount.ToString();
    }
}

```
prettier onSave vscode 動かない時の対処法

今回は自分が一番苦労したprettierのonSaveが効かない時の対処法を述べていこうと思います。
1![スクリーンショット 2020-10-25 8.48.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701698/30570273-8f96-e6b1-a7f3-83860b2ca8ab.png)
Vscodeの設定画面を開いてEditor:Format On Saveにチェックを入れる。
2![スクリーンショット 2020-10-25 8.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701698/249ccd14-1a91-771c-0cb5-8df7f3992e9c.png)
Vscodeの設定画面を開いてEditor:Default Formatterがnullになっていないかチェックをする。
自分の場合はesbnp.prettier-vscodeで通常通りprettierを走らせることができました。
<p style={{color:red}}>*追記上記のesbnp.prettier-vscodeの方法でもprettierが効かない人はbysabi.prettier-vscode-standardに変えてみてください。</p>
今回はPrettierのonSaveが効かない場合の対処法を書きました。
巷の解決法は1しかなく。自力で解決するのに時間がかかってしまったのでつまづいてる方の手助けになれたら幸いです。

また、この解決方でもprettierを走らせることができない場合はcommit時にprettierを走らせる実装をしてみてはいかがでしょうか？

```pakege.json
"lint-staged": {
    "*.{html,css,md,json,yaml}": "prettier --write",
    "*.{js,ts,tsx}": [
      "prettier --write"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  }
```
lint-stagedとhuskyとprettierをnpm installしてpakege.jsonにこのような記述を描いてあげるとcommit時にprettierが走ってくれます。
「SQL文取得」の使い方 - DBUpdateTool

Excelアドイン
DBUpdateTool(https://www.lasis.com/products/dbupdatetool)

SQL文を取得する処理のメニューです。

1. ご覧の通り、Excel上に、以下のデータが入力されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/3aba8bb8-784a-f937-ae12-1fb804e53045.png)

2. アドインタブの「DBUpdateTool」のメニューより、「SQL文取得」　>　「INSERT文取得」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/6a06477d-b53e-195f-8320-6a9840197029.png)

3. SQL文がクリップボードに保存されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/c7c8eece-d46a-695f-3fc2-4a09b96ff283.png)

4. クリップボードに保存されたデータを、テキストエディタに張り付けて確認してみます。ご覧の通り、すべての行のSQL文が発行されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/86512a0a-c8f3-013a-cd12-8c6796aed3e0.png)

5. 次に、1行目と3行目の任意のセルを、「Ctrl」キーで複数選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/5f101bc8-877e-b3f7-0963-6bf6f32fa723.png)

6. セルを選択したままの状態で、アドインタブの「DBUpdateTool」のメニューより、「SQL文取得」　>　「INSERT文取得」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/986f4206-4dcf-f9fc-dcc1-e913b1233679.png)

7. SQL文がクリップボードに保存されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/381d1a71-c683-b225-283a-1212fd18d2b7.png)

8. クリップボードに保存されたデータを、テキストエディタに張り付けて確認してみます。ご覧の通り、選択した行のSQL文が発行されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805113/364477e9-b4ec-c15b-d118-ad1c9075c98d.png)
Sequel AceでAWS SSMを利用する

Sequel Aceでsshのフォワードして接続するときに
SSMを使う設定の時の設定について

設定というよりも、Sequel Aceのソース変更して自分でbuildして使っている状況


変更したところは

https://github.com/galigalikun/Sequel-Ace/commit/7b7db3de69e920648e879ef56eaf874e9c818967

/usr/local/binあたりのパスを通す

```
ProxyCommand sh -c "/usr/local/bin/aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```

とかしてもだけど結局ソースいじったので追加することに

StrictHostKeyCheckingの設定も追加しなくも良かったような気も。



https://github.com/galigalikun/Sequel-Ace/commit/8092eedeb0fad35b84a58e47e41a22f3870102bf

sandbox設定があると、ssmでの権限で？怒られるのでまるっと削除。
多分、app storeでリジェクトされそうな気がする。


あとは、バンドルIDを自分のに変えてbuild

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27299/e7ed8232-e62b-492d-97cc-c5bf4073fa99.png)



結局自分用の設定になってしまった。。


そのままでも動く設定あれば教えてくださいませ。

ちなみに、「Sequel Pro Nightly」でも繋げられなかったです。
TeamsからPower Automateを実行する方法

# Power Automateの権限設定

TeamsからPower Automateを実行するためにはチームの権限を付与する必要があるので、
マイフローの中からTeamsで実行したい内容を選択する。


![図23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/c4a31a2e-1dc5-8d04-cfed-916291036177.png)


所有者の編集をクリック。

![図24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/e332b9bc-c7c1-e68c-f5f5-04b789f016e2.png)

所有者の追加からチーム名を入力して認証画面でOKを押して完了です。

![図25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/01377679-5f08-cbfb-5017-d4d0a80fb2c8.png)
![図26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/f5adec1c-1e4d-fa9c-003f-a6bf7065d33c.png)


# TeamsでPower Automateを実行する方法①

① 会話で`@fl` と入力するとMicrosoft Flowが候補として上がるのでEnterで選択
※マウスでクリックもできますが、一連の操作はキーボードだけでできるのでキーボードのみで扱ってほしいです。
※Microsoft FlowはPower Automateの前身の名前なので同じものです。

② 上矢印キーをクリックで`操作項目` を選択
③ `List flows` を選択

![図27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/7ecdd498-dc5b-00da-16a6-883512d2877d.png)


実行すると自動的にテキストが表示されます。
重要な箇所は下記画像の`既定の環境では、` の下にナンバリングされたPower Automateのフロー一覧です。
その番号を指定することによって、右のフローを実行することができます。

<span style="color: #d61b09">※注意点
チームに初めてPower Automateの権限を与えた場合はこの表示がでるまでに時間がかかることがあります。</span>

1時間ぐらいは気長に待ってみてください。
2つ目以降のフローはすぐに実行可能です。

![図28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/29131611-fcd3-4a60-75f8-61b77c5b3732.png)


先ほどと同様の手順でMicrosoft Flowを選択し、今度は`Run flow` を選択。

![図29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/1c783836-1e47-b7f1-0a7a-29847c3e1ed3.png)


`Flow Run flow`と表示されるので実行したい番号を入力、EnterでPower Automateを実行できます。

![図30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/91b3982d-58eb-42d5-b3bc-1fdec3537afb.png)

実行が無事行われたら下記の通知がきます。

![図31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/364f989a-f365-3082-1d80-d1d550883ebe.png)



# TeamsでPower Automateを実行する方法②

個人で実行する場合はフローにチームの権限を与えなくても実行が可能です。
下記画像の…からMicrosoft Flowの実行が可能です。
よく使う方はピン止めの方法を2パターン載せたので活用してください。

方法①
固定したいアプリを右クリックでピン留めを選択すると…で開くたびに上部に固定されます。
![図32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/869ef61a-51d5-c193-50a8-282ea298dd6b.png)

方法②
固定したいアプリをドラッグ&ドロップで左のメニューに持っていくとメニュー内で固定されます。
![図33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/8cb8997a-c3c5-8f7d-71e2-e563c61ade32.png)



個人でフローを作成した方はMicrosoft Flowのアプリを実行して`List flows` を試してみてください。
共有前のフローも含めて一覧がでてきます。
![図34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/c3dcf88b-a94d-4905-d0dd-c50373321fde.png)
テンプレートリテラル記法の中でHTMLをハイライトさせる

## やりたいこと
VSCodeでJSファイルの中でテンプレートリテラル記法を使ってHTMLを書く時、テンプレートリテラル内のHTMLをシンタックスでいい感じで色付けしたい
![ProductDisplay_js_—_intro-to-vue-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657259/64ab1e72-23d5-36c9-6563-3d16a9d93bef.gif)

## 結論
1. 拡張機能（[es6-string-html](https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html)）を入れる
2. テンプレートリテラル記法の直前に`/*html*/`の記述を付け加える

### 補足
`/*html*/`の記述を付け加えないと、味気ない感じになってしまう![ProductDisplay_js_—_intro-to-vue-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657259/4a808506-89de-6c11-1793-b5f41d5b6fb6.gif)
Azure Data StudioでSQLを使う

Azure Data Studioで、SQLのクエリを使いたいときの方法です。
<img src="https://qiita-image-store.s3.amazonaws.com/0/482880/1fd767d2-9b00-07c8-1522-86dfa7e07b7d.png" width=50%>
データベースの名前を右クリックして`New Query`を選択します。

```SQL
drop table dbo.[user]
```
SQLを入力すればOKです。右クリックで`Refresh`を選択するとDBが更新されます。
ASP.NET Core MVC の DB接続の設定

ASP.NET CoreのMVCアプリを作るときのデータベース接続設定です。`namespace`は各自で書き換えてください。設定は、SQLserverを使用する前提で記述しています。

## DBコンテキストクラスの作成
DBコンテキストクラスを継承したDB接続用のコンテキストクラスを作成します。

```C#:ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using ASP.NET_Blog.Models;

namespace ASP.NET_Blog.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }
        
        // あらかじめ作成したモデルの中でマイグレーションで生成したい物を記述
        public DbSet<User> User { get; set; }
    }
}
```

## DB接続文字列の設定
`appsettings.json`で接続文字列の設定を自身のデータベース情報に変更します。OS認証（例：Windows認証など）を使う場合、`Trusted_Connection`を`true`にします。反対に、SQLSever認証などを使用する場合は、`false`にしてユーザー名とパスワードを下記のように記述します。

```json:appsettings.json
"ConnectionStrings": {
        "DefaultConnection": "Server=localhost;Database=asp_blog;user=sa;password=P@sswOrd123;Trusted_Connection=false;"
    },

```

## 準備ができたらマイグレーション開始
上記の設定が済んだら、マイグレーションコマンドを実行します。Windowsの場合は、パッケージマネージャーコンソールから以下のコマンドを打ちます。

```:windows
add-migration [マイグレーション名]
update-database
```
`add-migration`で作成されたマイグレーションファイルを元に`update-database`コマンドによってデータベースにテーブルが作成されます。


macの場合は、ツールバーの表示→パッド→ターミナルか、プロジェクトファイルを右クリック→ツール→ターミナルパッドで開く、でターミナルを開いてコマンドを打ちます。

```:Mac
dotnet ef migrations add [マイグレーション名]
dotnet ef database update
```

## エラーが出た場合

設定中にこんなエラーが出ました。

SQLServer認証の設定で、ユーザー名やパスワードを入れ忘れたり、間違っている場合は認証エラーのメッセージが出ます。

```
Cannot authenticate using Kerberos. Ensure Kerberos has been initialized on the client with 'kinit' and a Service Principal Name has been registered for the SQL Server to allow Kerberos authentication.
ErrorCode=InternalError, Exception=Interop+NetSecurityNative+GssApiException: GSSAPI operation failed with error -  An unsupported mechanism was requested (unknown mech-code 0 for mech unknown).
   at System.Net.Security.NegotiateStreamPal.GssInitSecurityContext(SafeGssContextHandle& context, SafeGssCredHandle credential, Boolean isNtlm, SafeGssNameHandle targetName, GssFlags inFlags, Byte[] buffer, Byte[]& outputBuffer, UInt32& outFlags, Int32& isNtlmUsed)
   at System.Net.Security.NegotiateStreamPal.EstablishSecurityContext(SafeFreeNegoCredentials credential, SafeDeleteContext& context, String targetName, ContextFlagsPal inFlags, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ContextFlagsPal& outFlags)
   at Microsoft.Data.SqlClient.SNI.SNIProxy.GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, Byte[] receivedBuff, Byte[]& sendBuff, Byte[] serverName)
   at Microsoft.Data.SqlClient.SNI.TdsParserStateObjectManaged.GenerateSspiClientContext(Byte[] receivedBuff, UInt32 receivedLength, Byte[]& sendBuff, UInt32& sendLength, Byte[] _sniSpnBuffer)
   at Microsoft.Data.SqlClient.TdsParser.SNISSPIData(Byte[] receivedBuff, UInt32 receivedLength, Byte[]& sendBuff, UInt32& sendLength)

```
バージョンについてもエラーが出ました。

```:error
The EF Core tools version '3.1.6' is older than that of the runtime '3.1.9'. Update the tools for the latest features and bug fixes.
```
こんなときは、バージョンの設定を個別のアプリではなく、グローバルに更新する必要があります。

```:Mac
dotnet tool update --global dotnet-ef
```
visual studio for mac ですが、これでマイグレーションができるようになりました。
SSHのポート番号を変更

SSHサーバーの初期設定は、22番ポートを利用します。
このポート番号は一般的で広く知られているため、ポートの解放の際に不正侵入のリスクが高まります。
よってリスク回避のため、SSHのポート番号を22番から変更する。

SSHの設定ファイルを変更

その前にバックアップのためにSSH設定ファイルのバックアップを作成

```
[root@localhost ~]# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.old

```

ポート番号を変更するために、SSH設定ファイル（/etc/ssh/sshd_config）のPort項目を編集。

/etc/ssh/sshd_config
Port 59695 (59695の数字は例)

設定の変更の確認のためdiffコマンドを使用

```
[root@localhost ~]# diff /etc/ssh/sshd_config.old /etc/ssh/sshd_config
17c17
< #Port 59695
---
> Port 59695
```

設定ファイルの構文をチェックしエラーがないことを確認

```
[root@localhost ~]# sshd -t
```
エラーが表示されなければ正常に構文が変更されている。

SSHの設定を反映

```
[root@localhost ~]# service sshd restart
Redirecting to /bin/systemctl restart sshd.service
```

変更したポート番号で、SSHログインできるかを確認

クライアント側からSSH接続

```
ssh -p 59695 usr@(IP)
ssh: connect to host (IP) port 59695: Connection timed out
```

繋がらない、どうやらfirewalldの設定も必要のよう

```
[root@localhost ~]# cat /usr/lib/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="22"/>
</service>
```
firewalldの設定の前に設定ファイルをコピー

```
[root@localhost ~]#  cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/
```

次に設定ファイルのバックアップを作成

```
[root@localhost ~]# cp /etc/firewalld/services/ssh.xml  /etc/firewalld/services/ssh.xml.old
```

設定ファイルの中身を変更
先ほどの/usr/lib/firewalld/services/ssh.xmlのportを59695に変更

```
[root@localhost ~]#  cat /etc/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="59695"/>
</service>
```

設定の変更の確認のためdiffコマンドを使用

```
[root@localhost ~]# diff /etc/firewalld/services/ssh.xml.old /etc/firewalld/services/ssh.xml
5c5
<   <port protocol="tcp" port="22"/>
---
>   <port protocol="tcp" port="59695"/>
```

変更した設定を反映

```
[root@localhost ~]# firewall-cmd --reload
success
```

successと表示されれば、OK

sshd を再起動

```
[root@localhost ~]# systemctl restart sshd
```

再度変更したポート番号で、SSHログインできるかを確認

```
ssh -p 59695 usr@(IP)
Last login: Time from (IP)
[usr@localhost ~]$
```

無事SSHのポート変更による接続が完了


参考url
https://webkaru.net/linux/change-ssh-port/
https://webkaru.net/linux/centos7-firewalld-ssh-port/
Laravel 【初心者】 PHPフレームワーク Laravel入門 第2版 の内容を一部図式化してみた件 ⑰バリデーションルール

#はじめに
この記事はプログラミングをはじめたばかりの素人が、メモするのに利用しています。
内容には誤りがあるかもしれません。

#PHPフレームワーク Laravel入門 第2版 について
Laravelを独学で学ぶにあたり、評判がよかったのでAmazon Kindleで購入しました。
**内容も色々な方法が書いてあるので、Laravelをはじめて勉強される方にはおすすめの本です。**

Amazon リンク
https://www.amazon.co.jp/gp/product/B08625YD7H/ref=ppx_yo_dt_b_d_asin_image_o09?ie=UTF8&psc=1

#図式化について
学習中に、文字だけだとイメージが掴みづらかったので、自分の為に作成したものです。
また方法が色々あり過ぎて混乱したので、整理する意味もあります。
ディレクトリを覚えるのにも使いました。

コードは必要なものだけ抜粋しているので、全てではありません。
これだけ見ても勉強にはならないので、**PHPフレームワーク Laravel入門 第2版**を是非購入してみて下さい。

※ちなみに著者の方とは何の関係もありません。

素人が作成した物なので、参考程度に使ってください。

#バリデーションルール

![v3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/760252/61521071-6379-d760-5e50-44755a9181b6.jpeg)
Laravel 【初心者】 PHPフレームワーク Laravel入門 第2版 の内容を一部図式化してみた件 ⑯オリジナルバリデータ

#はじめに
この記事はプログラミングをはじめたばかりの素人が、メモするのに利用しています。
内容には誤りがあるかもしれません。

#PHPフレームワーク Laravel入門 第2版 について
Laravelを独学で学ぶにあたり、評判がよかったのでAmazon Kindleで購入しました。
**内容も色々な方法が書いてあるので、Laravelをはじめて勉強される方にはおすすめの本です。**

Amazon リンク
https://www.amazon.co.jp/gp/product/B08625YD7H/ref=ppx_yo_dt_b_d_asin_image_o09?ie=UTF8&psc=1

#図式化について
学習中に、文字だけだとイメージが掴みづらかったので、自分の為に作成したものです。
また方法が色々あり過ぎて混乱したので、整理する意味もあります。
ディレクトリを覚えるのにも使いました。

コードは必要なものだけ抜粋しているので、全てではありません。
これだけ見ても勉強にはならないので、**PHPフレームワーク Laravel入門 第2版**を是非購入してみて下さい。

※ちなみに著者の方とは何の関係もありません。

素人が作成した物なので、参考程度に使ってください。

#オリジナルバリデータ

![v2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/760252/f8b2e41d-8877-e20e-be6e-9347daae84c0.jpeg)
Laravel 【初心者】 PHPフレームワーク Laravel入門 第2版 の内容を一部図式化してみた件 ⑮オリジナルバリデータ

#はじめに
この記事はプログラミングをはじめたばかりの素人が、メモするのに利用しています。
内容には誤りがあるかもしれません。

#PHPフレームワーク Laravel入門 第2版 について
Laravelを独学で学ぶにあたり、評判がよかったのでAmazon Kindleで購入しました。
**内容も色々な方法が書いてあるので、Laravelをはじめて勉強される方にはおすすめの本です。**

Amazon リンク
https://www.amazon.co.jp/gp/product/B08625YD7H/ref=ppx_yo_dt_b_d_asin_image_o09?ie=UTF8&psc=1

#図式化について
学習中に、文字だけだとイメージが掴みづらかったので、自分の為に作成したものです。
また方法が色々あり過ぎて混乱したので、整理する意味もあります。
ディレクトリを覚えるのにも使いました。

コードは必要なものだけ抜粋しているので、全てではありません。
これだけ見ても勉強にはならないので、**PHPフレームワーク Laravel入門 第2版**を是非購入してみて下さい。

※ちなみに著者の方とは何の関係もありません。

素人が作成した物なので、参考程度に使ってください。

#オリジナルバリデータ

![v1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/760252/6ef339d2-5d4c-8f11-b929-5ab4ed1c7627.jpeg)
IBM Cloudの認定資格をとろう（IBM Certified Solution Advisor - IBM Cloud Foundations V2編）

# IBM Certified Solution Advisor - IBM Cloud Foundations V2とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/2833dbce-70b5-d2e7-c978-75f22dcc6b23.png)

過去記事[IBM Cloudの認定資格をとろう（概要編）](https://qiita.com/teruq/items/62fe97cd25c0110ee030)のとおり、IBM Certified Solution Advisor - IBM Cloud Foundations V2はIBM Cloud認定資格のもっとも基本的なレベルとなります。とはいえ、難易度は比較的高めです。IBM Cloudは多少使ったことがある、という程度では合格は難しいので、準備は必要です。

# 出題範囲

公式の[Study Guide](https://www.ibm.com/certify/api/getpdf/studyguides/stuc1000_083)がベースです。ただし、IBMさんの認定試験にありがちなのですが、これ以外の出題も多少ありえます。

試験規約により具体的なアドバイスはできないのですが、Foundationsでは幅広さが求められますので、Study Guideに出てくる単語はひととおり説明できるようになっているといいでしょう。

# 無料で受けられるe-ラーニング

試験対策になる（かもしれない）無料のe-ラーニングがいくつかあります。IBM社員ではない人でも受講できます。

## Introduction to Cloud

* URL https://cognitiveclass.ai/courses/introduction-to-cloud
* 所要時間 3時間
* Open Badge あり

IBM Cloudの認定資格を取ろうという人で、クラウドとはなんぞや、という人はいないと思いますが、念のため一から学びたい人向けです。最終クイズに合格するとCloud Coreバッジが貰えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/8fd0c881-6c37-1f1b-c01a-4c4c3c079e43.png)

## IBM Cloud Essentials – V3

* URL https://cognitiveclass.ai/courses/ibm-cloud-essentials
* 所要時間 5-8時間
* Open Badge あり

クイズは本番試験のレベル感に近いという印象でした。ある程度IBM Cloudの経験がある人は、各章末と最後のクイズだけでもやっておくといいでしょう。こちらも合格すればバッジが貰えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/279bfe75-6c5a-f967-4c2b-ea95da8560b0.png)

## IBM Cloud Certification Preparation Course

* URL https://learn.ibm.com/course/view.php?id=8093
* 所要時間 36時間
* Open Badge なし

こちらはFoundations試験の正式な準備コースです。きちんと腰を据えて試験勉強をしたい人向けです。まじめにやるとボリュームもかなりあります。こちらも、経験者で時間のない方は、クイズだけでもやっておくといいでしょう。

# 受験方法

PersonVUE社のサイトから「C1000-083: Foundations of IBM Cloud V2」を予約し、最寄りの会場で受験してください。受験料は2万円（税抜）です。

> https://www.pearsonvue.co.jp/Clients/IBM.aspx

テストセンターによって試験を開催している日にバラツキがあります。東京駅近辺ですと、秋葉原のテストセンターはほぼ毎日開催していますし、前日予約も可能ですので、急に受けたくなったときはお勧めです。

# 出題形式

1/4択はまた2/5択がほとんどです。ごく稀にそれ以外の特殊な回答方法があります。基本的には「正しいものを全て選べ」系の問題はないので、そこは安心です。

ちなみにもちろん試験は英語です。

試験時間は90分です。足りないということはないと思います。

# 合格条件

60問中43問以上の正解で合格となります。正答率71%以上に相当します。

# リトライしたい場合

1回で駄目でも記憶がフレッシュなうちに2回目を受験することをお勧めします。IBMの認定試験は同じ試験を30日間に2回まで受験できます。もちろん別料金です。

# アドバイス

試験範囲が広いので、自分は開発者なんで、、、というような人でも、IaaSの知識が問われてしまいます。アカウントの管理に対する知識も問われます。実際に手を動かして、IBM Cloudの主要なサービスを理解しておくことが望ましいです。

回答ですが、経験者であれば、4択問題は2択には絞れると思います。残った2択を取りこぼさないことが大事です。1つのテクニックですが、正しいことを言っていそうな2択が残ったときは、それが問題文以外の状況でも正しいかどうか、を考えてみるといいです。もしその選択肢が問題文固有の状況でのみ正しいなら、おそらくそれが正解です。これは私なりのテクニックなので、ご参考まで。
zshでプロンプトの右側部分を無理やりにでも先頭行に表示したい

# やりたいこと

zshで以下2つに当てはまると、2行目に`RPROMPT(プロンプトの右側)`が来てしまいます。

* `.zshrc`で`PROMPT`末尾に改行コードを入れて、コマンドを新しい行から入力するようにしている
* `RPROMPT`を有効にしている

下の画像のようになります。
![Screen Shot 2020-10-25 at 2.35.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174325/5859aadf-83b8-ac9d-93e0-f0e1923c599c.png)

これで困るのが、ターミナルの内容をSlackなどにコピペして共有しようとしたとき、`RPROMPT`までコピーされてしまい、それを消す手間ができてしまうということです。

なんでユーザーがコマンドを入力する行と同じ行に`RPROMPT`を出す仕様なんだろう。。
それをなんとかしたいというニッチな投稿です。

ちなみに何らかの設定で、シンプルにこれを解消する方法は思いつきませんでした。
(`RPROMPT`は改行コード効きません。`ZLE_RPROMPT_INDENT`を負の整数にしたりしても無視されます。)

# 解決方法の案

### 案1: `RPROMPT`使うのやめて、ANSIエスケープシーケンスで無理やり制御して描画する

ちょっとこんなやり方しかわからないです。

`.zshrc`を以下のようにします。

```sh
# 出したい情報をCUSTOM_RPROMPTに格納しておく

print_to_rprompt() {
	col=$(( COLUMNS - 8 ))
	print -Pn "\e7\e[1A\e[${col}G${CUSTOM_RPROMPT}\e8"
}

TMOUT=1
TRAPALRM() {
    print_to_rprompt
}
```

`COLUMNS`はウィンドウ幅が入っているzshの環境変数です。
右に出す文字を、先頭に半角スペースを挿入することで、全て8文字に統一した上で上記のように実装しました。

制御コードによる操作の説明をします。

* ESC7: 現在のカーソル位置などを保存する
* ESC[1A: カーソル位置を1行上に移動
* ESC[{NUM}G: カーソルを左端からNUMだけ右に移動
* ESC8: 保存していたカーソル位置などの復帰

そして、`TRAPALRM`でこれを1秒毎に実行します。
つまり、毎秒printで出したい情報を出し続けるということになります。

私は、gitのstatusと時刻を`RPROMPT`に出したいのですが、この方法だとプロンプトの右側の情報は保持されずに常に書き換えられるため、時刻は`PROMPT`にうつしてgitのstatusだけ表示するようにしました。
以下のような感じになります。

![Oct-25-2020 03-36-01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174325/e3cf41be-2e24-38a0-ec92-0d9fef41a57a.gif)

毎秒更新するあたり、本来の`RPROMPT`とは機能が異なってしまっていますが、gitのstatusをリアルタイムで更新して表示してくれるのでむしろ気に入りました。

### 案2: `PROMPT`に必要なだけのスペースを計算して挿入する

これでもできそうです。こちらのほうが本来やりたかったことに近いかも。
ただ今回は案1にしました。

### 案3: tmuxを使う

tmuxで`status-position top`で出来るらしいです。
tmuxにしようかな。。

# まとめ

試行錯誤してるうちに、以下のようなプロンプトができました。

* 複数行プロンプトの場合も、1行目の右側に情報を表示
* 毎秒更新(エディタでいじればそのステータスが反映される)


なにか他にいい方法があれば、ぜひ教えていただきたいです。。
iPhone（VisionKit）の文書スキャナーは、コンビニのマルチコピー機のスキャナーの代わりに使えるか

iPhoneのカメラで紙の文書をスキャンして、コピー機のスキャナーの代わりに書類のやりとりに使えるのでしょうか？　試してみました。

AppleのVisionKitを使えば、文書をスキャンできます。
斜めに撮っても、コンピュータービジョンでまっすぐな文書に直してくれます。

![Oct-25-2020 03-19-11.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/d8283462-f2e0-6573-8850-ac71c59f88c1.gif)

#つかいかた

```swift
import VisionKit
```


```swift
let documentCameraViewController = VNDocumentCameraViewController()
documentCameraViewController.delegate = self
present(documentCameraViewController, animated: true)
```

ドキュメントスキャナーにプリセットされているSaveボタンで写真ライブラリに保存するコードはこちら。
Info.PlistのPrivacy Camera Additional Usage Descriptionを設定しておくことを忘れずに。

```swift
// Saveボタンが押された時に呼ばれるデリゲートメソッド
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
    let image = scan.imageOfPage(at: 0)
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
```


#コンビニのスキャナーとの比較
###１、VisionKit
![IMG_2736.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/6e3f1c7a-aed5-2c3e-3aa6-d3643f61e322.png)

###２、コンビニのスキャナー
![scan-001のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/51887700-156f-4a57-55cc-2a57b7595099.png)

コンビニの方が圧倒的に綺麗でした。
蓋をして光を当てているので、シワが全然ない。

VisionKitは、Visionで文字認識する前に、紙から取り込むのとかには使えそうです。

🐣
****
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
AtomでDenoを動かす（簡易版）

denoの開発環境を整えるにあたって、まずはエディタの設定を整え…
と思ったらAtomにはdeno向けのプラグインが無いようだ。(2020年10月現在)
仕方ないので、パッケージ「script-runner」を入れてatom上で最低限動くようにだけする。

# atom上でdenoを実行する

#### 1. パッケージ「[script-runner](https://atom.io/packages/atom-runner)」をインストールする
#### 2. 「ファイル＞個人設定」でconfig.csonを開き、runner部分を以下のように編集する

```config.cson
  runner:
    scopes:
      js: "deno run" #<--この行を追加
      python: "python"
```
`js: "deno run"`の行を追加することで、`deno run [filepath]`の形でコマンドが実行されるようだ。
#### 3. 実行したいjsファイルを開き、Ctrl + Rで実行

以上。
ところで、denoには実行時に`--allow-net`などのオプションを指定する場面がある。が、この方法だと実行時オプションの指定ができない。`config.cson`に書くコマンドに`--allow-all`オプションを含めてしまってもいいが、設計思想(Secure by default==デフォルトで安全)に反する……？

# まとめ
これは暫定的な方法ということで、他に何かいい方法が見つかったら教えてください。

## 追記
配列をconsole.logするなどした時はうまく表示してくれません。なんなら`ctrl+shift+i`でAtomのコンソールを出しちゃったほうが便利という時もあったり…
（Atom自体がDenoと同じくV8で動いている）

## 追記2
denoでググると、「～での」という単語も検索結果に含まれてしまう。「"deno"」という風にダブルクォーテーションで囲うとdenoだけ検索してくれる。
gitignoreとは一体はなんぞや

さーて今日から始めますよとQiita投稿

プログラミングの知識をより深めるためにもアウトプットていきますよと
駆け出しのエンジニアなのでお手柔らかに🙇‍♂️

さて、そんな駆け出しエンジニアの初投稿の内容は！！！
gitignore

これなんとなくコミットさせたくないから〜的なこと認識でいたんです
まあ一応そんな感じではあるのですが、ただどういうときに必要なのかいまいちピンときていなかったんですよね、、、

しかし！！！今日ここで！！！
なんとなくの認識から抜け出し、gitignoreを使う時はどういう時なのかを、

なんとなく！！！

わかるようにすることが目的です(なんとなくなんかい)

じゃあ本題やっていきますよと

## .gitignoreって何？
まあ簡単いうとgitの管理下に置きたくないファイルの置き場所なんだとさ

* 必要ないデータをコミットすると、他の人は必要なデータだけを探しにくくなる
* 環境変数とかをコミットすると、セキュリティちょいゆるくない？？

以上のことを防止するためにも.gitignoreを使っているんです

ちなみに必要のないデータっていうのは、Mac使っている人なら
`.DS_Store`
というのが代表格ですかね
どうも勝手に作成されてしまうみたいなんですよ

## じゃあどうすんの
こいつをgitの管理下に置かない様にするためにやることは簡単

```ruby:.gitignore
.DS_Store
```


これだけ。
.gitignoreに.DS_Storeを記載するだけ。
ただただこれだけ。

簡単ですね♪
管理したくないデータを記載するだけでいいんです

もちろん、
"この拡張子を全部排除したい！"とか
"このディレクトリの一個だけは排除したくない！"とか
そういう要望にもある書き方をすれば、叶えてくれるんです

この書き方については再度編集するかまた新しい記事を投稿してみようと思います！
<br>
<br>
まあ最初の投稿はこんなとこで失礼しますm(_ _)m

思ったより投稿内容考えるの大変。。。
でもまたアップし続けますよと
継続力、大事☺️
指摘箇所があったら<b>優しく(ここ重要)</b>教えてくださいね

そりでぃは✋
<br>
<br>
<br>
<br>
<br>
<br>
記事投稿始めた俺…
止まるんじゃねぇぞ…

　　　　　　　　　　　　　　　rm1
　　　　　　　　　　　　　 　 〉　ｸ
　　　　　　　　　　　　　 　j￣l　　　　　,ｬvｧ,
　　　　　　　　　　　　　　j::::::l　　　　 ﾐt　　戔
　　　　　　　　　　　　　 j:::::::ﾄ、＿ _　幺wv､｢
　　　　　　　　　　　　　 t:::::::::::::::::｀::⌒ヾニニﾄ､_
　　　　　　　　　　　　　　￣｀ヾ:::::::::::;;;;;;;:::::;|;;;;;;;;::｀ｰ､
　　　　　　　　　　　　　　 　 　 ﾞY::::;;;;;;;;;;;;;;;|;;;;;;;;;;|::::::!
　　　　　　　　　　　　　　　　 　 ヾ::;;;;;;;;;;;;;;;|;;;;;;;;;;:!:::::|
　　　　　　　　　　　　　　　　　 　/;;;;;;;;;;;;;;;;|;;;;;;;;;;;l::::::l
　　　　　　　　　　　　　 　 　 　 /::::;;;;;;;;;;;;;;|;;;;;;;;;;;jl:::::ﾞi
　　　　　　　　　　　　　　　 　 /:::::;;;;;;;;;;;;;;;ﾊ;;;;;;;;;;tl:::::::l
　　　　　　　　　　　　　　　　〈::::;;;;;;;;;;;;;;;;/;|;;ﾞ､;;;;;;;ﾞl:::::::l
　　　　　　　　　　　　　　　 　 ヾ､＿＿/;;;|;;;;;ヾ＿｣::::::〉
　　　　　　　　　　　　　　 　 　 　 |;;;;;;;;;;;;;;|;;;;;;;;;;;;;;| l/え、
　　　　　　　　　　　　　　　　　 　 |;;;;;;;;;;;;;ﾊ;;;;;;;;;;;;;ﾞ〈t!杉!
　　　　　　　　　　　　　　　　　　　|;;;;;;;;;;;j　ヾ;;;;;;;;;;;;ﾞ､ ぐ
　　　　　　　　　　　　　　　　　　　|;;;;;;;;;;;!　　ヾ;;;;;;;;;l ＼>
　　　　　　　　　　　　　　　　　　　|;;;;;;;;;;|　　　ヾ;;;;;;;;!
　　　　　　　　　　　　　　　　　　　|;;;;;;;;;;|　　　　〉;;;;;;|
【Swiper】左揃え、それぞれのスライド幅が異なるスライダーの実装


Swiper v6.3.4を使用しました。
https://swiperjs.com/


### 実現したいこと
- 左でいい感じにスナップしてほしい
- 幅はCSSで指定せず、中身によって変化するようにしたい

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="YUUMU" data-slug-hash="KKMaxOZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Swiper Left justify / demo">
  <span>See the Pen <a href="https://codepen.io/YUUMU/pen/KKMaxOZ">
  Swiper Left justify / demo</a> by YUU (<a href="https://codepen.io/YUUMU">@YUUMU</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### 少し説明
- 中身によってスライド幅を変更したいので、`slidesPerView: 'auto'` に設定する
- `slidesPerView: 'auto'`を指定した場合、最後のスライドは右端揃えになってしまう
- 最後のアイテムに右マージンがあれば左揃えになるので、`slidesOffsetAfter`を指定する
- `slidesPerView: 'auto'`を指定した場合、最後のアイテムの`activeIndex`が取れない仕様らしい（https://github.com/nolimits4web/swiper/issues/2571#issuecomment-380105061）
- `snapGrid`と`slidesGrid`を上手く使うと`activeIndex`が取れるらしい（https://github.com/nolimits4web/swiper/issues/3108）

### 補足
- `width: fit-content;` はIE対応してません
- スライド幅が可変でなくていいなら、CSSで各スライドの`width`と最後のスライドの`margin-right`を指定すれば同様になります


### 使用例
<p class="codepen" data-height="560" data-theme-id="light" data-default-tab="js,result" data-user="YUUMU" data-slug-hash="YzWNRpE" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Swiper Left justify / sample">
  <span>See the Pen <a href="https://codepen.io/YUUMU/pen/YzWNRpE">
  Swiper Left justify / sample</a> by YUU (<a href="https://codepen.io/YUUMU">@YUUMU</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
DockerFileに最新のNode.jsを追加した話

他で作成していたイメージにNode.jsをインストールしたかったが、調べてもすぐには出てこなかったためメモ

##前提
Rustでwasmを触ってみようとして必要だった。
busterベースのコンテナを使用。


##結論
こちらを追加した

```
ENV NODE_VERSION 15.0.1

RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \
    && case "${dpkgArch##*-}" in \
    amd64) ARCH='x64';; \
    ppc64el) ARCH='ppc64le';; \
    s390x) ARCH='s390x';; \
    arm64) ARCH='arm64';; \
    armhf) ARCH='armv7l';; \
    i386) ARCH='x86';; \
    *) echo "unsupported architecture"; exit 1 ;; \
    esac \
    && set -ex \
    && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz" \
    && tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
    && rm "node-v$NODE_VERSION-linux-$ARCH.tar.xz" \
    && ln -s /usr/local/bin/node /usr/local/bin/nodejs \
    && node --version \
    && npm --version

```

やっていることとしては
アーキテクチャを取得
公式サイトの[url](https://nodejs.org/ja/download/ "node.sj公式のダウンロード")を叩く
展開


ログに表示されたバージョン

```
+ node --version
v15.0.1
+ npm --version
7.0.3
```

##考えたこと
最初はaptでインストールを行ったがバージョンが古く(10前後だった記憶)、せっかくなので最新にしようと考えた。しかし適当に調べても"正しい"方法が見つからないためDockerHubへ。
https://hub.docker.com/_/node

ここから自分の使っているイメージと似たようなOS(今回はbuster)をベースにしているイメージのDockerFileへ飛ぶ。
そこからnodeをインストールしている箇所を抜き出し、自分のDockerFileに適用。(本当はチェックサムやら何やらがあったが削除してしまった)

見事動いた。
以上。
#出典
https://hub.docker.com/_/node
https://github.com/nodejs/docker-node/blob/d58d7e65c4f92ef22a190b0ca835ce62464ff3ba/15/buster/Dockerfile
【JavaScript】Pure JSだけでハンバーガーメニュー

## jQueryを使わずにclassの付け替えで制御する
### クリックしたら「isActive」クラスをハンバーガーアイコンに追加する。

```html:index.html
<header class="header">
    <div class="inner">
      <div class="btn js-menuIcon">
        <span></span>
        <span></span>
        <span></span>
      </div>
      <nav class="nav__drawer">
        <ul class="nav__lists">
          <li class="nav__list">
            <a href="/">Top</a>
          </li>
        </ul>
      </nav>
      <div class="js-navBg"></div>
    </div>
  </header>
```

```js:main.js
// ハンバーガーメニュー
const menuIcon = document.querySelector('.js-menuIcon');
const navBg = document.querySelector('.js-navBg');

// ハンバーガーアイコンを押したら「is-active」クラスを付与してドロワーメニューが開く
menuIcon.addEventListener('click', () => {
  menuIcon.classList.toggle('isActive');
})

// 背景を押したら「is-active」クラスを取り除いてドロワーメニューを閉じる
navBg.addEventListener('click', () => {
  menuIcon.classList.remove('isActive');
})
```

```css:style.css
/* sp navigation */
.js-menuIcon {
  display: block;
  cursor: pointer;
  width: 40px;
  height: 40px;
  z-index: 10;
  position: absolute;
  /* background-color: blue; */
}

.js-menuIcon span {
  width: 30px;
  height: 4px;
  background-color: #fff;
  display: block;
  transition: all 0.2s;
  position: absolute;
  left: 10px;
  z-index: 4;
  cursor: pointer;
}
.js-menuIcon span:first-child {
  margin-top: 0;
  top: 10px;
}
.js-menuIcon span:nth-child(2) {
  top: 20px;
}
.js-menuIcon span:nth-child(3) {
  top: 30px;
}

.js-menuIcon.isActive span:first-child {
  transform: rotate(45deg);
  top: 20px;
}

.js-menuIcon.isActive span:nth-child(2) {
  transform: rotate(-45deg);
  top: 20px;
}

.js-menuIcon.isActive span:nth-child(3) {
  transform: rotate(-45deg);
  top: 20px;
}

.nav__drawer {
  background-color: pink;
  width: 50%;
  height: 100vh;
  z-index: 2;
  transform: translateX(-100%);
  transition: all 0.3s;
  position: absolute;
  top: 0;
  left: -50%;
}

.isActive ~ .nav__drawer {
  transform: translateX(0);
  left: 0;
}

.header .inner {
  position: relative;
}

.isActive ~ .js-navBg {
  background: rgba(0, 0, 0, 0.5);
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;

  cursor: pointer;
}

.nav__list a {
  display: block;
  padding: 1rem 0;
}

.nav__list a:hover {
  background-color: orange;
}
```
GitHubアカウントをマージする方法

# 概要
GitHubアカウントを複数運用していたりして、もしなんらかの理由で片方のアカウントを削除してマージしたいなんて場面になった時に向けた記事です。
マージは引き継ぐ形で行います
基本的な引き継ぎとContributionsの引き継ぎ方法について記載します。

1,基本的な引き継ぎ
基本的な部分は全て手作業による引き継ぎになります。
公式ドキュメントが参考になります。

公式ドキュメント(複数のユーザーアカウントをマージする)
https://docs.github.com/ja/free-pro-team@latest/github/setting-up-and-managing-your-github-user-account/merging-multiple-user-accounts

リポジトリのオーナーの変更は
Setting >>Transfer ownership
によって行うことが可能です。

GitHub pagesなども引き継ぎたい場合は都度対応します。

2,Contributions(草)の引き継ぎ
GitHubのContributionsは登録しているemailと紐づいています。
そのため、過去のコミット全てのユーザー名とemailを上書きすることが可能です。
ただし、この方法はコミットが追加される(新たなコミットハッシュが生成される)ので、基本的に非推奨です。
PRを作成しても新しい差分が発生してしまうのでなんらかの特別な事情(そのリポジトリへのコントリビューションに思い入れがあるなど)がない限り捨ててしまうのが良いと思います。

コマンド
これでHEAD以下の全ての過去のコミット履歴を上書きできます。
filter-branchとforce pushを使用するのでリスクは高いです。
何が起きるかはっきりしない、不明確な部分がある場合はgitに詳しい人に相談してから行うか決めてください。

```
//　コミットを変更する
$git filter-branch --commit-filter '
    if [ "$GIT_AUTHOR_NAME" = "<変更前の名前>" ]; then
        GIT_AUTHOR_NAME="<変更後の名前>";
        GIT_AUTHOR_EMAIL="<変更後のメールアドレス>";
        GIT_COMMITTER_NAME="<変更後の名前>";
        GIT_COMMITTER_EMAIL="<変更後のメールアドレス>";
        git commit-tree "$@";
    else
        git commit-tree "$@";
    fi' HEAD

// masterへ force pushする
$git push origin master -f
```

filter-branchは過去のコミット全てを操作できてしまう強力なコマンドです。
windows ファイル・フォルダの削除コマンド

## ファイル削除 

```cmd:単体の削除
$ del /s /q ファイル名
```

拡張子(例えばjpg)を指定して削除するとき、 *.jpg　と入力

## フォルダ削除

```cmd:単体の削除
$ rd /s /q フォルダ名
```

```cmd:複数の削除
$ rd /s /q フォルダ名1 フォルダ名2 フォルダ名3
```

/s：サブフォルダも削除
/q：削除確認メッセージを表示せずに削除

注意
コマンドを実行しても、どこまで削除されているのかがコマンドプロンプトには出力されない。
少し不安になりますが、時間がたてば終わります。

# 参考サイト
[del /s /q コマンドとエクスプローラの削除の違い](http://tooljp.com/windows/chigai/html/Windows/del-command-explorer-del-chigai.html)
[フォルダ（ディレクトリ）を削除する](https://jj-blues.com/cms/wantto-deletefolder/)
【Laravel】Redis::pipelineが爆速だったメモ

最近業務の一貫で他エンジニアのコードレビューをしている時にコメントした件を備忘録として残しておく。

自身が所属するプロジェクトではPHP×Laravelを使用していて、今回以下のような実装要件であった。
`複数のリスト型キーをRedisにセットする`

そして以下のような実装がされていた。

```php
foreach($key_map as $key => $value) {
   Redis::lpush($key, $value);
   Redis::expire($key, self::CACHE_EXPIRE_TIME);
}
```
普通に動くと思うし、パフォーマンスを気にする必要ないのなら、スルーでもいいですが、せっかくなので、
Laravelの公式ドキュメント( https://readouble.com/laravel/5.4/ja/redis.html )をみると、こんなコマンドがあるよと。
>パイプラインコマンド
>一回の操作でサーバに対し多くのコマンドを送る必要がある場合はパイプラインを使うべきでしょう。pipelineメソッドは引数をひとつだけ取り、Redisインスタンスを取る「クロージャ」です。このRedisインスタンスで全コマンドを発行し、一回の操作で全部実行できます。

```php
Redis::pipeline(function ($pipe) {
    for ($i = 0; $i < 1000; $i++) {
        $pipe->set("key:$i", $i);
    }
});
```
ふむふむ、インスタンス内で全コマンドを発行して一回の操作で全部実行とな。
それは確かにパフォーマンス良さそう。

ということで適当にartisanコマンド作って試してみる。
こんな感じ

```php
        // 直接
        $startTime = microtime(true);
        for ($i = 0; $i < $count; $i++) {
            Redis::lpush('test_key' . $i, 'hoge');
        }
        $runningTime =  microtime(true) - $startTime;
        var_dump('straight running time: ' . $runningTime . ' [s]');

        // pipeline
        $startTime = microtime(true);
        $redis = Redis::connection('redis_0');
        $redis->pipeline(function ($pipe) use($count) {
            for ($i = 0; $i < $count; $i++) {
                $pipe->lpush('test_key_pipeline' . $i, 'hoge');
            }
        });
        $runningTime =  microtime(true) - $startTime;
        var_dump('pipeline running time: ' . $runningTime . ' [s]');
```
↓↓結果↓↓

```zsh
// 10件一括
# php artisan redis_test 10
string(42) "straight running time: 0.0122230052948 [s]"
string(46) "pipeline running time: 0.00022292137145996 [s]"

// 1000件一括
# php artisan redis_test 1000
string(43) "straight running time: 0.15764403343201 [s]"
string(45) "pipeline running time: 0.0015499591827393 [s]"
```

パフォーマンス的には<b>100倍</b>くらいでてる。使わない理由はなさそう。
setとかはアトミックにそもそもできるから、使う必要はないだろうけど、
リスト型やハッシュ型とかで複数一括実行が必要になった際は使えそうです。

注意なのが、Redis複数台ある時は、全部に同じコマンドが発行されて無駄が出たりするので、
手前でconnectionごとにグルーピングして、それぞれのRedisサーバーに対して適切なキーリストを渡してあげることかなと思います。

これからも勉学に励みます。
Pacemaker+Corosync PingでNIC監視とリソースのフェイルオーバー


##概要
クラウド環境でのPacemaker+Corosyncのクラスタ構成のシステム構築の際、GW宛のPing結果次第でリソースのフェイルオーバーを実装しようとしたらインターネットに通じるDMZのGWがPingを返さなかった。

GW側の設定変更も難しかった為、場当たり的な対応としてインスタンスの持つNICのIP叩いて監視することに。

## 環境
```
RHEL 7.9
pacemaker-1.1.15
corosync-2.3.6
drbd-9.15.0-1(Master/Slaveリソース)

host1(master):192.168.1.1
host2(slave):192.168.1.2

```

## /etc/hosts
```
192.168.1.1   host1
192.168.1.2   host2
```

## リソース設定
pcsコマンドからリソースを作成する。

PING-HOSTXや各種パラメータは適宜変更
host_listはホスト名でもIPv6でもおーけー。


```
# Pingリソース作成 HOST1
# 今回は自らのNICの監視のみなので --cloneは付与せず
pcs resource create PING-HOST1 ocf:pacemaker:ping \
dampen=5s multiplier=1000 \
host_list=192.168.1.1

# Pingリソース作成 HOST2
pcs resource create PING-HOST2 ocf:pacemaker:ping \
dampen=5s multiplier=1000 \
host_list=192.168.1.2
```
<br>
自分の持つNICに対してのみPing監視を行うように制限を付与する。
(masterのnicが死んだときslaveが死んだnicを見ないように)

```
# 自サーバが保有するNICに向けてPing
# 除外ホスト指定のため、対向のホスト名を入力
pcs constraint location PING-HOST1 avoids host2
pcs constraint location PING-HOST2 avoids host1
```

<br>
pingの結果でMaster/Slaveリソースをフェイルオーバーする。
他にping監視を追加していた場合はそれもフェイルオーバー条件に入るので注意

```
# Ping系が失敗した場合フェイルオーバー
pcs constraint location マスタースレーブリソース \
rule score=-INFINITY pingd lt 1 or not_defined pingd
```


##参考
[6.1. 場所の制約]
(https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/configuring_the_red_hat_high_availability_add-on_with_pacemaker/ch-resourceconstraints-haar#s1-locationconstraints-HAAR)
 [7.3. 接続状態が変化したためリソースの移動を行う](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/configuring_the_red_hat_high_availability_add-on_with_pacemaker/s1-moving_resources_due_to_connectivity_changes-haar)
Mattermost APIを使って投稿の検索結果をファイル出力する

# Mattermost APIを使って投稿の検索結果をファイル出力する

## はじめに

  私のプロジェクトでは、日報代わりに一人ふりかえりとしてMattermostにYWT(やったこと･わかったこと･つぎやること)を投稿し、メンバー内で共有しています。
日報を書き始めて半年以上が経ち、自身の投稿をまとめておきたいと思い、MattermostAPIを使ってファイル出力してみました。

  
## 使用するツール


|      動作確認環境      |   バージョン   |
| ---------------------- | -------------- |
| Windows10 Home Edition | バージョン2004 |
| Docker for Windows     | 2.4.0.0        |
| GitLab                 | 13.4.3         |
| GitLab Mattermost      | 5.26.2         |
| Python                 | 3.8            |
| MattermostDriver       | 6.3            |

GitLab Mattermostは前回(https://qiita.com/shimi58/items/0e9b81f2eac8993be71b)で構築済みのものを使用しています。

## 動くもの

[GitHub](https://github.com/shimi58/mattermostApiPostSearch)に登録しています。

### 使い方

1. mattermostdriverをインストール
    - powerShellまたはコマンドプロンプトで実行

        ```cmd
        pip install mattermostdriver
        ```

1. config.iniを開き、接続先、ログイン情報、検索条件を指定

    ```config.ini
    [CONNECTION]
    # MattermostのURLを指定
    scheme = http
    url = localhost
    port = 9081

    # APIでサインインするユーザーを指定
    login_id = test
    password = Password1!

    [SEARCH]
    # 検索対象のチーム名を指定
    team_name = sample
    # 検索条件を指定
    tearms = #XXXXXXX


    [OUTPUT]
    path = ./mattermostPost.txt
    ```

1. mattermost.pyを実行する

    ```cmd
    python mattermost.py
    ```

## 作ったもの

ソースコートです。

```python
from mattermostdriver import Driver
import configparser

# 定義読み込み
config_ini = configparser.ConfigParser()
config_ini.read('config.ini', encoding='utf-8')

# Mattermostログイン
connection = Driver({
    'url': config_ini['CONNECTION']['url'],
    'login_id': config_ini['CONNECTION']['login_id'],
    'password': config_ini['CONNECTION']['password'],
    'scheme': config_ini['CONNECTION']['scheme'],
    'basepath': '/api/v4',
    'verify': True,
    'port': int(config_ini['CONNECTION']['port']),
    })
connection.login()

# チーム名からTeam IDを取得
teamId = connection.api['teams'].get_team_by_name(config_ini['SEARCH']['team_name'])['id']

# 検索条件に合致する投稿を取得
postMessage = connection.api['posts'].search_for_team_posts(teamId,options={
'terms': config_ini['SEARCH']['tearms']
})

#ファイルオープン
with open(config_ini['OUTPUT']['path'], 'w') as f:

  #検索結果を出力
  for post in postMessage['posts'].values():
    print(post['message'], file=f)
    #区切り文字
    print('====================', file=f)
```

### 参考にしたもの

- [MattermostDriverの公式ドキュメント](https://vaelor.github.io/python-mattermost-driver/index.html)
    こちらに接続方法が書いており、ほぼその通りで接続ができました。  
    また、EndPointsに各APIの引数の情報も書いています。
- [MattermostAPIの公式ドキュメント](https://api.mattermost.com/)
    APIでどのような操作ができるかが記載しています。(当然といえば当然。。)

## さいごに

  MattermostAPIは使用できるAPIも豊富でドキュメントの記載も厚く、特に詰まることなく作れました。
Mattermost自体の検索がイマイチなので、後々抽出した投稿はハッシュタグなんかをつけておくルールにすると、運用しやすいかと。
次は、Botなんかも作ってみたいなぁと思っています。
git pushでremote: Repository not foundと言われる場合の対処法

# 概要
git push がある日できなくなってしまいました。

自分の場合、GitHubアカウントを会社用(エンジニアアカウントとマスターアカウント)と個人用など複数使用していたためGitHub側の認証情報が切り替わっていてこの現象が起きているようでした。

本来、GitHubは規約で１つのアカウント使用することになっています。
なので、会社用アカウントを使用せず、個人アカウントで作業することで大抵は解決できます。
GitHubの規約
https://docs.github.com/en/free-pro-team@latest/github/site-policy/github-terms-of-service

しかし、会社用のマスターアカウントでデータ管理をしていて、複数使わざるを得ない時や人もいるかと思います。もしおきた場合、その場合の対処方を記載します。

# 対処法
httpsではなく、SSHで接続することで解決できます。
その際にすでに作成したリモートリポジトリの登録を削除するコマンドは

```
// すでに作成したリモートリポジトリの登録を削除する
git remote rm origin
```
です。

SSH接続の仕方は
GitHub>プロフィールアイコン>settings>SSH and GPG Keys
で公開鍵を登録します。

小さな事ですが、ある日できなくなるとびっくりしますね。
参考になりますと幸いです。

補足:
GitHubの運用に関してZOZOテクノロジーズさんの記事がとても参考になりました。
こんな感じだと理想的なのだなと思います。
https://techblog.zozo.com/entry/github_sso#%E4%BC%9A%E7%A4%BE%E7%94%A8GitHub%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%82%92%E4%BD%BF%E3%81%84%E7%B6%9A%E3%81%91%E3%82%8B%E5%A0%B4%E5%90%88
Gradleジャーニー：快適なパッケージを求めて

ほぼ動的型付け言語しか使用しないチームに転職し、
┌（ ＾o＾┌ ）┐ <- これのごとく型付けェ型付けェと禁断症状に...
欲求不満に任せ、いつのまにか理想のGradleパッケージのジャーニーへと旅立っていました。
せっかくなので情報整理がてらやりたいこと・過程を紹介します。
あと、Githubにpublicのrepositoryを作っているので、
それをご覧いただくもよし、そのまま流用するもよし(そんな価値があればよいですが...)。
Github Link: [gradle-docker](https://github.com/akotadakura/gradle-docker)
※本記事はJava/Gradle/Dockerなど基礎知識はすでにある前提でお読みください。

### やりたいこと
1. [Dockerにすんなり疎通できる](https://qiita.com/akotadakura/items/ceafd0aea8e419bd1197)
2. テストのフローはきっちり(Junit5 - Jacocoでカバレッジ)(YET)
3. Logも今風(slf4j*logback - Jsonized Log)(YET)
4. 書き方も統制しよう(formatter, linter)(YET)

ここまでやれば、まぁ禁断症状は治まるかと...
あと、これをベースにAWSのコンソール操作を自動化するツールも作るつもりなので...

### プロローグ
生まれたての小鹿パッケージ、作るだけ、作りますか。
gradle initの時の選択肢は、まぁオーソドックスですね。
javaですし、DSLはgroovyですし、テストはJUnitですし🍣。

```console
$ cd '任意のディレクトリ'
$ mkdir 'project name'
$ cd 'project name'
$ gradle init --type java-application
$ gradle wrapper
```
これで、よくある、ローカルにjavaさえ入っていれば
- maven,gradleなくともできますよ、
- gradleは固定ですよ
の環境が出来上がりですね。
あとは最低限のプロジェクト・パッケージ情報をシコシコ仕込みますか。

```gradle:gradle.build
plugins {
  id 'java'
  id 'application'
  id 'idea'
  id 'eclipse'
}

repositories {
  mavenCentral()
}
// パッケージのバージョン指定
project.version = '0.1.1'
// javaランタイムは11(15はそのうち...)
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11

dependencies {
  testImplementation 'junit:junit:4.13'
}

// Runするとき、Appのmain関数を起点に指定
application {
  mainClassName = 'info.akotadakura.App'
}

// UTF-8強要します。
tasks.withType(JavaCompile).all {
  options.encoding = "UTF-8"
}

// java -jarするとき、Appのmain関数を起点に指定
// あとjarファイル名にバージョンつくの嫌だ！
jar {
  archiveFileName = "${project.name}.jar"
  manifest {
    attributes 'Main-Class' : 'info.akotadakura.App'
  }
}
```

実に初々しい...
と、ここにいろいろ付け加えていくことになります。
まずはコンテナ対応、Docker Nativeな時代ですからね。

P.S.
初投稿なので、まさかりはお手柔らかに.....