OmniAICreator/Qiita-1.07M huggingface dataset:
Xperia端末、OpenSLでの録音音声異常問題

# はじめに
最近Xperiaの端末(1 IV等)音声に関する面白い問題を調査したため、その問題と解決方法を記載します。

# 問題概要
ウチのアプリ上Xperia1 IVを利用して配信したら、配信開始後20秒前後で、異常のダイアログが出て、配信終了になる。

# 解決
結論から言います。
OpenSLのEngine起動時、パラメータ``SL_ANDROID_RECORDING_PRESET_CAMCORDER``から``SL_ANDROID_RECORDING_PRESET_UNPROCESSED``へ変更すること。

# 調査経過
ダイアログからエンコード時、音声のタイムスタンプと画像のタイムスタンプが10何秒ずれることにたどり着いた。
↓
そこから音声のエンコード時、異常端末は明らかに遅い。最初は音声エンコードのフォーマットを疑ったが、正常の端末と同様。
↓
そうなると録音音声データの元、マイクからのデータを確認したところ、正常端末の音声データはちゃんと見えるが、異常端末の場合メモリー上0x0000のまま。

音声処理はNative層のOpenSLを利用しているのため、[Androidの関連ページ](https://developer.android.com/ndk/guides/audio/opensl?hl=ja)を確認したら、Oboeという新しい音声処理ライブラリが今のおすすめだそう。まさかOpenSLはもうサポートされないかと思い、[CDD(Android互換性定義)](https://source.android.com/docs/compatibility/12/android-12-cdd?hl=ja#511_capture_for_unprocessed)を開き、OpenSLで検索したら、``SL_ANDROID_RECORDING_PRESET_UNPROCESSED``にたどり着いた。

# 残る疑問
今まで他のAndroid端末、音声処理時``SL_ANDROID_RECORDING_PRESET_CAMCORDER``の設定で動いたけど、Xperiaの特定端末だけ今回の異常が発生する。
Xperiaの端末で``SL_ANDROID_RECORDING_PRESET_CAMCORDER``に関する何らかの実装が行われたと思います。
**もしXperiaのエンジニアがいれば、是非アドバイスやコメントをお願いします！**
もし他のAndroidエンジニアも同じような現象に困っているなら、本記事の方法で試してください。(あんまりないかもしれない)

*以前Xperia端末の音声設定「インテリジェントウインドフィルター」がONの時、録音の音声が雑音になる問題も今回で一緒に解決されると思います。


# 参考リンク
https://developer.android.com/ndk/guides/audio/opensl?hl=ja


https://source.android.com/docs/compatibility/12/android-12-cdd?hl=ja#511_capture_for_unprocessed
CpawCTF Writeup Level 3 Q29.[Crypto] Common World (注意<spoiler>)

# Q29.[Crypto] Common World

```
Cpaw君は,以下の公開鍵を用いて暗号化された暗号文Cを受け取りました．しかしCpaw君は秘密鍵を忘れてしまいました.Cpaw君のために暗号文を解読してあげましょう.

(e, N) = (11, 236934049743116267137999082243372631809789567482083918717832642810097363305512293474568071369055296264199854438630820352634325357252399203160052660683745421710174826323192475870497319105418435646820494864987787286941817224659073497212768480618387152477878449603008187097148599534206055318807657902493850180695091646575878916531742076951110529004783428260456713315007812112632429296257313525506207087475539303737022587194108436132757979273391594299137176227924904126161234005321583720836733205639052615538054399452669637400105028428545751844036229657412844469034970807562336527158965779903175305550570647732255961850364080642984562893392375273054434538280546913977098212083374336482279710348958536764229803743404325258229707314844255917497531735251105389366176228741806064378293682890877558325834873371615135474627913981994123692172918524625407966731238257519603614744577)

暗号文: 80265690974140286785447882525076768851800986505783169077080797677035805215248640465159446426193422263912423067392651719120282968933314718780685629466284745121303594495759721471318134122366715904

これは…？

フラグは以下のシンタックスです.
cpaw{復号した値}

※復号した値はそのままで良いですが，実は意味があります，余力がある人は考えてみてください.
```
RSA暗号

Nをp,qに素因数分解すればよさそう

```.py:q29.py
import sympy

e = 11
n = 236934049743116267137999082243372631809789567482083918717832642810097363305512293474568071369055296264199854438630820352634325357252399203160052660683745421710174826323192475870497319105418435646820494864987787286941817224659073497212768480618387152477878449603008187097148599534206055318807657902493850180695091646575878916531742076951110529004783428260456713315007812112632429296257313525506207087475539303737022587194108436132757979273391594299137176227924904126161234005321583720836733205639052615538054399452669637400105028428545751844036229657412844469034970807562336527158965779903175305550570647732255961850364080642984562893392375273054434538280546913977098212083374336482279710348958536764229803743404325258229707314844255917497531735251105389366176228741806064378293682890877558325834873371615135474627913981994123692172918524625407966731238257519603614744577
c = 80265690974140286785447882525076768851800986505783169077080797677035805215248640465159446426193422263912423067392651719120282968933314718780685629466284745121303594495759721471318134122366715904

[p, q] = sympy.factorint(n)

lcm = sympy.lcm(p - 1, q - 1)
d = sympy.Mod(sympy.Pow(e, -1), lcm)
m = sympy.Mod(sympy.Pow(c, d), n)

print(m)

```
cpaw{424311244315114354}
【UE4】Android の Permission を上書きする

# 方法

`ManifestRequirementsOverride.txt` という名前のテキストファイルを `[ProjectDirectory]/Build/Android` 直下に配置すると、`AndroidManifest.xml` の Requirements 以降がテキストファイルの内容で置換され、デフォルトで定義されている Permission を上書きできる。
これにより Google Play Console でのアプリ提出時に、課金要素が無いのに Billing 関連のエラーでひっかかる問題を回避できたりする。

Android のパッケージングを行うと、そのパッケージに適用された `AndroidManifest.xml` が`[ProjectDirectory]/Intermediate/Android` 内で見つかる。
実際に上書きできているかどうかは、ここを確認すればよい。

例えば UE 4.27 の `AndroidManifest.xml` の Requirements 以降は、デフォルトで以下のようになっている。

```AndroidManifest.xml
<!-- Requirements -->
<uses-feature android:glEsVersion="0x00030001" android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.android.vending.BILLING" />
<!-- Supported texture compression formats (cooked) -->
<supports-gl-texture android:name="GL_KHR_texture_compression_astc_ldr" />
```

ここで WAKE_LOCK 以外の Permission が不要な場合は、`ManifestRequirementsOverride.txt` を以下のようにすればよい。

```xml:ManifestRequirementsOverride.txt
<uses-feature android:glEsVersion="0x00030001" android:required="true" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Supported texture compression formats (cooked) -->
<supports-gl-texture android:name="GL_KHR_texture_compression_astc_ldr" />
```

# おまけ

超裏技的だが、同じ方法で Application Definition を上書きすることもできる。

https://twitter.com/suramaru517/status/1534485676166889473

# 参考

https://historia.co.jp/archives/5892/
業務効率化について

__おすすめの業務効率化Tipsを、コメント欄に記載くださいますと喜びます。__

# 業務を加速するTips集

## 全般

### 昼寝とコーヒー
150mg程度のカフェインと、昼休憩のパワーナップは必須。
昼寝直後は覚醒系のホルモンが分泌されるらしく、圧倒的なパフォーマンスを発揮できる。
15分くらいで元に戻るが。

### ムチン入り目薬
とろ～り。
ドライアイなので。

### 食事と運動
疎かにされがちだが、適度な運動と健康的な食事は仕事のパフォーマンスにも如実に影響する。
タンパク質と食物繊維が大事。
仕事できないやつは大体メタボ。
塩糖脂は悪だって、はっきりわかんだね。

### 論理的思考
MECEだのTAPSだの色々あるフレームワークを**適切に**使うことが大事。
間違った使い方は、自分の首を締める。
KT法なんかは悪い例(結局DAでの点数付けで、採点者の意向が反映されてしまうなど)を生みがち。

### 在宅ワーク
顔を突き合わせるのがほんとのコミュニケーションだ！とか訳分からん事言う輩もいるが、そういう人は大体在宅時はスヤスヤ寝てる。

## ソフト・Webサービス

### Clibor
クリップボードソフト。
WindowsならCliborが使いやすい。
もはやないと仕事にならない。

### Tablucus Explore
標準だとゴミ仕様なExplorerに、色んなアドオンをつけられる様になるソフト。
タブ化でき、前回の利用フォルダが履歴として残るのが素晴らしい。
Windows限定。

### DeepL
言わずと知れた翻訳サイト。ネ申。

### AHK（AutoHotKey）またはKalabiner
キー割り当て系ソフト。後述のゲーミングマウスと組合せで、よく使う機能を登録するのがおすすめ。 

### Todoist
タスク管理サービス。
タスクを階層化でき、無料である事から採用。
ガントチャート化できればもっとよかったのになあ、、
RedmineやWrike、その他色んなツールが登場しているため、好みに合わせて、どうぞ。

### Toggl
タスク時間の記録サービス。
タスク名を記載して時間を測る事ができるのだが、プロジェクト設定やタグ付けも可能であり自分が何にどれだけの時間を割いたかが可視化できる。
また、上記のTodoistとも連携できるため、任意のタスクを起点に時間記録が可能。

下記は、プライベートでの1ヶ月の勉強時間を記録した例。
（※12月は転職前の有給期間のため、平日も記録されている。決してニートではない。)
![スクリーンショット 2022-12-20 19.14.42.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768666/c9570d8a-6785-dffa-2ee2-b176f9255cb4.jpeg)
この例ではプロジェクトを勉強したカテゴリとして、集計している。

