@sayue_ltr/fleq 1.49.8 → 1.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +156 -361
  3. package/assets/icons/default.png +0 -0
  4. package/assets/icons/earthquake-cancel.png +0 -0
  5. package/assets/icons/earthquake-critical.png +0 -0
  6. package/assets/icons/earthquake-info.png +0 -0
  7. package/assets/icons/earthquake-normal.png +0 -0
  8. package/assets/icons/earthquake-warning.png +0 -0
  9. package/assets/icons/earthquake.png +0 -0
  10. package/assets/icons/eew-cancel.png +0 -0
  11. package/assets/icons/eew-critical.png +0 -0
  12. package/assets/icons/eew-info.png +0 -0
  13. package/assets/icons/eew-normal.png +0 -0
  14. package/assets/icons/eew-warning.png +0 -0
  15. package/assets/icons/eew.png +0 -0
  16. package/assets/icons/lg-observation-cancel.png +0 -0
  17. package/assets/icons/lg-observation-critical.png +0 -0
  18. package/assets/icons/lg-observation-info.png +0 -0
  19. package/assets/icons/lg-observation-normal.png +0 -0
  20. package/assets/icons/lg-observation-warning.png +0 -0
  21. package/assets/icons/lg-observation.png +0 -0
  22. package/assets/icons/nankai-trough-cancel.png +0 -0
  23. package/assets/icons/nankai-trough-critical.png +0 -0
  24. package/assets/icons/nankai-trough-info.png +0 -0
  25. package/assets/icons/nankai-trough-normal.png +0 -0
  26. package/assets/icons/nankai-trough-warning.png +0 -0
  27. package/assets/icons/nankai-trough.png +0 -0
  28. package/assets/icons/seismic-text-cancel.png +0 -0
  29. package/assets/icons/seismic-text-critical.png +0 -0
  30. package/assets/icons/seismic-text-info.png +0 -0
  31. package/assets/icons/seismic-text-normal.png +0 -0
  32. package/assets/icons/seismic-text-warning.png +0 -0
  33. package/assets/icons/seismic-text.png +0 -0
  34. package/assets/icons/tsunami-cancel.png +0 -0
  35. package/assets/icons/tsunami-critical.png +0 -0
  36. package/assets/icons/tsunami-info.png +0 -0
  37. package/assets/icons/tsunami-normal.png +0 -0
  38. package/assets/icons/tsunami-warning.png +0 -0
  39. package/assets/icons/tsunami.png +0 -0
  40. package/assets/icons/volcano-cancel.png +0 -0
  41. package/assets/icons/volcano-critical.png +0 -0
  42. package/assets/icons/volcano-info.png +0 -0
  43. package/assets/icons/volcano-normal.png +0 -0
  44. package/assets/icons/volcano-warning.png +0 -0
  45. package/assets/icons/volcano.png +0 -0
  46. package/dist/engine/notification/notifier.js +51 -19
  47. package/dist/ui/repl.js +21 -8
  48. package/dist/ui/waiting-tips.js +64 -31
  49. package/package.json +1 -1
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Notifier = exports.NOTIFY_CATEGORY_LABELS = void 0;
37
+ exports.resolveIconPath = resolveIconPath;
37
38
  const path = __importStar(require("path"));
38
39
  const fs = __importStar(require("fs"));
39
40
  const types_1 = require("../../types");
@@ -42,8 +43,38 @@ const sound_player_1 = require("./sound-player");
42
43
  const nodeNotifierLoader = __importStar(require("./node-notifier-loader"));
43
44
  const intensityUtils = __importStar(require("../../utils/intensity"));
44
45
  const log = __importStar(require("../../logger"));
45
- /** 通知アイコンのパス (assets/icons/icon.png が存在する場合に使用) */
46
- const NOTIFY_ICON_PATH = path.resolve(__dirname, "../../../assets/icons/icon.png");
46
+ /** 通知アイコンディレクトリ */
47
+ const ICONS_DIR = path.resolve(__dirname, "../../../assets/icons");
48
+ /** NotifyCategory → アイコンファイル名プレフィックス */
49
+ const CATEGORY_ICON_PREFIX = {
50
+ eew: "eew",
51
+ earthquake: "earthquake",
52
+ tsunami: "tsunami",
53
+ seismicText: "seismic-text",
54
+ nankaiTrough: "nankai-trough",
55
+ lgObservation: "lg-observation",
56
+ volcano: "volcano",
57
+ };
58
+ /**
59
+ * カテゴリとレベルからアイコンパスを解決する。
60
+ * 3段フォールバック: {prefix}-{level}.png → {prefix}.png → default.png
61
+ * いずれも見つからなければ undefined を返す。
62
+ */
63
+ function resolveIconPath(category, level) {
64
+ const prefix = CATEGORY_ICON_PREFIX[category];
65
+ const candidates = [];
66
+ if (level) {
67
+ candidates.push(path.join(ICONS_DIR, `${prefix}-${level}.png`));
68
+ }
69
+ candidates.push(path.join(ICONS_DIR, `${prefix}.png`));
70
+ candidates.push(path.join(ICONS_DIR, "default.png"));
71
+ for (const candidate of candidates) {
72
+ if (fs.existsSync(candidate)) {
73
+ return candidate;
74
+ }
75
+ }
76
+ return undefined;
77
+ }
47
78
  /** 通知アプリ名 */
48
79
  const NOTIFY_APP_NAME = "FlEq";
49
80
  /** 通知カテゴリと日本語ラベルの対応 */
@@ -134,7 +165,7 @@ class Notifier {
134
165
  return;
135
166
  }
136
167
  if (result.isCancelled) {
137
- this.send("[取消] 緊急地震速報", "緊急地震速報は取り消されました", "cancel");
168
+ this.send("[取消] 緊急地震速報", "緊急地震速報は取り消されました", "eew", "cancel");
138
169
  return;
139
170
  }
140
171
  const soundLevel = info.isWarning ? "critical" : "warning";
@@ -147,13 +178,13 @@ class Notifier {
147
178
  const body = info.earthquake
148
179
  ? `${info.earthquake.hypocenterName} / M${info.earthquake.magnitude} / 最大予測震度${maxInt}`
149
180
  : title;
150
- this.send(title, body, soundLevel);
181
+ this.send(title, body, "eew", soundLevel);
151
182
  }