## デバイス系

### ノイキャンイヤホン
雑音が集中力を妨げるのは言うまでもなく、ホワイトノイズや自然音を聴きながらタスクを行うのがオススメ。
出社だとイヤホン外せとか訳分からん事言う輩もいるが、そういう人は大体偉そうなだけでろくな仕事してない。

### ゲーミングマウス
デバイスへの投資は賛否両論だが、私は肯定派である。
G604の各ボタンへFunctionキーを割り当て、前述のKalabinerやAHKによりマクロを割り振る事で、コピペやクリップボードソフトへのアクセスをワンアクションで行えるようにしている。

### モニター(アーム)
コーディングを行う方なら縦置き１枚と、資料作成に横置き１枚のトリプルディスプレイがおすすめ。
モニターアームがあると、好みの位置に持ってこれるからなおよし。

### スタンディングデスク
歩く>立つ>座る　の順に脳が働く気がする。
色々研究があるようだが、セロトニンが出やすいんだとか。
もちろん歩きながら仕事は出来ないので、立ち上がる。
ステッパーはお好きに、どうぞ。

### 電気ホットアイマスク
ドライアイなので。

## 資料作成系

### Excel PowerQuery
GUI操作によりデータ加工・集計を行える機能。
VBAや関数も大事だが、本一冊勉強してみると世界が広がるかも。

### Officeショートカットキー全般
Ctrl+C,Vだけでなくいろんなショートカットキーを網羅的に眺めて、よく使いそうなものは覚えてしまおう。
ちなみに、Excelでは"Alt"keyを押すとタブ上にサジェストが表示される。

### Canva
https://www.canva.com/ja_jp/

デザインテンプレートサイト。
スライドテンプレもあるため、デザインの参考にしてしまおう。

## プログラミング系

### Github Copilot
コメントや、記載途中のコード内容を基にコードをサジェストしてくれるAIツール。(サブスク)
今までもテキストエディタを使うことで、ある程度の構文サジェストくらいはできたが、本ツールのサジェストはレベルが違う。
また、Github Copilot Nightlyでは選択範囲の処理を文章化(英語)してくれる機能もあり、他人のコードで何を行っているかわからない時に有用。されには、別の言語への変換も可能。
競合のツールが続々登場しているようだが、しばらくは一強のような気もしている。

### AI Programmer
https://aiprogrammer.hashlab.jp/

日本語で処理を書くと、選択したプログラミング言語でコードをサジェストしてくれるツール。
高度な処理は難しいというのが所感で、SQLなどの簡単な処理をサクッとサジェストしてほしいという時にワンポイント利用するのが適切かもしれない。

### VSCode
説明不要。宗教戦争は知らん。

# 最後に
一般的なJTCでは効率化した仕事や手順は、上司にバレないように黙っておくのが自分の為である。
せっかく時間を生み出しても、余計な仕事を振られかねない。
Windows、Mac、Android、iOS、TVの間で相互に画面共有（ミラーリング）するアプリ、そしてやり方の紹介

<img class="aligncenter" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269229/0920c2e9-1118-4074-8e28-ad82392cbda1.jpeg" alt="FIFAワールドカップをPCで見る方法" width="680" height="450">


お仕事や授業、ソフト開発など様々なニーズで画面共有という機能が必要です。簡単に言いますと、画面共有（画面ミラーリング）とは、デバイスAの画面をそのままデバイスB、C、Dなどに出力することです。特に今のテレワークやオンラインコース、ライブ配信などに応用されています。
それらの原因で本記事では<strong>使いやすい画面ミラーリングアプリ・ソフト</strong>をまとめていきます。あらゆる階層の人々が参照でき、皆さんに役立つだと思います。

<h3>ApowerMirror</h3>
画面ミラーリングにとても人気があるソフト<a href="https://www.apowersoft.jp/phone-mirror?apptype=1116e">ApowerMirror</a>は、個人、会社やグループユーザーが世界中にたくさんいます。主な機能は画面ミラーリングですが、他に録画、ホワイトボード、スクリーンショット、PCでスマホを操作すること、iPhoneでAndroidを操作すること、異なるネットワークを接続しているデバイス間でのミラーリングなどの実用機能が内蔵されています。有線と無線接続に対応しています。使い方はシンプルなので、以下はiPhoneをPCにミラーリングすることを例にします。
<ol>
<li>iPhoneとPCにApowerMirrorをインストールします。</li>
<li>同じネットワークに接続した後両方のデバイスから起動します。</li>
<li>iPhone側で「ローカル」をタップしてPCのデバイス名が検出された後選びます。

![apowermirror-select.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269229/9b8e4456-de8f-f8f0-6a3d-7abc7921b0a9.jpeg)
</li>
<li>「ブロードキャストを開始」をタップすれば、カウントダウン後にiPhoneの画面をPCに出力できます。

![apowermirror-mirroring.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269229/b2919958-73e1-38e2-0f14-7122a055cb44.jpeg)
</li>
<li>Androidも同じ手順です。違いは、PCデバイスを選択した後、スマホで「今すぐ開始」をクリックすることです。

![apowermirror-android-mirroring.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269229/c6d231e6-0f59-c693-6d4e-9c762e762123.jpeg)
</li>
<li>他の機能について、ApowerMirrorのホームページまで確認してお願いします。</li>
</ol>

<h3>LetsView</h3>
<a href="https://letsview.com/jp/?apptype=1116e">LetsView</a>もここでおすすめしたい無料画面ミラーリングアプリです。ミラーリング、録画、ホワイトボード機能はとてもつ使いやすいですが、ApowerMirrorと比べてみると機能が少ないです。それでもその素晴らしいミラーリング機能のため、企業や個人ユーザーが多いです。使い手順はシンプルで、Windows、Mac、Android、iOSデバイス上で動作できます。
<ol>
<li>LetsViewをPCとスマホにインストールします。同じネットワークWi-Fiに接続します。</li>
<li>両方のデバイスで立ち上げます。検出されたデバイスの中でPCデバイスを選択します。</li>
<li>コントロールセンターを開き、「画面ミラーリング」でもう一度PCデバイスを選択すれば、iPhoneをパソコンにミラーリングすることができます。

![letsview-select.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269229/8190e216-66ed-63be-8b58-dd0f26fea58f.jpeg)

![letsview-mirroring.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269229/73d09bf5-cf99-f3a3-2ddd-c7ce6894b38e.jpeg)

</li>
</ol>

<h3>AirPlay</h3>
AirPlayとは、iTunesやiPhone、iPod touch、iPadで再生している音楽や動画、画像を、家庭内のネットワークを経由して他の機器でストリーミング再生する機能である（出典：ウィキペディア）。Apple製品の間でAirPlay機能を利用して画面共有ができるのでとても便利です。Apple製品を使っている方々におすすめです。

![airplay.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269229/59901ba3-4d28-9a3d-96d8-d594bcccb649.jpeg)


<h3>最後に</h3>
他にも画面ミラーリングアプリがたくさんありますが、本記事では体験したアプリしか紹介しません。今の新型ウィルスの時に仕事や勉強をよりスムーズに進むために、ぜひご参考ください。
Powershell 7.3で追加されたコマンド補完機能をオフにする

こんにちは。Powershellについて初投稿です。

# はじめに
先日、Powershellのバージョン7.3がリリースされました。
アップデートしたのですが、見慣れない機能が追加されています。
コマンドを打とうとすると過去の履歴から「このコマンドじゃないですか?」と予測してきます。
![スクリーンショット (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414198/240946a9-3dda-85cc-41d2-054671f7c106.png)

個人的に強制的に目に入ってくるところに情報がでてくるようなおせっかい機能が好きではないので（カイルくんとか）、
機能をオフにしていきます。

# 解決策
消すには以下のコマンドを実行します。
```Powershell
Set-PSReadLineOption -PredictionSource None
```
スッキリしました。
![スクリーンショット (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414198/35d0827c-9160-c340-a705-db8b2d024bd2.png)

ただ残念なことにターミナルを起動し直すと、またコマンド補完が有効になっています。
~~設定変更したら保持しとけよ~~
しょうがないのでプロファイルに無効化コマンドを実行するように登録しておきます。

```:profile.ps1
/* 他の設定項目（あれば） */

Set-PSReadLineOption -PredictionSource None
```


Powershellのプロファイルの初期設定についてはいろいろな記事があるので、ここでは割愛します。

https://qiita.com/smicle/items/0ca4e6ae14ea92000d18

# そもそもこの機能はなんなのか
先に~~お前を消す方法~~コマンド補完機能をオフにする方法を紹介しましたが、
そもそもこの機能は何でしょうか。

Powershell 7.3に付属するPSReadLineツールによるものだそう。
PSReadLineはPowershell向けのコマンド入力補助ツールで、構文エラーの視覚化やタブ補完など複数の機能をもっています。
このタブ補完（予測 IntelliSense）が、今回のおせっかい機能の正体。
いままではユーザが機能を有効化する必要がありましたが、
今回Powershell 7.3に付属したPSReadLine 2.2.6からデフォルトで有効になりました。

# さいごに
カイルくん以来、ひさしぶりにおせっかいな機能が来たなーと思いました。
お仕事用のパソコンでなければ画面を叩き割っているところでしたが、さすがにできませんので
Powershellのプロファイルに無効化コマンドを追加して、事なきを得ました。

# 参考
- [about_PSReadLine](https://learn.microsoft.com/ja-jp/powershell/module/psreadline/about/about_psreadline?view=powershell-7.3)
- [PowerShellの.bashrc的な設定ファイルこと$Profileについての紹介](https://qiita.com/smicle/items/0ca4e6ae14ea92000d18)
配列／テーブルのDIM(*CTDATA オプション指定による要素数設定

V7R4 以上の限定機能となるが、配列／テーブルの定義で `DIM(*CTDATA)` オプションの指定が追加されている。
これにより、コンパイル時・配列／テーブルの要素数指定が、リテラル数値を記述するのではなく、コンパイル時に実在する、配列／テーブルより自動的に要素数が定義される、地味に嬉しい機能だ。

今までのパターンだと、**MSG** テーブルが増えると、毎回 **DIM(xx)** を修正しないとコンパイルエラーになる。そのため、ある程度固定で余分に要素を取るケースもあったり、なかったり。今必要な要素数は「3」だけど、キリが良い「5や10」にするなど。しかし、これにはもう悩まされない、我々には、いつでも `DIM(*CTDATA)` がいてくれるから！もっと早く欲しかった（笑）　:-P

---
### Before
```rpgle:従来：QII0080R.RPGLE
      H DATEDIT(*YMD)
      D*---<< 配列／テーブル --->>*
      D MSG             S             40A   DIM(05) CTDATA PERRCD(1)
      D IX              S              5I 0
      C*
      C                   FOR         IX = 1 TO %ELEM(MSG)
      C     MSG(IX)       DSPLY
      C                   ENDFOR
      C*
      C                   SETON                                        LR
      C                   RETURN
 **CTDATA MSG
  ○○エラーです１
  ○○エラーです２
  ○○エラーです３
  ○○エラーです４
  ○○エラーです５
//----------------------------------------------------------------------------
// コンパイルリスト
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+.
          フィールド        属性               参照（ D= 定義  M= 変更）    
         MSG(5)            A(40)                   3D      5       6       7
                                                   8       9      13M       

```

### After
```rpgle:新：QII0081R.RPGLE
     H DATEDIT(*YMD)
     D*---<< 配列／テーブル --->>*
     D MSG             S             40A   DIM(*CTDATA)
     D IX              S              5I 0
     C*
     C                   FOR         IX = 1 TO %ELEM(MSG)
     C     MSG(IX)       DSPLY
     C                   ENDFOR
     C*
     C                   SETON                                        LR
     C                   RETURN
**CTDATA MSG
 ○○エラーです１
 ○○エラーです２
 ○○エラーです３
 ○○エラーです４
 ○○エラーです５
 ○○エラーです６
//----------------------------------------------------------------------------// コンパイルリスト
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+..
          フィールド        属性               参照（ D= 定義  M= 変更）     
         IX                I(5,0)                  4D      6       7         
         MSG(6)            A(40)                   3D      6       7      12M
```
【CSS】スクロール可能な方向を認識させる影

利用規約のコーディングといえば、めっちゃ長い文章を縦スクロールさせるのが通例ですよね。

しっかし、iPhone だとスクロールバーが表示されず、パッと見スクロールできるのかがわかりません…:weary:

というわけで、スクロール可能な方向を認識させる影を CSS で表現してみました！

## HTML

```html:HTML
<!-- 横スクロール -->
<div class="scrollBox is-horizon">
  <div class="scrollContent"></div>
</div>
scroll-shadow
<!-- 縦スクロール -->
<div class="scrollBox is-vertical">
  <div class="scrollContent"></div>
</div>
```

## CSS

```css:CSS
.scrollBox {
  --background-color-rgb: 255 255 255;
  --shadow-color-rgb: 0 0 0;
  --shadow-size: 50px;
  --shadow-opacity: 0.5;
  height: 500px;
  width: 500px;
  overflow: auto;
}

/* 横スクロール */
.scrollBox.is-horizon {
  overflow: auto;
  background: linear-gradient(
      90deg,
      rgb(var(--background-color-rgb)) 50%,
      rgb(var(--background-color-rgb) / 0)
    ),
    linear-gradient(
        90deg,
        rgb(var(--background-color-rgb) / 0),
        rgb(var(--background-color-rgb)) 50%
      )
      0 100%,
    radial-gradient(
      farthest-side at 0 50%,
      rgb(var(--shadow-color-rgb) / var(--shadow-opacity)),
      transparent
    ),
    radial-gradient(
        farthest-side at 100% 50%,
        rgb(var(--shadow-color-rgb) / var(--shadow-opacity)),
        transparent
      )
      0 100%;
  background-color: rgb(var(--background-color-rgb));
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
  background-position: 0 0, 100%, 0 0, 100%;
  background-size: calc(var(--shadow-size) * 2) 100%,
    calc(var(--shadow-size) * 2) 100%, var(--shadow-size) 100%,
    var(--shadow-size) 100%;
}
.scrollBox.is-horizon .scrollContent {
  width: 300%;
}

/* 縦スクロール */
.scrollBox.is-vertical {
  background: linear-gradient(
      rgb(var(--background-color-rgb)) 50%,
      rgb(var(--background-color-rgb) / 0)
    ),
    linear-gradient(
        rgb(var(--background-color-rgb) / 0),
        rgb(var(--background-color-rgb)) 50%
      )
      0 100%,
    radial-gradient(
      farthest-side at 50% 0,
      rgb(var(--shadow-color-rgb) / var(--shadow-opacity)),
      rgb(var(--background-color-rgb) / 0)
    ),
    radial-gradient(
        farthest-side at 50% 100%,
        rgb(var(--shadow-color-rgb) / var(--shadow-opacity)),
        rgb(var(--background-color-rgb) / 0)
      )
      0 100%;
  background-color: rgb(var(--background-color-rgb));
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
  background-size: 100% calc(var(--shadow-size) * 2),
    100% calc(var(--shadow-size) * 2), 100% var(--shadow-size),
    100% var(--shadow-size);
}
.scrollBox.is-vertical .scrollContent {
  height: 300%;
}
```

## DEMO

<p class="codepen" data-height="500" data-default-tab="result" data-slug-hash="gOKmBWR" data-user="taqumo" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/taqumo/pen/gOKmBWR">
  CSS Scroll Shadow</a> by Takuya Mori (<a href="https://codepen.io/taqumo">@taqumo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
CpawCTF Writeup Level 3 Q26.[PPC]Remainder theorem (注意<spoiler>)

# Q26.[PPC]Remainder theorem


```:CpawCTF
x ≡ 32134 (mod 1584891)
x ≡ 193127 (mod 3438478)

x = ?


フラグはcpaw{xの値}です！
```


modの理解ができていればコードを書くだけ

```:q26.cpp
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)

int main(){
    long long x;
    for(long long i = 0;;i++){
        x = i * 1584891 + 32134;
        if(x % 3438478 == 193127){
            cout << x << endl;
            break;
        }
    }
    return 0;   
}
```

注意としては値が大きいのでlong longを使った方がよい。（int型だと違った値になる）

cpaw{35430270439}
【React】memo()やstyled()を使うとジェネリクスが効かなくなる

# 解決方法
`memo()`の戻り値の型を`as typeof Component`で上書きします。

```tsx
/** React `memo()` */
const MemoButton = memo(Button) as typeof Button;
/** MUI(Emotion) `styled()` */
const StyledButton = styled(Button)({ ... }) as typeof Button;
/** MobX React `observer()` */
const ObserverButton = observer(Button) as typeof Button;
```

# 初めに

内部のコンポーネントを上書きする仕組みを提供するためにTypeScriptのジェネリクスを利用してコンポーネントを作る事があると思いますが、後に最適化のためmemoを使用したらジェネリクスが機能しなくなりました。

# ジェネリックなコンポーネントとは

例えば、`React.ElementType`を継承する`T`のジェネリックな`Hoge`を定義して、そのプロパティに`React.ComponentPropsWithRef<T>`を指定しておいて、

```tsx
function Hoge<T extends React.ElementType = 'div'>({ component, ...props }: { component: T } & React.ComponentPropsWithRef<T>) {
  const Component = component ?? 'div';

  return <Component {...props} />
}
```

`component`に特定のコンポーネントを指定したら、そのコンポーネントのプロパティが`Hoge`のプロパティとして補完に表示されるようになります。

```tsx
function Fuga({ property1 }: { property1: string }) { ... }

// `property1`(`Fuga`のプロパティ)が`Hoge`のプロパティに追加され、補完に表示される。
<Hoge component={Fuga} property1="1234">...</Hoge>
```

私はMUIをよく利用するのですが、MUIとReact Routerでよく以下のようにしてボタンリンクを簡単に作成しています。

```tsx
// `to`(`Link`のプロパティ)が`Button`のプロパティに追加され、補完に表示される。
// 必須なので指定していないと怒られる。
<Button component={Link} to="/profile">プロフィール</Button>
```

# `memo()`や`styled()`と併用できない

ジェネリックなコンポーネントは簡単に動作を上書き出来て便利ですが、`memo()`や`styled()`を使うとジェネリクスが機能しなくなります。

```tsx
/** React `memo()` */
const MemoButton = memo(Button);
/** MUI(Emotion) `styled()` */
const StyledButton = styled(Button)({});
/** MobX `observer()` */
const ObserverButton = observer(Button);

// OK
<Button component={Link} to="/profile">プロフィール</Button>
// NG
// `to`が存在しないと言われる。
<MemoButton component={Link} to="/profile">プロフィール</Button>
// NG
<StyledButton component={Link} to="/profile">プロフィール</Button>
// NG
<ObserverButton component={Link} to="/profile">プロフィール</Button>
```

# `as typeof Component`で型を上書きする

`memo()`を使わないわけにはいかないので、少々強引ですが`as typeof Component`で`memo()`の戻り値の型を上書きします。

```tsx
/** React `memo()` */
const MemoButton = memo(Button) as typeof Button;
/** MUI(Emotion) `styled()` */
const StyledButton = styled(Button)({}) as typeof Button;
/** MobX `observer()` */
const ObserverButton = observer(Button) as typeof Button;
```

# 終わりに

この問題について[#37087](https://github.com/DefinitelyTyped/DefinitelyTyped/issues/37087)でも議論されていますが、`as typeof`で型を上書きする方法にリアクションがたくさんついているので、現状はこの方法で凌ぐのが簡単そうです。

他に良さげな方法をご存じでしたらぜひ教えてください！
Leetcode 1926. Nearest Exit from Entrance in Maze

# 1926. Nearest Exit from Entrance in Maze
https://leetcode.com/problems/nearest-exit-from-entrance-in-maze/description/

## アプローチ
### BFS

```java
class Solution {
    public int[] dx = {1, 0, -1, 0};
    public int[] dy = {0, 1, 0, -1};
    public int height;
    public int width;
    public boolean[][] isVisited;
    public Queue<Point1926> q;
    public int result = Integer.MAX_VALUE;

    public int nearestExit(char[][] maze, int[] entrance) {

        height = maze.length;
        width = maze[0].length;
        isVisited = new boolean[height][width];

        q = new LinkedList<>();

        q.add(new Point1926(entrance[0], entrance[1], 0));
        isVisited[entrance[0]][entrance[1]] = true;


        while (!q.isEmpty()) {
            Point1926 now = q.poll();

            for (int i = 0; i < 4; i++) {
                int nextX = dx[i] + now.x;
                int nextY = dy[i] + now.y;

                if (nextX < 0 || height <= nextX || nextY < 0 || width <= nextY) {
                    if (now.count == 0) {
                        continue;
                    }
                    result = Math.min(now.count, result);
                    continue;
                }

                if (isVisited[nextX][nextY] == true) {
                    continue;
                }

                if (maze[nextX][nextY] == '+') {
                    continue;
                }

                q.add(new Point1926(nextX, nextY, now.count + 1));
                isVisited[nextX][nextY] = true;


            }
        }
        return result == Integer.MAX_VALUE ? -1 : result;

    }
}

class Point1926 {
    int x;
    int y;
    int count;

    Point1926(int x, int y, int count) {
        this.x = x;
        this.y = y;
        this.count = count;
    }
}
```
配列になっているJSONの値を複数レコードとして保存する

railsでJSONファイルで値を受け取る際、その値が配列になっていたとします。これをいい感じにdbに保存する方法を模索しました。
## 結論
each文で回すしかなくない？
私の技術力不足、ググり力不足かもしれないけどeach文で回して値整理してって感じしか思いつかない。

## 私の実装方法
想定しているJSON
```json
{
    "proposed_days": [
		"2022-11-14T18:15:45.087+09:00",
		"2022-11-14T18:16:45.087+09:00",
		"2022-11-14T18:52:09.671+09:00"
	]
}
```
controllerでの処理
```ruby
proposed_days_params.each do |proposed_at|
    render json: event.errors unless possible_dates.create(proposed_at:)
end

private
def proposed_days_params
   params.require(:proposed_days)
end
```
ちょっと端折ってるけどこんな感じ。他にいい方法あるのかな。見つかったら追記します。
ブックマークの使い方について

ブックマークを整理するにあたって思いついたことをルール化や習慣化できるようまとめます。
11/15　google chromeの使用者向け

### 初めに
ブックマークマネージャーというものがあることが分かりました。
“ブックマークマネージャ”を呼び出すショートカットキーは［Ctrl］＋［Shift］＋［O］で開くことができます。
ルール化や習慣化に関して、皆さんも参考になる点がありましたら、是非真似してみてください。
![bookmark5a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/3a503631-bca7-29df-9eca-205846d450f4.jpeg)


## ブックマークのルール４つ
### 1、先にフォルダを作ってしまう
### 2、名前を２階層目に着ける
### 3、ブックマークの名前を変更する
### 4、３階層以上入り込まない

一つずつ詳しく説明していきます。

#### 1 先に（フォルダ)を作ってしまう
![bookmark1a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/a1e6e24d-984b-a806-c115-29cd45ebdd3c.png)

フォルダの数や使い方を先に考えておきましょう。
自分の場合は１～７には、よく使うファイル8～14にはよくアクセスするわけではないけど、残しておきたいブックマークを分類しています。
分類分けとしては「金融機関」「SNS」「趣味」など、人によって色々違うとは思います。


ちなみに、新しいフォルダの名前が思いつかないときは日付を名前にしてしまっています。

#### 2 名前を２階層目に着ける
![bookmark2a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/12e944ef-868f-4e62-fa12-6534743bf18d.png)

これはリモートでの画面共有やスクリーンショットの際に余計な情報（個人情報）が移るのをさけるためです。ブログなどアウトプットが増え始めてきずきましたが、検索履歴やブックマークが画面映り込むのは、結構恥ずかしい思いをすることがありました。
（「転職」のワードが並( ﾟДﾟ)んだブックマークを会社の同僚に見られたときは笑って誤魔化しました。( ﾟДﾟ)

ちなみにフォルダの名前だけで空にしています。

#### 3 ブックマークの名前を変更する
![bookmark3a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/a658aba6-80db-5db9-1c6a-a326b60e5b28.png)

公式サイトの一ページ目などは、短くてわかりやすいのですが、普段使わないけど１年以内には再度アクセスしそうだなと思うものは、名前を変えてしまった方が分かりやすいです。
何を調べるためにブックマークしているのか、名前を付けられないのであれば素直にブックマークから外してしまった方がいいかもしれません。

#### 4 ３階層以上入り込まない
![bookmark4a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/c2c95d74-b91e-9236-86df-fa97cb62006f.png)

これはマウスのカーソルやスマホでの利用も考えたときに、使いにくいと感じたためです。
ブックマークは、使いこなしている人だと100～700個ほどあるらしいです。そのためには
一ファイルに10個前後のブックマークがあるとして、
10×7×10個ほどあればよいと思っています。
1階層目は、chromeの検索部分を開いたときに見えるファイル
自分の場合1から14の数字で書いていますが、空の部分あるので実際には10個前後しか使っていません。
2階層目は、1階層目を開いて見えるフォルダでファイルの名前ようフォルダもここに入ります。後はよく使うTwitterやQiitaのブックマークはここにあった方が早くアクセスできます。
3階層目は、実際のブックマークで毎日アクセスはしないけれども、残しておきたいものや再度調べなおすときに必要なブックマークを整理しておきます。

まとめ
ブックマークをまとてみて、どこから情報を探しているのか見返すいい機会になりました。Google検索　1ページ目に表示されるサイトは、すごく読みやすいけれども抽象的で、多くの人を対象とした記事がヒットすることが多いので、ブックマークをしっかり残して情報を得ることは大切だと感じました。

個人的には、3「ブックマークの名前を変更する」というルールをこれから大切にしていきたいです。何を探すための情報源だったのか頭の中で言語化して整理できるからです。

以上

最後まで読んでいただきありがとうございました。

追記
「bukku」→（ぶっく）と打つところを
「book u」→（ぼおく）にタイプミスを何度もしました。
ESP32: Hello World

Ubuntu 24.10 上の Arduino IDE 2.3.4 を使います。

```bash
./arduino-ide_2.3.4_Linux_64bit.AppImage --no-sandbox
```

ボードは、
ESP32 Dev Module
です。

```text:hello_world.ino
// ---------------------------------------------------------------------
/*
	hello_world.ino

						Jan/28/2025
*/
// ---------------------------------------------------------------------
#define	PROGRAM	"hellow_world.ino"
#define	VERSION	"2025-01-28 PM 16:47"

int count = 0;
// ---------------------------------------------------------------------
void setup()
{
	Serial.begin(115200);
	
	delay(1000);
	Serial.println("*** start ***");
	delay(1000);
	Serial.println(PROGRAM);
	Serial.println(VERSION);
	Serial.println("*** setup end ***");
}

// ---------------------------------------------------------------------
void loop() 
{
	Serial.println(PROGRAM);
	Serial.println(VERSION);
	Serial.println("Hello World! " + String(count));
	delay(1000);
	Serial.println("Good Morning! " + String(count));
	delay(1000);
	Serial.println("こんにちは " + String(count));
	Serial.println();
	delay(3000);
	count++;
}

// ---------------------------------------------------------------------
```

コンパイルとアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/ae6e0e21-fe7e-9751-f43d-6188be740e85.png)


シリアルポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/cc441590-c8fc-bb63-cf16-3585ce580e76.png)


ターミナルで接続した結果

```text
$ cu -l /dev/ttyUSB0 -s 115200
Connected.
Good Morning! 63
こんにちは 63

hellow_world.ino
2025-01-28 PM 16:47
Hello World! 64
Good Morning! 64
こんにちは 64

hellow_world.ino
2025-01-28 PM 16:47
Hello World! 65
Good Morning! 65
こんにちは 65
```

## M5Core2
このプログラムはそのまま M5Core2 で使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/505c3ab9-4564-4401-f5c4-43eb6483cba4.png)


実行結果

```text
$ cu -l /dev/ttyUSB0 -s 115200
Connected.
hellow_world.ino
2025-01-28 PM 16:47
Hello World! 11
Good Morning! 11
こんにちは 11

hellow_world.ino
2025-01-28 PM 16:47
Hello World! 12
Good Morning! 12
こんにちは 12

hellow_world.ino
2025-01-28 PM 16:47
Hello World! 13
Good Morning! 13
こんにちは 13
```
【2022年更新】プログラミング無料学習サイト5選!独学での勉強に役立つ

最近とても流行っているプログラミングサイトをいくつかお勧めします。プログラミングの効率を高め、よりよく独学に役立つと思います。
## 1.AtCoder
AtCoderは、プログラミング初級者から上級者まで楽しめる、日本国内最大の競技プログラミングコンテストサイトです。オンラインで毎週開催プログラミングコンテストを開催しています。競技プログラミングを用いて、客観的に自分のスキルを計ることのできるサービスです。
**【リンク】https://atcoder.jp/**
![代替テキスト](https://jp.scrapestorm.com/wp-content/uploads/2022/07/1.AtCoder.png)
## 2.Paiza
paizaラーニングは、オンラインでプログラミングしながらスキルアップできる、プログラミング入門学習コンテンツです。Paiza独自のシステムにより、面倒な環境構築が不要、Webブラウザがあれば5秒で学習が開始できます。わかりやすい1本3分の動画と豊富な演習問題で初心者〜中級者のプログラミング学習を支援します。
**【リンク】https://paiza.jp/works**
![代替テキスト](https://jp.scrapestorm.com/wp-content/uploads/2022/07/2.Paiza_.png)
## 3.Progate
Progateはオンラインプログラミング学習サービスです。「初心者から、創れる人を生み出す」を理念として、プログラミング初心者のハードルを出来る限り取り払うこと、そして本当に創れるようになるレベルの高い学習を提供することを目指しています。
**【リンク】https://prog-8.com/**
![代替テキスト](https://jp.scrapestorm.com/wp-content/uploads/2022/07/3.Progate.png)
## 4.CodeMonkey
「コードモンキーJr.」 は、幼児・未就学児を対象としたコースです。 ゲーム感覚で、コーディングの基礎を学習します。コーディングブロックを操作して、ビジュアルプログラミングによって一連のプログラムを組み立て、サルのモンタが宝箱へたどり着くように手助けします。
**【リンク】https://codemonkey.jp/**
![代替テキスト](https://jp.scrapestorm.com/wp-content/uploads/2022/07/4.CodeMonkey.png)
## 5.Codepen
CodepenはオンラインフロントエンドプログラミングWebサイトです。ここでは、多くのフロントエンドコードを見つけます。さまざまなWebページのレイアウトコードに加えて、より多くの種類の楽しくてクールで斬新なフロントエンドアニメーションと特殊効果があります。
**【リンク】https://codepen.io/**
![代替テキスト](https://jp.scrapestorm.com/wp-content/uploads/2022/07/5.Codepen.png)
難題を切り刻め！

皆さんは、難題を目の当たりにした時にどうしてますか？

難題の種類といしては、
・問題が大きすぎて全体像がよく見えない
・体験した事が無いのでよく分からない
・色んな情報が錯綜していて問題の本質が見えない
等があると思います。

# そんな時は、難題を切り刻め！
中学でならった因数分解。これの目的って覚えてますか？
因数分解は、２次方程式や３次方程式等の方程式を解くための前準備でした。公式に当て込む事が出来れば解を求める事が出来ますが、問題に出てくる式は、そのままでは利用出来ません。そのため、事前に因数分解をやって、公式に当てはまる形に変換して公式をときます。
これと同じで、難題も小さく分解していけば、実は過去に扱った公式に当てはめて解決できる事が多いです。
いきなり問題を解こうとするのではなく、事前準備が大事という事です。

# 問題が大きすぎて全体像がよく見えない時は
先ずは現状を小さく分解して整理します。現状が小さく整理できれば、今度はそれを抽象化すれば全体像が見えてきます。**一度小さくして、抽象化する**。これにより、課題の数や課題の関係性、ボトルネックが見えてきます。
よく見る失敗例としては、問題が大きすぎて全体像がよく見えない状態で、１つの課題に対してフォーカスして解決しようとする事です。局所的に課題を対処しても課題が絡み合っている時は、全く解決しない事が多いです。
これは、フィードバックの連続によって世の中が成り立っているからです。つまり、ある事象が起こると次の事象につながる。更にその事象から次の事象へと雪だるま式に起こるので、ただ１点の課題を解決しても他の事象が起こるし、そもそも、その解決しようとしている課題は、別の場所から発生した課題の可能性もあります。
先ずは、**一度小さくして、抽象化してみてください**。

# 体験した事が無いのでよく分からない時は
目的を分解して、出来るタスクに分解して下さい。
例えば、来Qでシステムのパフォーマンスを10%アップさせる。コストを15%ダウンさせる。
こんな時、どこから手をつけて良いのか分からない事が多いと思います。
こんな時は、先ずは、**出来るタスクに分解して下さい。**
システムのパフォーマンスをアップさせるためには、
１．サーバーのパフォーマンスを向上させる
１−１．プログラミングでCPU利用を減らす
１−2．プログラミングでメモリ利用を減らす
１−3．プログラミングでDBアクセス数を減らす
１−4．プログラミングでAPIアクセス数を減らす
といった具合に小さなタスクに分解すれば、やる事が見えてきます。**オートマチックに小さなタスクをクリアすれば、大きな目的がクリア出来る状態に変化しているでしょう。**

# 色んな情報が錯綜していて問題の本質が見えない時は
情報を整理して、どこが課題がを分析してみて下さい。
例えば、Lineメッセージ配信で負荷が掛かってシステムがダウンしたけど、サーバーが悪いという人、データベースが悪いという人、プログラミング（SQL)が悪いという人。色々とあると思います。
こんな時は、
・ネットワークの問題（ネットワークトラフィックやLB）
・サーバーの問題（CPUやメモリ、ロードアベレージ）
・データベースの問題（CPUやメモリ、ロードアベレージ）
・外部APIの問題（レスポンススピード、回数）
・キャッシュの問題（レスポンススピード、回数）
等、全てをチェックしボトルネックを把握し対処していきます。もちろん、一つのボトルネックが解消されると別の部分がボトルネックになったりするので、これを何度も繰り返します。
負荷が高いからと言ってサーバーのspecだけを上げてもコストの無駄になるだけです。課題を整理して分析しましょう。

# 最後に
この他にも難題に対して、動けなくなる時は沢山あると思いますが、難題なんて小さくすれば怖くない！
全ての難題は、小さく切り刻めば、自分の手のひらで解決できます。
怖がらずに、焦らずに対処してみて下さい
皆既日食と皆既月食のcssを作ってみた


2022年11月8日に皆既月食があり全国で話題となったので、CSSで皆既日食と皆既月食を作ってみました。


# 皆既日食

>　日食[1]（にっしょく、solar eclipse[1]）とは太陽が月によって覆われ、太陽が欠けて見えたり、あるいは全く見えなくなったりする現象である。

[日食 - Wikipedia](https://ja.wikipedia.org/wiki/%E6%97%A5%E9%A3%9F)

`boxshadow`でぼかしを入れることで良い感じの雰囲気ができました。


<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="oNyeNgb" data-user="mori-goq" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mori-goq/pen/oNyeNgb">
  皆既日食</a> by mori (<a href="https://codepen.io/mori-goq">@mori-goq</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 皆既月食

>　月食[1]（げっしょく、英語: lunar eclipse[1]）とは地球が太陽と月の間に入り、地球の影が月にかかることによって月が欠けて見える現象のことである。

[月食 - Wikipedia](https://ja.wikipedia.org/wiki/%E6%9C%88%E9%A3%9F)

皆既月食は`#moon`に`overflow: hidden;`をつけて#earthとの乗算で赤色にしたかったのですが、四角で効いてしまうため、`clip-path: circle(50%);`で円で効くようにしてます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="WNyENbJ" data-user="mori-goq" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mori-goq/pen/WNyENbJ">
  皆既月食</a> by mori (<a href="https://codepen.io/mori-goq">@mori-goq</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# まとめ

cssだけでも、簡単に綺麗な皆既日食・月食が作れました。


# 最後に
### GoQSystemでは一緒に働いてくれる仲間を募集中です！
ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site?qiita=60ea8111a8955f5d9c62
業務プロセスの改善

# 業務プロセスの改善
企業内の業務には```一定の実施順序があり、この一連の流れ```を```業務プロセス(ビジネスプロセス)```という。また、情報技術やインターネットを活用して、```消費者や取引先とのアクセスから決済・配送までの一連の経済行為をシステム化し、モデル化```したものを```ビジネスモデル```と呼ぶ。
業務プロセスを見直して、効率化・最適化を行うため方法として次のようなものが出題されています。

### BPR(Business Process Re-engineering: 業務プロセス再構築)
業務全体を一つのプロセスと捉え、その流れに基づいて```情報システムを抜本的に再構築```すること。
部門間のセクショナリズムを克服し、```業務の合理化やコスト削減```を目指す。

#### セクショナリズムとは？
集団や組織において、各部門が自分たちが持つ権限や利害にこだわって外部からの干渉を排除し、部門間で協力せず、組織全体の利益や効率性を考えずに行動する状態のことを言います。官僚主義にありがちな「縄張り争い」「派閥主義」などがこれにあたります。
出典 
### BPM(Business Process Management)
業務分析、設計、業務プロセス構築、プロセスの実行とモニタリング、評価といった```PDCAサイクルを繰り返し```ながら、```業務プロセスを継続的に監視・改善していく管理手法```。BPMを実施・運用するための基盤となる仕組みを```BPMS(BPM System）```という。

### BPO(Business Process Outsourcing)
自社の業務プロセスの一部を```外部の専門業者へアウトソーシング（委託)```すること。
#### オフショア(offshore)
国内企業から見た海外を意味する用語。
業務プロセスにおいては、```情報システムの開発や運用を人件費の安い海外の企業や子会社に委託```すること。
```オフショア開発```、```オフショアアウトソーシング```などがある。

### 事務的な作業の自動化
#### RPA(Robotic Process Automation)
標準化された常型業務を、```人間に代わって自動的に処理するシステム```。人が行うソフトウェアの操作を```模倣させて作業```を行う。一つのソフトウェアで動作するマクロとは異なり、```複数のソフトウェアをまたがった操作を実行させることも```できる。

#### ワークフローシステム
ペーパーレスによる事務手続きを行うためのシステム。稟議書などを、承認を得るべき担当者に回覧し、最終的に```決済を得るまでの作業を自動化```することができる。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
CpawCTF Writeup Level 3 Q24.[Web]Baby's SQLi - Stage 2- (注意<spoiler>)

# Q24.[Web]Baby's SQLi - Stage 2-
内容にはこう書かれている
```:CpawCTF
さてはStage 1をクリアしてないな．
待っているから，先にStage 1をクリアしてからもう一度来てね．
```

ヒントとなるものがStage 1にあるよう。

Q22に戻り、再度フラグを取得すると、next stage urlが書かれているのでそのurlに飛ぶ。

ユーザー名は既に書かれているため、パスワードを入れればよい。

一般的なSQLiの方法で試せばログインできる。

~~~:SQLi
' OR 1=1--
~~~

ログインが成功するとフラグが取得できる。


cpaw{p@ll0c_1n_j@1l3:)}
DataGridViewでCellの値をソース上で変更してもRowstateがModifiedにならない

ソース上でCellの値を変更するとBeginEditが自動で開始されており、
Cellの値を変更した後にEndEditを実行することでRowstateに変更が反映される。(Modified)
(EndEditを実行しないとRowstateがunchangedで変更されておらず困った)

    'セルの値を変更することで自動的にBeginEdit()が開始される
    hoge.Rows(0).Cells("仕入先コード").Value = strShiiresakiCodeValue

    hoge.Rows(0).Cells("仕入先名称").Value = strShiiresakiNameValue

    'セルが変更されたことを明示的に知らせる(RowstateにModifiedをセット)
    hoge.Rows(0).EndEdit()
UWP SoftwareBitmapの画素データをbyte配列に格納する

# 実現したい内容

画像について、画素(ピクセル)の情報の確認や、色や明るさなどの変更を行いたい。そのため、`SoftwareBitmap`で管理する画像の画素情報を`byte`配列に格納し、BGRAの操作をできるようにする。

# 対処その1

`SoftwareBitmap`から、`WritableBitmap`の`IBuffer`にデータをコピーし、`IBuffer`から`stream`を介して、`byte`配列に読み込む。

:::note
Microsoft Docsの`SoftwareBitmap.CopyToBuffer()`のRemarksをヒントにした方法
:::

```C#:WriteableBitmapのIBufferを活用
WriteableBitmap wb = new WriteableBitmap(_SourceBitmap.PixelWidth, _SourceBitmap.PixelHeight);

using (SoftwareBitmap sb = SoftwareBitmap.Copy(_SourceBitmap))
{
    sb.CopyToBuffer(wb.PixelBuffer);
}

int n = (int)wb.PixelBuffer.Length;
_SourceByteArray = new byte[n];

using (Stream stream = wb.PixelBuffer.AsStream())
{
    await stream.ReadAsync(_SourceByteArray,0,n);
}
```

- `_SourceBitmap`: コピー元の`SoftwareBitmap`
- `_SourceByteArray`: コピー先の`byte`配列

## 逆手順：byte配列からSoftwareBitmapの生成

同様にWritableBitmapを用いて逆の手順を実現できる。

`WriteableBitmap`の`IBuffer`に`stream`を介して`byte`配列からデータを読み込み、`IBuffer`から`SoftwareBitmap`にデータをコピーする。

```C#:byte配列からSoftwareBitmapを生成
WriteableBitmap wb = new WriteableBitmap(w, h);
SoftwareBitmap tgt = new SoftwareBitmap(BitmapPixelFormat.Bgra8, w, h);

using (var stream = wb.PixelBuffer.AsStream())
{
    await stream.WriteAsync(_TargetByteArray, 0, _TargetByteArray.Length);
    tgt.CopyFromBuffer(wb.PixelBuffer);
    _TargetBitmap = SoftwareBitmap.Copy(tgt);
}
```

- `_TargetByteArray`: コピー元の`byte`配列
- `_TargetBitmap`: コピー先の`SoftwareBitmap`

# 対処その2

以前、やや苦し紛れに書いたもの。対処その1より効率は落ちると思うが、何らか別の用途があるかもしれない。

- `SoftwareBitmap`を`BitmapEncoder`にセットし`stream`に書き出し。
- `stream`を用いて`BitmapDecoder`を生成。
- `BitmapDecoder`から`PixelDataProvider`を生成。
- `PixelDataProvider`から`byte`配列を得る。

```C#:BitmapEncoder,BitmapDecoderを活用
using (SoftwareBitmap sb = SoftwareBitmap.Copy(_SourceBitmap))
{
    BitmapEncoder encoder;
    InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
    encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, ras);
    encoder.SetSoftwareBitmap(sb);

    try
    {
        await encoder.FlushAsync();
    }
    catch (Exception e)    {
        Debug.WriteLine("err in encoding image: {0}", e.Message);
        return 0;
    }

    ras.Seek(0);

    BitmapDecoder decoder;
    decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.BmpDecoderId, ras);
    PixelDataProvider provider = await decoder.GetPixelDataAsync();

    _SourceByteArray = provider.DetachPixelData();
}
```

- `_SourceBitmap`: コピー元のSoftwareBitmap
- `_SourceByteArray`: コピー先のbyte配列
CpawCTF Writeup Level 3 Q23.[Reversing]またやらかした！ (注意<spoiler>)

# Q23.[Reversing]またやらかした！
rev200をghidraで解析する

Windows10 で Ghidra を動かす　https://hi120ki.github.io/blog/posts/20200109/

fileから新規プロジェクトを選択。適当なディレクトリでプロジェクト作成する。

選択したディレクトリにrev200をコピーする。

rev200をクリックすると解析が始まる。

解析のフィルタからmainを入力し選択。

右の解析出力にｃのコードが出力される。

~~~c:rev200.cpp
undefined4 main(void)

{
  int iVar1;
  uint *puVar2;
  int local_84;
  uint local_7c [14];
  uint local_44 [14];
  
  local_7c[0] = 0x7a;
  local_7c[1] = 0x69;
  local_7c[2] = 0x78;
  local_7c[3] = 0x6e;
  local_7c[4] = 0x62;
  local_7c[5] = 0x6f;
  local_7c[6] = 0x7c;
  local_7c[7] = 0x6b;
  local_7c[8] = 0x77;
  local_7c[9] = 0x78;
  local_7c[10] = 0x74;
  local_7c[11] = 0x38;
  local_7c[12] = 0x38;
  local_7c[13] = 100;
  puVar2 = local_44;
  for (iVar1 = 0xe; iVar1 != 0; iVar1 = iVar1 + -1) {
    *puVar2 = 0;
    puVar2 = puVar2 + 1;
  }
  for (local_84 = 0; local_84 < 0xe; local_84 = local_84 + 1) {
    local_44[local_84] = local_7c[local_84] ^ 0x19;
  }
  return 0;
}

~~~

エラーとなる文を修正し、コードを実行するとフラグが現れる。

~~~c++:rev200fix.cpp
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)

int main(void)

{
  int iVar1;
  unsigned int *puVar2;
  int local_84;
  unsigned int local_7c [14];
  unsigned int local_44 [14];
  
  local_7c[0] = 0x7a;
  local_7c[1] = 0x69;
  local_7c[2] = 0x78;
  local_7c[3] = 0x6e;
  local_7c[4] = 0x62;
  local_7c[5] = 0x6f;
  local_7c[6] = 0x7c;
  local_7c[7] = 0x6b;
  local_7c[8] = 0x77;
  local_7c[9] = 0x78;
  local_7c[10] = 0x74;
  local_7c[11] = 0x38;
  local_7c[12] = 0x38;
  local_7c[13] = 100;
  puVar2 = local_44;
  for (iVar1 = 0xe; iVar1 != 0; iVar1 = iVar1 + -1) {
    *puVar2 = 0;
    puVar2 = puVar2 + 1;
  }
  for (local_84 = 0; local_84 < 0xe; local_84 = local_84 + 1) {
    local_44[local_84] = local_7c[local_84] ^ 0x19;
  }
  char c;
  rep(i,14){
    c = local_44[i];
    cout << c ;
  }
  cout << endl;
  return 0;
}

~~~


cpaw{vernam!!}
IBM RPAで正規表現を用いてテキストを加工する


# IBM RPAと正規表現ビルダー
IBM RPAでは、テキスト処理を行う多くのケースで正規表現を用います。そのため正規表現の動作を確認するための正規表現ビルダーと呼ばれる機能も開発ツールに組み込まれています。この記事では正規表現ビルダーの使い方と代表的な正規表現によるテキスト処理についてまとめます。

# 正規表現ビルダーの使い方
IBM RPA Studio上でツール＞正規表現ビルダーを選択することで正規表現ビルダーを起動することができます。
パターンの部分に正規表現を記述し、左下の欄に記入したテキストに対してマッチングや置換、分割をテストすることが可能です。

以下の画像は、行頭のAという文字をBという文字に置換するパターンをA123Aというテキストに対して適用した例です。
作成したパターンはサーバー上に保存して他のユーザーと共有することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117736/dc48ebd3-27c4-ce75-9962-dcc4524cf7bd.png)


# 正規表現の使用例
RPAのボットを実装する際に使用した正規表現の使用例をいくつか紹介しておきます。
- RPAのOCR機能を使用した際に付与されたパラグラフ・セパレータを削除する 
IBM RPAにはOCR機能があり、画像やPDFファイルからテキストを抽出することが可能です。実際にテキストを取得するサンプルを実装してみたところ、行末にパラグラフ・セパレータがついた状態で認識されるケースがありました。そのようなケースでは「テキストの置換」コマンドを用いて、パラグラフセパレータを空文字に置換することで対応可能です。正規表現でパラグラフ・セパレータは以下の用意表現可能です。

　　\p{Zp}



- 特定の文字列で囲まれた文字列を取得する
Windowsのコマンドを実行し、標準出力として以下の様なデータを受け取ったケースがあり、---start---と---end---に囲まれた部分のテキストを取得したいケースがありました。

```
C:\RPASampleScripts\pythonOCR>python detectRect.py
---start---
5,4,972,373
14,17,330,101
340,17,962,101
14,116,304,244
314,116,644,244
654,116,962,244
14,259,601,362
611,259,962,362
---end---
```
このようなケースでは、「正規表現からテキストを取得」コマンドを用いて、以下のような正規表現を指定することで実現可能です。

　　(?<=---start---\r\n)(.*)(?=\r\n---end---)

※オプションとして「単一行」を指定する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117736/eb9154d2-f325-ddd9-729c-4379f07e42a9.png)
# まとめ
IBM RPAではテキストの加工などの様々な操作で正規表現を利用します。正規表現ビルダーを用いることで正規表現の動作を確認することも可能です。今後も正規表現を利用した際にはそのパターンを共有していきたいと思います。

### ※Japan Business Automation User Groupのご紹介
IBMのコミュニティーである、[Japan Business Automation User Group](http://ibm.biz/JPBizAutomationUG)では、IBMのBusiness Automation製品関連の様々な技術情報、イベント情報の参照や、フォーラムを介した技術的な質問を行うことが可能です。是非ご参加ください。　http://ibm.biz/JPBizAutomationUG
OUPC2022 A「Grouping」解説

# はじめに

「Grouping」writer の Badlylucky です。

OUPC2022 にご参加いただき、ありがとうございました。OUPC2021 で A 問題枠を担当しましたが、OUPC2022 でも A 問題枠を担当しました。

# 問題

[A「Grouping」](https://onlinejudge.u-aizu.ac.jp/beta/room.html#OUPC2022/problems/A)

$A$ 以上 $B$ 以下の数を $N$ で割ったあまりでそれぞれ分類する問題です。

# 解法
## 解法1: 愚直に分類する

$A$ 以上 $B$ 以下の数の総数、$B-A+1$ はたかだか $2\times10^5 + 1$ であり、すべての数に対してどのグループに所属するかを愚直に計算しても十分間に合います[^1]。

必要になるグループは所属する数の個数が最大になるものと最小になるものだけですが、事前にどのグループが最大・最小になるか分からないため全グループについて集計します。

グループごとの集計は配列を使って実現します。

この解法の C++ での実装例を下に示します。

```c++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    int A, B, N;
    cin >> A >> B >> N;
    vector<int> group(N, 0);
    for (int i = A; i <= B; i++) {
        int r = ((i % N) + N) % N;
        group[r]++;
    }
    int groupMax = -1;
    int groupMin = B - A + 2;
    for (int i = 0; i < N; i++) {
        groupMax = max(groupMax, group[i]);
        groupMin = min(groupMin, group[i]);
    }
    cout << groupMin << " " << groupMax << endl;
    return 0;
}
```

## 解法2: 数学的に計算する

丁寧に考察すると、実は所属する数の個数が最大になるものと最小になるもののグループに所属する数の個数の差は、$0$ か $1$ にしかならないことが分かります。

$A$ を $N$ で割ったあまりを $r_A$ 、$B$ を $N$ で割ったあまりを $r_B$ とします。簡単のため、以降の議論では $A, B \geq 0$ 、 $r_A = 0$ の場合について考えます。

このとき、適当な正の整数 $q_{A}, q_{B} (q_{A} \leq q_{B})$ を使って、$A = q_{A}N, B = q_{B}N + r_B$ と表せます。$A$ 以上 $B$ 以下の整数は漏れなく対象の数の中に入っていることを考慮すると、$A$ 以上 $B$ 以下の数の中には、あまりが $0$ 以上 $N-1$ 以下のグループの数が $q_B - q_A$ 個ずつと $0$ 以上 $r_B$ 以下のグループの数が $1$ 個ずつあることが分かります。

よって $r_B = N-1$ のときに限り所属する数が最大になるグループと最小になるグループの所属する数の個数は等しくなり、それ以外のケースでは所属する数が最大になるグループと最小になるグループの所属する数の個数の差はちょうど $1$ となります。

これは一般の $A, B$ についても成立します。$A$ 以上 $B$ 以下の数の集合を $k$ ずらして $A+k$ 以上 $B+k$ 以下の数の集合に置き換えることは、この問題においてはあまりのグループを $k$ ずらすのと同義であり、全体の個数に変化はありません。したがって、$A, B \geq 0$ について、$A' = A + k = 0$ となるように $A, B$ をずらすことで $r_A = 0$ の場合と同じケースにできます。

また、$A, B$ が負の場合でも、$-10^5 \leq A \leq B \leq 10^5$ の区間を $0 \leq A \leq B \leq 2\times10^5$ のようにずらすことで $A,B \geq 0$ 、$r_A = 0$ の場合と同じように計算することができます。

これらをまとめると $r_B - r_A = N-1 \pmod{N}$ のときに限り最大値と最小値はともに $\left\lfloor \dfrac{B - A + 1}{N} \right\rfloor$ となり、それ以外のときは最小値は $\left\lfloor \dfrac{B - A + 1}{N} \right\rfloor$ 、最大値は $\left\lfloor \dfrac{B - A + 1}{N} \right\rfloor + 1$ となります。

この解法の C++ での実装を下に示します。

```c++
#include <iostream>
using namespace std;
int main() {
    int A, B, N;
    cin>> A >> B >> N;
    int minGroup = (B - A + 1) / N;
    int maxGroup = minGroup;
    if ((B - A + 1) % N > 0) {
        maxGroup++;
    }
    cout<< minGroup << " " << maxGroup << endl;
    return 0;
}
```

[^1]: この問題の元の案では、$-10^9 \leq A \leq B \leq 10^9$ でしたが、C++ の場合それでもコンパイル時の最適化が効いて間に合いました。
MFC から SVG の塗りとストローク

## 塗り
パスや基本図形の中を一色で塗りつぶす場合の処理です。
先述の記事にて AddAttribute 関数を宣言しておりますのでそちらを呼び出し側で使用すれば十分です。
ただ、すべての属性を呼び出し側で行うというのは機能単位に分けたクラスとして機能不足であると考えられるため、AddAttrFill 関数を追加します。

https://triple-underscore.github.io/SVG11/painting.html
```diff_cpp:SvgImage
class SvgImage
{
public:
+   void AddAttrFill(COLORREF crFill, BOOL bTransparent = FALSE);
+   void AddAttrFillUrl(LPCTSTR strFill);
}
```
```cpp:SvgImage.cpp
void SvgImage::AddAttrFill(COLORREF crFill, BOOL bTransparent)
{
    if (bTransparent)
    {
        AddAttribute(L"fill", L"none");
    }
    else
    {
        AddAttrColor(L"fill", crFill);
    }
}
void SvgImage::AddAttrFillUrl(LPCTSTR strFill)
{
    CString strUrl;
    strUrl.Format(L"url(#%s)", (LPCTSTR)strFill);
    AddAttribute(L"fill", strUrl);
}
```
塗りつぶしを行わないことも考慮しておきます。
```cpp
    if (bTransparent)
    {
        AddAttribute(L"fill", L"none");
    }
    else
    {
        AddAttrColor(L"fill", crFill);
    }
```
単色塗りではなく、パターン塗りやグラデーションを行うときに使用します。
```cpp
    CString strUrl;
    strUrl.Format(L"url(#%s)", (LPCTSTR)strFill)
    AddAttribute(L"fill", strUrl);
```
## ストローク
塗りと同じくストロークにも関数を用意します。
線の太さ設定や点線の設定もここで行います。

```diff_cpp:SvgImage

+#define PS_SOLID            0
+#define PS_DASH             1       /* -------  */
+#define PS_DOT              2       /* .......  */
+#define PS_DASHDOT          3       /* _._._._  */
+#define PS_DASHDOTDOT       4       /* _.._.._  */
+#define PS_NULL             5

class SvgImage
{
public:
+   void AddAttrLineType(BYTE byLineType);
+   void AddAttrStrokeWidth(int nWidth);
+   void AddAttrStroke(COLORREF crPen, int nWidth, BYTE byLineType);
}
```
```cpp:SvgImage.cpp
void SvgImage::AddAttrLineType(BYTE byLineType)
{
	switch (byLineType)
	{
	case PS_SOLID:
		break;
	case PS_DASH:
		AddAttribute(L"stroke-dasharray", L"5,1", TRUE);
		break;
	case PS_DOT:
		AddAttribute(L"stroke-dasharray", L"1,1", TRUE);
		break;
	case PS_DASHDOT:
		AddAttribute(L"stroke-dasharray", L"10,1,2,1", TRUE);
		break;
	case PS_DASHDOTDOT:
		AddAttribute(L"stroke-dasharray", L"8,1,2,1,2,1", TRUE);
		break;
	case PS_NULL:
	default:
		break;
	}
}

void SvgImage::AddAttrStrokeWidth(int nWidth)
{
	CString strWidth;
    strWidth.Format(L"%d", nWidth);
	AddAttribute(L"stroke-width", strWidth, TRUE);
}

void SvgImage::AddAttrStroke(COLORREF crPen, int nWidth, BYTE byLineType)
{
	AddAttrColor(L"stroke", crPen, TRUE);
    AddAttrStrokeWidth(nWidth);
    AddAttrLineType(byLineType);
}
```
ラインの装飾をしています。
点線などは "stroke-dasharray" 属性で繰り返し内容を明記します。

```cpp
	switch (byLineType)
	{
	case PS_SOLID:
		break;
	case PS_DASH:
		AddAttribute(L"stroke-dasharray", L"5,1", TRUE);
		break;
	case PS_DOT:
		AddAttribute(L"stroke-dasharray", L"1,1", TRUE);
		break;
	case PS_DASHDOT:
		AddAttribute(L"stroke-dasharray", L"10,1,2,1", TRUE);
		break;
	case PS_DASHDOTDOT:
		AddAttribute(L"stroke-dasharray", L"8,1,2,1,2,1", TRUE);
		break;
	case PS_NULL:
	default:
		break;
	}
```

ストロークのカラー、幅、点線の設定を一度に行います。
```cpp
	AddAttrColor(L"stroke", crPen, TRUE);
    AddAttrStrokeWidth(nWidth);
    AddAttrLineType(byLineType);
```
フェイルマネージメントで見える開発の未来

**フェイルマネージメント**
検索しても出てきません。僕が作りました。

# フェイルマネージメントとは
失敗を管理する事で強い開発組織にしていきましょうという話です。
開発組織では、沢山の失敗が存在します。
・プロマネの失敗
・要件定義の失敗
・設計の失敗
・プログラミングの失敗
・テストの失敗
・デプロイの失敗
・インフラの失敗
あなたの組織では、適切に管理出来ていますか？
この失敗は、開発組織にとって宝の山です。
状況を分析し、対策を施し、改善し、二度と同じ失敗を繰り返さない事が出来るのは、この**フェイルマネージメント**です。

# 体制の構築から
ある程度の組織になれば、失敗のログは残しているかもしれませんが、失敗を分析し適切に改善できている組織は少ないかもしれません。僕もこの改善プロセスは大嫌いです。特に当事者は、やりたくないものです。
必ず監査する別組織の立上げが必要です。この役目はCTOでは駄目です。
CTOがPJ側の立場で物事の推進をサポートする必要があります。
当事者では、優しさが生まれたり、難易度への配慮が入ったり手を抜いてしまいます。
従って、CTOとは別組織での構築が必要です。

# 失敗の記録だけでは足りない
失敗の記録だけでなく、成功の記録も必要です。
僕はゴルフが好きなのですが、ゴルフのスコアアップには、スイングの録画が重要な上達ポイントです。
上手く出来たスイングと失敗したスイングを比較して、どこにエラーが存在するのか、そのエラーを発生させないための対策はどうすれば良いのか。
成功した理由の分析も再現性には重要な手がかりとなります。

# 人に依存しない再現性を
失敗を分析し成功パターンにより対策が得られた場合は、成功するパターンを再現性あるモノに変えていく必要があります。
単純に分析しただけでは足りなくて、対策しただけでも足りません。
２度と失敗しない形、システムに落とし込んでいく必要があります。
最も良いパターンはプログラムに落とし込む事です。プログラムであれば、再現性は１００％です。
プログラム化が難しい場合もシステム化、フロー化を行い再現性を極限まで求めて行くことです。

# 失敗の対策は面倒くさい、だから１度だけ
エンジニアにとってプログラミングは楽しいです。新規に作り上げていくのに喜びを覚えます。
一方、失敗の対策は、地味だし、手間だし、やりたくないものです。なので１度だけ。２度と起きない様に。
全員で集中して対策しましょう。幸せなエンジニアライフのために。