152
183
  notifyEarthquake(info) {
153
184
  if (!this.settings.earthquake)
154
185
  return;
155
186
  if (info.infoType === "取消") {
156
- this.send(`[取消] ${info.title}`, "この情報は取り消されました", "cancel");
187
+ this.send(`[取消] ${info.title}`, "この情報は取り消されました", "earthquake", "cancel");
157
188
  return;
158
189
  }
159
190
  const soundLevel = this.earthquakeSoundLevel(info);
@@ -165,13 +196,13 @@ class Notifier {
165
196
  if (info.intensity) {
166
197
  parts.push(`最大震度${info.intensity.maxInt}`);
167
198
  }
168
- this.send(info.title, parts.length > 0 ? parts.join(" / ") : (info.headline ?? info.title), soundLevel);
199
+ this.send(info.title, parts.length > 0 ? parts.join(" / ") : (info.headline ?? info.title), "earthquake", soundLevel);
169
200
  }
170
201
  notifyTsunami(info) {
171
202
  if (!this.settings.tsunami)
172
203
  return;
173
204
  if (info.infoType === "取消") {
174
- this.send(`[取消] ${info.title}`, "この情報は取り消されました", "cancel");
205
+ this.send(`[取消] ${info.title}`, "この情報は取り消されました", "tsunami", "cancel");
175
206
  return;
176
207
  }
177
208
  const soundLevel = this.tsunamiSoundLevel(info);
@@ -185,33 +216,33 @@ class Notifier {
185
216
  if (info.headline) {
186
217
  parts.push(info.headline);
187
218
  }
188
- this.send(info.title, parts.length > 0 ? parts.join(" / ") : info.title, soundLevel);
219
+ this.send(info.title, parts.length > 0 ? parts.join(" / ") : info.title, "tsunami", soundLevel);
189
220
  }
190
221
  notifySeismicText(info) {
191
222
  if (!this.settings.seismicText)
192
223
  return;
193
224
  if (info.infoType === "取消") {
194
- this.send(`[取消] ${info.title}`, "この情報は取り消されました", "cancel");
225
+ this.send(`[取消] ${info.title}`, "この情報は取り消されました", "seismicText", "cancel");
195
226
  return;
196
227
  }
197
228
  const body = info.headline ?? info.bodyText.slice(0, 80);
198
- this.send(info.title, body, "info");
229
+ this.send(info.title, body, "seismicText", "info");
199
230
  }
200
231
  notifyNankaiTrough(info) {
201
232
  if (!this.settings.nankaiTrough)
202
233
  return;
203
234
  if (info.infoType === "取消") {
204
- this.send(`[取消] ${info.title}`, "この情報は取り消されました", "cancel");
235
+ this.send(`[取消] ${info.title}`, "この情報は取り消されました", "nankaiTrough", "cancel");
205
236
  return;
206
237
  }
207
238
  const body = info.headline ?? info.bodyText.slice(0, 80);
208
- this.send(info.title, body, "warning");
239
+ this.send(info.title, body, "nankaiTrough", "warning");
209
240
  }
210
241
  notifyLgObservation(info) {
211
242
  if (!this.settings.lgObservation)
212
243
  return;
213
244
  if (info.infoType === "取消") {
214
- this.send(`[取消] ${info.title}`, "この情報は取り消されました", "cancel");
245
+ this.send(`[取消] ${info.title}`, "この情報は取り消されました", "lgObservation", "cancel");
215
246
  return;
216
247
  }
217
248
  const soundLevel = this.lgObservationSoundLevel(info);
@@ -225,21 +256,21 @@ class Notifier {
225
256
  if (info.maxInt) {
226
257
  parts.push(`最大震度${info.maxInt}`);
227
258
  }
228
- this.send(info.title, parts.length > 0 ? parts.join(" / ") : info.title, soundLevel);
259
+ this.send(info.title, parts.length > 0 ? parts.join(" / ") : info.title, "lgObservation", soundLevel);
229
260
  }
230
261
  notifyVolcano(info, presentation) {
231
262
  if (!this.settings.volcano)
232
263
  return;
233
264
  if (info.infoType === "取消") {
234
- this.send(`[取消] ${info.title}`, "この情報は取り消されました", "cancel");
265
+ this.send(`[取消] ${info.title}`, "この情報は取り消されました", "volcano", "cancel");
235
266
  return;
236
267
  }
237
- this.send(info.title, presentation.summary, presentation.soundLevel);
268
+ this.send(info.title, presentation.summary, "volcano", presentation.soundLevel);
238
269
  }
239
270
  notifyVolcanoBatch(batch, presentation) {
240
271
  if (!this.settings.volcano)
241
272
  return;
242
- this.send("降灰予報(定時)", presentation.summary, presentation.soundLevel);
273
+ this.send("降灰予報(定時)", presentation.summary, "volcano", presentation.soundLevel);
243
274
  }
244
275
  // ── 内部メソッド ──
245
276
  _notifier = null;
@@ -252,18 +283,19 @@ class Notifier {
252
283
  }
253
284
  return this._notifier;
254
285
  }
255
- send(title, message, level) {
286
+ send(title, message, category, level) {
256
287
  if (this.isMuted())
257
288
  return;
258
289
  try {
259
290
  const nn = this.getNotifier();
260
291
  if (nn) {
292
+ const iconPath = resolveIconPath(category, level);
261
293
  nn.notify({
262
294
  title,
263
295
  message,
264
296
  sound: false,
265
297
  appID: NOTIFY_APP_NAME,
266
- ...(fs.existsSync(NOTIFY_ICON_PATH) ? { icon: NOTIFY_ICON_PATH } : {}),
298
+ ...(iconPath ? { icon: iconPath } : {}),
267
299
  });
268
300
  }
269
301
  }
package/dist/ui/repl.js CHANGED
@@ -140,6 +140,10 @@ class StatusLine {
140
140
  getLastMessageTime() {
141
141
  return this.lastMessageTime;
142
142
  }
143
+ /** プロンプト経過時間の基準時刻を返す (lastMessageTime ?? connectedAt) */
144
+ getElapsedBase() {
145
+ return this.lastMessageTime ?? this.connectedAt;
146
+ }
143
147
  }
144
148
  /** 現在時刻を HH:mm:ss 形式で返す */
145
149
  function formatCurrentTime() {
@@ -199,7 +203,7 @@ class ReplHandler {
199
203
  statusTimer = null;
200
204
  commandRunning = false;
201
205
  tipIntervalMs;
202
- nextTipAt = null;
206
+ lastTipMilestone = 0;
203
207
  tipIndex = 0;
204
208
  statusProviders;
205
209
  detailProviders;
@@ -1964,30 +1968,39 @@ class ReplHandler {
1964
1968
  maybeShowWaitingTip() {
1965
1969
  if (!this.rl || this.commandRunning)
1966
1970
  return;
1967
- if (this.tipIntervalMs <= 0 || this.nextTipAt == null)
1971
+ if (this.tipIntervalMs <= 0)
1968
1972
  return;
1969
1973
  const status = this.wsManager.getStatus();
1970
1974
  if (!status.connected)
1971
1975
  return;
1976
+ const base = this.statusLine.getElapsedBase();
1977
+ if (base == null)
1978
+ return;
1972
1979
  const lastMessageAt = this.statusLine.getLastMessageTime();
1973
1980
  if (lastMessageAt != null && Date.now() - lastMessageAt < 10_000)
1974
1981
  return;
1975
- if (Date.now() < this.nextTipAt)
1982
+ const elapsed = Date.now() - base;
1983
+ const currentMilestone = Math.floor(elapsed / this.tipIntervalMs);
1984
+ if (currentMilestone <= this.lastTipMilestone)
1976
1985
  return;
1977
1986
  this.clearInput();
1978
1987
  const tip = waiting_tips_1.WAITING_TIPS[this.tipIndex % waiting_tips_1.WAITING_TIPS.length];
1979
1988
  this.tipIndex++;
1980
- do {
1981
- this.nextTipAt += this.tipIntervalMs;
1982
- } while (this.nextTipAt <= Date.now());
1989
+ this.lastTipMilestone = currentMilestone;
1983
1990
  console.log(chalk_1.default.gray(` ${tip}`));
1984
1991
  }
1985
1992
  resetTipSchedule() {
1986
1993
  if (this.tipIntervalMs <= 0) {
1987
- this.nextTipAt = null;
1994
+ this.lastTipMilestone = 0;
1995
+ return;
1996
+ }
1997
+ const base = this.statusLine.getElapsedBase();
1998
+ if (base == null) {
1999
+ this.lastTipMilestone = 0;
1988
2000
  return;
1989
2001
  }
1990
- this.nextTipAt = Date.now() + this.tipIntervalMs;
2002
+ const elapsed = Date.now() - base;
2003
+ this.lastTipMilestone = Math.floor(elapsed / this.tipIntervalMs);
1991
2004
  }
1992
2005
  }
1993
2006
  exports.ReplHandler = ReplHandler;
@@ -4,48 +4,69 @@ exports.WAITING_TIPS = void 0;
4
4
  exports.WAITING_TIPS = [
5
5
  // ── コマンド基本 ──
6
6
  "Tip: help で利用可能なコマンド一覧を表示できます。",
7
- "Tip: mode compact にすると長時間監視でもログが追いやすくなります。",
8
- "Tip: status で接続状態や再接続試行回数を確認できます。",
7
+ "Tip: status で接続状態やソケットID、再接続試行回数を確認できます。",
9
8
  "Tip: history 20 で直近20件の地震履歴を確認できます。",
9
+ "Tip: history だけを入力すると、デフォルトの10件分の地震履歴が表示されます。",
10
+ "Tip: mode compact にすると長時間監視でもログが追いやすくなります。",
11
+ "Tip: mode normal にすると詳細情報も含めたフル表示に戻せます。",
10
12
  "Tip: tablewidth 80 のように表示幅を環境に合わせて調整できます。",
11
13
  "Tip: infotext full でお知らせ電文を全文表示に切り替えできます。",
12
- "Tip: mute 30m で通知を30分だけ一時停止できます。",
13
- "Tip: mute off で通知ミュートを解除できます。",
14
14
  "Tip: notify でカテゴリ別通知のON/OFF状態を確認できます。",
15
- "Tip: notify all:off で全カテゴリ通知を一括で停止できます。",
16
15
  "Tip: notify eew on のようにカテゴリ個別に通知設定を変更できます。",
16
+ "Tip: notify all:off で全カテゴリ通知を一括で停止できます。",
17
+ "Tip: mute 30m で通知を30分だけ一時停止できます。",
18
+ "Tip: mute off で通知ミュートを解除できます。",
19
+ "Tip: sound off で通知音を無効にできます。sound on で再び有効になります。",
20
+ "Tip: clock now でプロンプトの時計を現在時刻表示に切り替えできます。clock elapsed で経過時間に戻せます。",
21
+ "Tip: detail で直近の津波情報や火山情報を再表示できます。",
22
+ "Tip: detail volcano で火山関連の情報を再表示できます。津波は detail tsunami または detail だけで表示されます。",
23
+ "Tip: eewlog on でEEWイベントのログ記録を有効にできます。eewlog off で無効にします。",
24
+ "Tip: fold 10 で観測点の表示を10件に制限できます。fold off で全件表示に戻せます。",
25
+ "Tip: limit で各種出力の表示件数上限を設定できます。limit <キー> <数値> のように指定します。",
26
+ "Tip: backup on でEEW用のバックアップ接続を有効にできます。冗長性を高めたい時に便利です。",
27
+ "Tip: theme show で現在のカラーテーマを確認できます。theme reset でデフォルトに戻せます。",
28
+ "Tip: test sound warning のように、通知音のテスト再生ができます。レベルは critical / warning / normal / info / cancel です。",
29
+ "Tip: test table earthquake 1 のように、各種電文の表示テストができます。動作確認に便利です。",
30
+ "Tip: colors で震度・長周期地震動階級・フレームレベルの色分け一覧を確認できます。",
17
31
  "Tip: contract で現在契約中の区分を確認できます。",
18
32
  "Tip: socket で現在開いているソケット一覧を確認できます。",
19
- "Tip: retry は切断中に手動で再接続を試す時に使えます。",
20
33
  "Tip: config で現在の永続設定を確認できます。",
21
- "Tip: fleq config set waitTipIntervalMin 10 でヒント間隔を10分に変更できます。",
22
- "Tip: colors で震度や長周期地震動階級の色分け一覧を確認できます。",
34
+ "Tip: retry は切断中に手動で再接続を試す時に使えます。",
35
+ "Tip: tipinterval 10 でヒント間隔を10分に変更できます。tipinterval 0 で待機中Tipを止められます。",
23
36
  "Tip: clear でターミナルの画面をクリアできます。",
24
37
  "Tip: quit または exit でモニタリングを終了できます。",
25
- "Tip: history だけを入力すると、デフォルトの10件分の地震履歴が表示されます。",
26
- "Tip: mode normal にすると詳細情報も含めたフル表示に戻せます。",
27
38
  // ── コマンド応用 ──
28
39
  "Tip: help notify や help mute で、そのコマンドだけの詳しい使い方を確認できます。",
29
40
  "Tip: ? status のように ? は help の別名として使えます。",
30
- "Tip: tablewidth だけを入力すると、今の表示幅を確認できます。",
41
+ "Tip: 多くのコマンドには短縮名があります。hist, stat, conf, cont, sock, noti, cols, det, tw, snd, thm, bkup, lim, cls などが使えます。",
42
+ "Tip: tablewidth だけを入力すると、今の表示幅を確認できます。tablewidth auto で自動検出に戻せます。",
31
43
  "Tip: mode だけを入力すると、現在の表示モードを確認できます。",
32
44
  "Tip: infotext short で、お知らせ電文を省略表示に戻せます。",
33
- "Tip: tipinterval だけで現在のヒント間隔を確認でき、tipinterval 0 で待機中Tipを止められます。",
45
+ "Tip: tipinterval だけで現在のヒント間隔を確認できます。",
34
46
  "Tip: mute だけを入力すると、いまミュート中かどうかと残り時間を確認できます。",
35
- "Tip: mute 90s のように、秒単位の短いミュートも使えます。",
47
+ "Tip: mute 90s のように秒単位、mute 2h のように時間単位の指定もできます。",
36
48
  "Tip: notify eew のように on / off を省略すると、そのカテゴリをトグルできます。",
37
49
  "Tip: notify all:on は、通知設定を一気に立て直したい時に便利です。",
50
+ "Tip: notify のカテゴリには短縮名が使えます。eq, tsu, st, nt, lgob, vc でそれぞれ earthquake, tsunami, seismicText, nankaiTrough, lgObservation, volcano を指定できます。",
38
51
  "Tip: history 1 なら最新1件だけ、history 100 なら上限までまとめて確認できます。",
39
52
  "Tip: status と socket を見比べると、手元の接続状態と dmdata 側のソケット状況を切り分けやすいです。",
53
+ "Tip: eewlog fields で、EEWログに記録するフィールドの一覧とON/OFF状態を確認できます。",
54
+ "Tip: eewlog fields magnitude off のように、EEWログの個別フィールドを切り替えできます。",
55
+ "Tip: test table には earthquake, eew, tsunami, seismicText, nankaiTrough, lgObservation, volcano の7種類があり、それぞれ複数のバリエーションがあります。",
56
+ "Tip: test table のタイプにも短縮名が使えます。eq, tsu, st, nt, lgob, vc が対応しています。",
57
+ "Tip: theme validate でテーマファイルの構文チェック、theme reload で外部テーマの再読み込みができます。",
58
+ "Tip: fold は観測点が多い地震情報で画面を見やすくするのに便利です。fold 5 なら上位5件だけ表示されます。",
59
+ "Tip: limit <キー> default で個別の上限をデフォルトに戻せます。limit reset で全キーをリセットできます。",
40
60
  "Tip: fleq config set tableWidth 120 のようにすると、次回起動からの表示幅をあらかじめ設定できます。",
41
61
  "Tip: fleq config set displayMode compact にすると、起動時からcompactモードになります。",
62
+ "Tip: fleq config set promptClock clock にすると、起動時から現在時刻表示になります。",
42
63
  "Tip: fleq config keys で設定可能なキー一覧を確認できます。",
43
64
  "Tip: fleq config path で設定ファイルの保存場所を確認できます。",
44
65
  "Tip: fleq config unset <key> で個別の設定を初期値に戻せます。",
45
66
  "Tip: fleq init で初期設定ウィザードを再実行できます。APIキーや通知設定をやり直したい時に便利です。",
46
- "Tip: fleq --test で過去の電文を使ったテストモードで起動できます。動作確認に便利です。",
47
- "Tip: notify tsunami off にすると、津波情報の通知だけを停止できます。カテゴリ別に細かく制御できます。",
48
- "Tip: mute 2h のように時間単位でも指定できます。就寝前など長時間のミュートに便利です。",
67
+ "Tip: fleq --test including で過去のテスト電文を含めたモードで起動できます。--test only ならテスト電文のみです。",
68
+ "Tip: fleq --close-others を付けると、既存の WebSocket 接続を切断して新しく接続します。デフォルトでは既存接続を維持します。",
69
+ "Tip: fleq --debug でデバッグログを有効にできます。問題の切り分けに便利です。",
49
70
  // ── 防災知識 ──
50
71
  "Tip: 緊急地震速報を見聞きしたら、まず身の安全を確保するのが基本です。",
51
72
  "Tip: 緊急地震速報の報知音を覚えておくと、画面を読む前に動き出しやすくなります。",
@@ -89,35 +110,47 @@ exports.WAITING_TIPS = [
89
110
  "Tip: 避難時はブレーカーを落としてから出ると、通電火災のリスクを減らせます。",
90
111
  // ── ツールの仕組み ──
91
112
  "Tip: FlEq は既定で telegram.earthquake、eew.forecast、eew.warning、telegram.volcano を受け、電文種別ごとに地震・津波・南海トラフ・火山などへ振り分けています。",
92
- "Tip: notify eew カテゴリは、EEW予報とEEW警報の両方をまとめて扱います。",
93
- "Tip: 切断時の再接続は 1秒、2秒、4秒… と待ち時間を伸ばす指数バックオフで、少しランダム幅も入ります。",
94
- "Tip: サーバーから ping を受けるたびに pong を返して、接続の生存確認をしています。",
113
+ "Tip: 電文のルーティング優先順位は EEW 火山 → テキスト系 → 長周期 → 地震 → 津波 → 南海トラフの順です。どれにも当てはまらない電文はヘッダだけ表示されます。",
114
+ "Tip: notify の7カテゴリは eew, earthquake, tsunami, seismicText, nankaiTrough, lgObservation, volcano です。eew は予報と警報の両方をまとめて扱います。",
115
+ "Tip: 通知にはカテゴリごとに異なる Material Symbols アイコンが使われます。アイコンが使えない環境では3段階のフォールバックで代替表示されます。",
116
+ "Tip: 切断時の再接続は 1秒、2秒、4秒… と待ち時間を伸ばす指数バックオフで、少しランダム幅(ジッタ)も入ります。",
117
+ "Tip: 再接続の最大待ち時間は設定の maxReconnectDelaySec で変更できます。fleq config set maxReconnectDelaySec 30 のように指定します。",
118
+ "Tip: サーバーから約30秒ごとに ping を受けるたびに pong を返して、接続の生存確認をしています。",
95
119
  "Tip: 約90秒間 ping か data が来ないと、ハートビート切れとしてソケットを閉じて再接続に入ります。",
96
120
  "Tip: XML 以外の電文は本文を無理にパースせず、ヘッダ情報だけを表示します。",
121
+ "Tip: FlEq は電文の gzip + base64 エンコードされた本文を自動でデコードしてから XML パースします。",
97
122
  "Tip: 同じ EventID・同じ報番号の EEW は、重複報としてスキップされます。",
98
123
  "Tip: EEW は EventID ごとに追跡され、最終報や取消報が来るとイベントのログを閉じます。",
99
- "Tip: 震度の色分けはカラーユニバーサルデザインを意識した配色です。色が見づらい環境向けのラベル表示も併用しています。",
100
- "Tip: 待機中Tipは、接続中で入力が空、しかも直近10秒ほど新着がない時だけ出ます。",
101
- "Tip: 接続中のプロンプトには、最終受信からの経過時間 (または現在時刻) と次のpingまでの残り秒数が表示されます。",
102
- "Tip: tablewidth が 80 以上あると、津波情報の一部はカラム区切りの表で表示されます。",
124
+ "Tip: EEWログは EventID ごとにファイルが作られ、第1報から最終報まで時系列で記録されます。",
125
+ "Tip: EEWログには12種類のフィールドがあり、震源・規模・変化理由・予測地域など個別にON/OFFできます。",
126
+ "Tip: backup on でEEW用のバックアップ接続を有効にすると、メイン接続に問題が起きてもEEWを受信し続けられます。",
127
+ "Tip: 震度の色分けはカラーユニバーサルデザイン(CUD)を意識した配色です。色が見づらい環境向けのラベル表示も併用しています。",
103
128
  "Tip: FlEq の表示フレームは critical / warning / normal / info / cancel の5段階で色が切り替わります。",
104
129
  "Tip: 震度6弱以上の地震情報は critical フレーム、震度4以上は warning フレームで表示されます。",
105
130
  "Tip: EEW の警報は critical フレーム、予報は warning フレームで表示されます。",
106
131
  "Tip: 大津波警報は critical、津波警報は warning、注意報は normal フレームで表示されます。",
132
+ "Tip: 長周期地震動階級4は critical、階級3は warning、階級2は normal フレームで表示されます。",
133
+ "Tip: 噴火速報(VFVO56)は critical フレーム、噴火警戒レベル4-5への引上げも critical で表示されます。",
134
+ "Tip: 待機中Tipは、接続中で入力が空、しかも直近10秒ほど新着がない時だけ出ます。",
135
+ "Tip: プロンプトの ● が点滅しているのは接続が生きている証拠です。○ のままなら切断中です。",
136
+ "Tip: プロンプトには最終受信からの経過時間(または現在時刻)と、次のハートビートタイムアウトまでの残り秒数が表示されます。",
137
+ "Tip: clock コマンドでプロンプトの時計を経過時間表示と現在時刻表示に切り替えられます。",
138
+ "Tip: tablewidth が 80 以上あると、津波情報の一部はカラム区切りの表で表示されます。tablewidth auto でターミナル幅を自動検出します。",
139
+ "Tip: compact モードでは、地震情報のうち観測点ごとの詳細震度表示が省略され、1行サマリーになります。",
140
+ "Tip: fold コマンドで観測点の表示件数を制限すると、大きな地震でも画面を見やすく保てます。",
107
141
  "Tip: VXSE53 は震源・震度に関する情報で、最も詳細な観測点別震度が含まれる電文です。",
108
142
  "Tip: VXSE51 は震度速報で、地震発生直後に大まかな震度分布をいち早く伝える電文です。",
109
143
  "Tip: VTSE41/VTSE51/VTSE52 はそれぞれ異なる津波情報の電文種別です。",
110
- "Tip: EEWログは EventID ごとにファイルが作られ、第1報から最終報まで時系列で記録されます。",
111
- "Tip: dmdata.jp の REST API で地震履歴を取得しているため、history コマンドはローカル保存ではなくサーバーからリアルタイムに取得します。",
112
- "Tip: --keep-existing オプションを使うと、既存の WebSocket 接続を切断せずに新しい接続を追加できます。",
113
144
  "Tip: 南海トラフ関連情報は VYSE50/51/52/60 の4種類の電文で構成されています。",
114
145
  "Tip: 長周期地震動の観測情報は VXSE62 電文で、高層ビルへの影響を示す専用の電文です。",
115
146
  "Tip: 火山電文は10種類(VFVO50/51/52/53/54/55/56/60, VFSVii, VZVO40)で、噴火警報・噴火速報・降灰予報などを扱います。",
116
- "Tip: 噴火警戒レベルは1(活火山であることに留意)〜5(避難)の5段階です。レベル引上げは critical フレームで表示されます。",
117
- "Tip: VFVO56 は噴火速報で、噴火が発生した直後にいち早く伝える電文です。critical フレームで表示されます。",
118
- "Tip: compact モードでは、地震情報のうち観測点ごとの詳細震度表示が省略されます。",
119
- "Tip: FlEq は電文の gzip + base64 エンコードされた本文を自動でデコードしてから XML パースします。",
120
- "Tip: プロンプトの が点滅しているのは接続が生きている証拠です。○ のままなら切断中です。",
147
+ "Tip: 噴火警戒レベルは1(活火山であることに留意)〜5(避難)の5段階です。",
148
+ "Tip: VFVO53(噴火に関する火山観測報)は単発処理ではなく、一定時間バッチ集約されてから表示されます。",
149
+ "Tip: dmdata.jp の REST API で地震履歴を取得しているため、history コマンドはローカル保存ではなくサーバーからリアルタイムに取得します。",
150
+ "Tip: デフォルトでは既存の WebSocket 接続を維持したまま新しい接続を追加します。--close-others で既存接続を切断してから接続します。",
151
+ "Tip: 設定は CLIオプション 環境変数 → .envファイル → configファイル → デフォルト値 の優先順位で解決されます。",
152
+ "Tip: theme コマンドで外部テーマファイルを読み込むと、フレームや震度の色をカスタマイズできます。",
153
+ "Tip: test table コマンドで各種電文のサンプル表示を確認できます。表示幅やモードの変更後の見た目チェックに便利です。",
121
154
  // ── 地震・津波の雑学 ──
122
155
  "Tip: 震度は「ある場所の揺れの強さ」、マグニチュードは「地震そのものの規模」です。",
123
156
  "Tip: 日本の震度階級は 0、1、2、3、4、5弱、5強、6弱、6強、7 の10段階です。",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sayue_ltr/fleq",
3
- "version": "1.49.8",
3
+ "version": "1.50.1",
4
4
  "description": "Project DM-D.S.S (dmdata.jp) リアルタイム地震・津波・EEW情報モニター CLI",
5
5
  "main": "dist/index.js",
6
6
  "bin": {