@sayue_ltr/fleq 1.50.1 → 2.0.0
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.
- package/CHANGELOG.md +174 -0
- package/README.md +42 -6
- package/dist/config.js +37 -4
- package/dist/dmdata/rest-client.js +58 -3
- package/dist/dmdata/telegram-parser.js +115 -64
- package/dist/dmdata/ws-client.js +49 -18
- package/dist/engine/cli/cli-run.js +88 -3
- package/dist/engine/cli/cli.js +12 -0
- package/dist/engine/eew/eew-tracker.js +41 -15
- package/dist/engine/filter/compile-filter.js +21 -0
- package/dist/engine/filter/compiler.js +188 -0
- package/dist/engine/filter/errors.js +41 -0
- package/dist/engine/filter/field-registry.js +78 -0
- package/dist/engine/filter/index.js +15 -0
- package/dist/engine/filter/parser.js +137 -0
- package/dist/engine/filter/rank-maps.js +34 -0
- package/dist/engine/filter/tokenizer.js +121 -0
- package/dist/engine/filter/type-checker.js +104 -0
- package/dist/engine/filter/types.js +2 -0
- package/dist/engine/filter-template/pipeline-controller.js +73 -0
- package/dist/engine/filter-template/pipeline.js +16 -0
- package/dist/engine/messages/display-callbacks.js +7 -0
- package/dist/engine/messages/message-router.js +114 -182
- package/dist/engine/messages/summary-tracker.js +106 -0
- package/dist/engine/messages/telegram-stats.js +103 -0
- package/dist/engine/messages/volcano-route-handler.js +122 -0
- package/dist/engine/monitor/monitor.js +52 -4
- package/dist/engine/monitor/shutdown.js +1 -0
- package/dist/engine/notification/notifier.js +21 -4
- package/dist/engine/notification/sound-player.js +398 -36
- package/dist/engine/presentation/diff-store.js +158 -0
- package/dist/engine/presentation/diff-types.js +2 -0
- package/dist/engine/presentation/events/from-earthquake.js +53 -0
- package/dist/engine/presentation/events/from-eew.js +72 -0
- package/dist/engine/presentation/events/from-lg-observation.js +58 -0
- package/dist/engine/presentation/events/from-nankai-trough.js +39 -0
- package/dist/engine/presentation/events/from-raw.js +35 -0
- package/dist/engine/presentation/events/from-seismic-text.js +37 -0
- package/dist/engine/presentation/events/from-tsunami.js +51 -0
- package/dist/engine/presentation/events/from-volcano.js +88 -0
- package/dist/engine/presentation/events/to-presentation-event.js +32 -0
- package/dist/engine/presentation/level-helpers.js +118 -0
- package/dist/engine/presentation/processors/process-earthquake.js +36 -0
- package/dist/engine/presentation/processors/process-eew.js +105 -0
- package/dist/engine/presentation/processors/process-lg-observation.js +30 -0
- package/dist/engine/presentation/processors/process-message.js +53 -0
- package/dist/engine/presentation/processors/process-nankai-trough.js +30 -0
- package/dist/engine/presentation/processors/process-raw.js +22 -0
- package/dist/engine/presentation/processors/process-seismic-text.js +30 -0
- package/dist/engine/presentation/processors/process-tsunami.js +42 -0
- package/dist/engine/presentation/processors/process-volcano.js +41 -0
- package/dist/engine/presentation/types.js +2 -0
- package/dist/engine/startup/config-resolver.js +2 -0
- package/dist/engine/template/compile-template.js +18 -0
- package/dist/engine/template/compiler.js +105 -0
- package/dist/engine/template/field-accessor.js +31 -0
- package/dist/engine/template/filters.js +100 -0
- package/dist/engine/template/index.js +5 -0
- package/dist/engine/template/parser.js +185 -0
- package/dist/engine/template/tokenizer.js +96 -0
- package/dist/engine/template/types.js +2 -0
- package/dist/types.js +3 -2
- package/dist/ui/display-adapter.js +60 -0
- package/dist/ui/earthquake-formatter.js +22 -5
- package/dist/ui/eew-formatter.js +25 -10
- package/dist/ui/formatter.js +116 -32
- package/dist/ui/minimap/grid-layout.js +91 -0
- package/dist/ui/minimap/index.js +16 -0
- package/dist/ui/minimap/minimap-renderer.js +277 -0
- package/dist/ui/minimap/pref-mapping.js +82 -0
- package/dist/ui/minimap/types.js +2 -0
- package/dist/ui/night-overlay.js +56 -0
- package/dist/ui/repl-handlers/command-definitions.js +327 -0
- package/dist/ui/repl-handlers/index.js +11 -0
- package/dist/ui/repl-handlers/info-handlers.js +633 -0
- package/dist/ui/repl-handlers/operation-handlers.js +233 -0
- package/dist/ui/repl-handlers/settings-handlers.js +927 -0
- package/dist/ui/repl-handlers/types.js +10 -0
- package/dist/ui/repl.js +81 -1752
- package/dist/ui/statistics-formatter.js +258 -0
- package/dist/ui/status-line.js +80 -0
- package/dist/ui/summary/index.js +5 -0
- package/dist/ui/summary/summary-line.js +18 -0
- package/dist/ui/summary/summary-model.js +31 -0
- package/dist/ui/summary/token-builders.js +317 -0
- package/dist/ui/summary/types.js +2 -0
- package/dist/ui/summary/width-fit.js +41 -0
- package/dist/ui/summary-interval-formatter.js +72 -0
- package/dist/ui/test-samples.js +6 -0
- package/dist/ui/theme.js +43 -5
- package/dist/ui/tip-shuffler.js +81 -0
- package/dist/ui/volcano-formatter.js +15 -13
- package/dist/ui/waiting-tips-eew.js +63 -0
- package/dist/ui/waiting-tips-info-systems.js +81 -0
- package/dist/ui/waiting-tips-seismology.js +97 -0
- package/dist/ui/waiting-tips-tsunami.js +72 -0
- package/dist/ui/waiting-tips-weather.js +189 -0
- package/dist/ui/waiting-tips.js +420 -249
- package/package.json +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PresentationDiffStore = void 0;
|
|
4
|
+
/** TTL のデフォルト値 (30分) */
|
|
5
|
+
const DEFAULT_TTL_MS = 30 * 60 * 1000;
|
|
6
|
+
/** プルーニング実行間隔 (apply 呼び出し回数) */
|
|
7
|
+
const PRUNE_INTERVAL = 50;
|
|
8
|
+
/**
|
|
9
|
+
* PresentationEvent の差分を検出・保持するストア。
|
|
10
|
+
*
|
|
11
|
+
* apply() は PresentationEvent を受け取り、同一 diffKey を持つ直前のイベントとの
|
|
12
|
+
* 差分を検出して diff プロパティを付与して返す。
|
|
13
|
+
*
|
|
14
|
+
* TTL ベースの自動クリーンアップにより、長時間稼働時のメモリ蓄積を防止する。
|
|
15
|
+
*/
|
|
16
|
+
class PresentationDiffStore {
|
|
17
|
+
previous = new Map();
|
|
18
|
+
ttlMs;
|
|
19
|
+
applyCount = 0;
|
|
20
|
+
constructor(ttlMs) {
|
|
21
|
+
this.ttlMs = ttlMs ?? DEFAULT_TTL_MS;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* イベントを受け取り、差分を検出する。
|
|
25
|
+
* - 初回 (同一 diffKey で初めて) → diff なし
|
|
26
|
+
* - 2回目以降 → diff あり (changed フラグ + summary + fields)
|
|
27
|
+
* - diffKey が解決できないドメイン → diff なし (対象外)
|
|
28
|
+
*/
|
|
29
|
+
apply(event) {
|
|
30
|
+
this.applyCount++;
|
|
31
|
+
if (this.applyCount % PRUNE_INTERVAL === 0) {
|
|
32
|
+
this.prune();
|
|
33
|
+
}
|
|
34
|
+
const diffKey = this.resolveDiffKey(event);
|
|
35
|
+
if (diffKey == null)
|
|
36
|
+
return event;
|
|
37
|
+
const entry = this.previous.get(diffKey);
|
|
38
|
+
const diff = entry ? this.computeDiff(entry.event, event) : undefined;
|
|
39
|
+
this.previous.set(diffKey, { event, updatedAt: Date.now() });
|
|
40
|
+
return diff ? { ...event, diff } : event;
|
|
41
|
+
}
|
|
42
|
+
/** 指定した diffKey のエントリを削除する */
|
|
43
|
+
remove(diffKey) {
|
|
44
|
+
this.previous.delete(diffKey);
|
|
45
|
+
}
|
|
46
|
+
/** テスト用: ストアをクリアする */
|
|
47
|
+
clear() {
|
|
48
|
+
this.previous.clear();
|
|
49
|
+
}
|
|
50
|
+
/** TTL を超過した古いエントリを削除する */
|
|
51
|
+
prune() {
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
for (const [key, entry] of this.previous) {
|
|
54
|
+
if (now - entry.updatedAt > this.ttlMs) {
|
|
55
|
+
this.previous.delete(key);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// ── diffKey 解決 ──
|
|
60
|
+
resolveDiffKey(event) {
|
|
61
|
+
switch (event.domain) {
|
|
62
|
+
case "eew":
|
|
63
|
+
return event.eventId ? `eew:${event.eventId}` : null;
|
|
64
|
+
case "tsunami":
|
|
65
|
+
return event.type === "VTSE41" ? "tsunami:vtse41" : null;
|
|
66
|
+
case "volcano":
|
|
67
|
+
return event.type === "VFVO50" && event.volcanoCode
|
|
68
|
+
? `volcano:${event.volcanoCode}`
|
|
69
|
+
: null;
|
|
70
|
+
default:
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// ── diff 算出 ──
|
|
75
|
+
computeDiff(prev, curr) {
|
|
76
|
+
const fields = [];
|
|
77
|
+
const summary = [];
|
|
78
|
+
switch (curr.domain) {
|
|
79
|
+
case "eew":
|
|
80
|
+
this.compareEew(prev, curr, fields, summary);
|
|
81
|
+
break;
|
|
82
|
+
case "tsunami":
|
|
83
|
+
this.compareTsunami(prev, curr, fields, summary);
|
|
84
|
+
break;
|
|
85
|
+
case "volcano":
|
|
86
|
+
this.compareVolcano(prev, curr, fields, summary);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
changed: fields.length > 0,
|
|
91
|
+
summary,
|
|
92
|
+
fields,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
compareEew(prev, curr, fields, summary) {
|
|
96
|
+
// magnitude
|
|
97
|
+
if (prev.magnitude !== curr.magnitude) {
|
|
98
|
+
fields.push({
|
|
99
|
+
key: "magnitude",
|
|
100
|
+
previous: prev.magnitude ?? null,
|
|
101
|
+
current: curr.magnitude ?? null,
|
|
102
|
+
significance: "major",
|
|
103
|
+
});
|
|
104
|
+
if (prev.magnitude != null && curr.magnitude != null) {
|
|
105
|
+
summary.push(`M${prev.magnitude}→${curr.magnitude}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// maxInt (forecastMaxInt for EEW)
|
|
109
|
+
const prevInt = prev.forecastMaxInt ?? prev.maxInt;
|
|
110
|
+
const currInt = curr.forecastMaxInt ?? curr.maxInt;
|
|
111
|
+
if (prevInt !== currInt) {
|
|
112
|
+
fields.push({
|
|
113
|
+
key: "maxInt",
|
|
114
|
+
previous: prevInt ?? null,
|
|
115
|
+
current: currInt ?? null,
|
|
116
|
+
significance: "major",
|
|
117
|
+
});
|
|
118
|
+
if (prevInt != null && currInt != null) {
|
|
119
|
+
summary.push(`${prevInt}→${currInt}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// hypocenterName
|
|
123
|
+
if (prev.hypocenterName !== curr.hypocenterName) {
|
|
124
|
+
fields.push({
|
|
125
|
+
key: "hypocenterName",
|
|
126
|
+
previous: prev.hypocenterName ?? null,
|
|
127
|
+
current: curr.hypocenterName ?? null,
|
|
128
|
+
significance: "minor",
|
|
129
|
+
});
|
|
130
|
+
summary.push("震源変更");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
compareTsunami(prev, curr, fields, summary) {
|
|
134
|
+
if (prev.areaCount !== curr.areaCount) {
|
|
135
|
+
fields.push({
|
|
136
|
+
key: "areaCount",
|
|
137
|
+
previous: prev.areaCount,
|
|
138
|
+
current: curr.areaCount,
|
|
139
|
+
significance: "major",
|
|
140
|
+
});
|
|
141
|
+
summary.push(`${prev.areaCount}区域→${curr.areaCount}区域`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
compareVolcano(prev, curr, fields, summary) {
|
|
145
|
+
if (prev.alertLevel !== curr.alertLevel) {
|
|
146
|
+
fields.push({
|
|
147
|
+
key: "alertLevel",
|
|
148
|
+
previous: prev.alertLevel ?? null,
|
|
149
|
+
current: curr.alertLevel ?? null,
|
|
150
|
+
significance: "major",
|
|
151
|
+
});
|
|
152
|
+
if (prev.alertLevel != null && curr.alertLevel != null) {
|
|
153
|
+
summary.push(`Lv${prev.alertLevel}→${curr.alertLevel}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.PresentationDiffStore = PresentationDiffStore;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromEarthquakeOutcome = fromEarthquakeOutcome;
|
|
4
|
+
const intensity_1 = require("../../../utils/intensity");
|
|
5
|
+
/** EarthquakeOutcome → PresentationEvent */
|
|
6
|
+
function fromEarthquakeOutcome(outcome) {
|
|
7
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
8
|
+
const info = outcome.parsed;
|
|
9
|
+
const maxInt = info.intensity?.maxInt ?? null;
|
|
10
|
+
const maxIntRank = maxInt != null ? (0, intensity_1.intensityToRank)(maxInt) : null;
|
|
11
|
+
const areas = info.intensity?.areas ?? [];
|
|
12
|
+
const areaNames = areas.map((a) => a.name);
|
|
13
|
+
const areaItems = areas.map((a) => ({
|
|
14
|
+
name: a.name,
|
|
15
|
+
maxInt: a.intensity,
|
|
16
|
+
}));
|
|
17
|
+
return {
|
|
18
|
+
id: outcome.msg.id,
|
|
19
|
+
classification: outcome.msg.classification,
|
|
20
|
+
domain: outcome.domain,
|
|
21
|
+
type: outcome.headType,
|
|
22
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
23
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
24
|
+
headline: xmlReport?.head.headline ?? null,
|
|
25
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
26
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
27
|
+
isTest: outcome.msg.head.test,
|
|
28
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
29
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
30
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
31
|
+
isCancellation: info.infoType === "取消",
|
|
32
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
33
|
+
serial: xmlReport?.head.serial ?? null,
|
|
34
|
+
originTime: info.earthquake?.originTime ?? null,
|
|
35
|
+
hypocenterName: info.earthquake?.hypocenterName ?? null,
|
|
36
|
+
latitude: info.earthquake?.latitude ?? null,
|
|
37
|
+
longitude: info.earthquake?.longitude ?? null,
|
|
38
|
+
depth: info.earthquake?.depth ?? null,
|
|
39
|
+
magnitude: info.earthquake?.magnitude ?? null,
|
|
40
|
+
maxInt,
|
|
41
|
+
maxIntRank,
|
|
42
|
+
areaNames,
|
|
43
|
+
forecastAreaNames: [],
|
|
44
|
+
municipalityNames: [],
|
|
45
|
+
observationNames: [],
|
|
46
|
+
areaCount: areaNames.length,
|
|
47
|
+
forecastAreaCount: 0,
|
|
48
|
+
municipalityCount: 0,
|
|
49
|
+
observationCount: 0,
|
|
50
|
+
areaItems,
|
|
51
|
+
raw: outcome.parsed,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromEewOutcome = fromEewOutcome;
|
|
4
|
+
const intensity_1 = require("../../../utils/intensity");
|
|
5
|
+
/** EewOutcome → PresentationEvent */
|
|
6
|
+
function fromEewOutcome(outcome) {
|
|
7
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
8
|
+
const info = outcome.parsed;
|
|
9
|
+
// 予測地域から最大予測震度を算出
|
|
10
|
+
const forecastAreas = info.forecastIntensity?.areas ?? [];
|
|
11
|
+
let forecastMaxInt = null;
|
|
12
|
+
let forecastMaxIntRank = null;
|
|
13
|
+
for (const area of forecastAreas) {
|
|
14
|
+
const rank = (0, intensity_1.intensityToRank)(area.intensity);
|
|
15
|
+
if (forecastMaxIntRank == null || rank > forecastMaxIntRank) {
|
|
16
|
+
forecastMaxIntRank = rank;
|
|
17
|
+
forecastMaxInt = area.intensity;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const areaNames = forecastAreas.map((a) => a.name);
|
|
21
|
+
const areaItems = forecastAreas.map((a) => ({
|
|
22
|
+
name: a.name,
|
|
23
|
+
kind: "forecast",
|
|
24
|
+
maxInt: a.intensity,
|
|
25
|
+
}));
|
|
26
|
+
return {
|
|
27
|
+
id: outcome.msg.id,
|
|
28
|
+
classification: outcome.msg.classification,
|
|
29
|
+
domain: outcome.domain,
|
|
30
|
+
type: outcome.headType,
|
|
31
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
32
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
33
|
+
headline: xmlReport?.head.headline ?? null,
|
|
34
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
35
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
36
|
+
isTest: outcome.msg.head.test,
|
|
37
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
38
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
39
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
40
|
+
isCancellation: info.infoType === "取消",
|
|
41
|
+
eventId: info.eventId ?? xmlReport?.head.eventId ?? null,
|
|
42
|
+
serial: info.serial ?? xmlReport?.head.serial ?? null,
|
|
43
|
+
isWarning: info.isWarning,
|
|
44
|
+
isFinal: info.nextAdvisory != null,
|
|
45
|
+
isAssumedHypocenter: info.isAssumedHypocenter,
|
|
46
|
+
hypocenterName: info.earthquake?.hypocenterName ?? null,
|
|
47
|
+
latitude: info.earthquake?.latitude ?? null,
|
|
48
|
+
longitude: info.earthquake?.longitude ?? null,
|
|
49
|
+
depth: info.earthquake?.depth ?? null,
|
|
50
|
+
magnitude: info.earthquake?.magnitude ?? null,
|
|
51
|
+
forecastMaxInt: forecastMaxInt,
|
|
52
|
+
forecastMaxIntRank: forecastMaxIntRank,
|
|
53
|
+
nextAdvisory: info.nextAdvisory ?? null,
|
|
54
|
+
areaNames,
|
|
55
|
+
forecastAreaNames: areaNames,
|
|
56
|
+
municipalityNames: [],
|
|
57
|
+
observationNames: [],
|
|
58
|
+
areaCount: areaNames.length,
|
|
59
|
+
forecastAreaCount: areaNames.length,
|
|
60
|
+
municipalityCount: 0,
|
|
61
|
+
observationCount: 0,
|
|
62
|
+
areaItems,
|
|
63
|
+
stateSnapshot: {
|
|
64
|
+
kind: "eew",
|
|
65
|
+
activeCount: outcome.state.activeCount,
|
|
66
|
+
colorIndex: outcome.state.colorIndex,
|
|
67
|
+
isCancelled: outcome.state.isCancelled,
|
|
68
|
+
diff: outcome.state.diff,
|
|
69
|
+
},
|
|
70
|
+
raw: outcome.parsed,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromLgObservationOutcome = fromLgObservationOutcome;
|
|
4
|
+
const intensity_1 = require("../../../utils/intensity");
|
|
5
|
+
/** LgObservationOutcome → PresentationEvent */
|
|
6
|
+
function fromLgObservationOutcome(outcome) {
|
|
7
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
8
|
+
const info = outcome.parsed;
|
|
9
|
+
const maxLgInt = info.maxLgInt ?? null;
|
|
10
|
+
const maxLgIntRank = maxLgInt != null ? Number(maxLgInt) || null : null;
|
|
11
|
+
const observations = info.areas ?? [];
|
|
12
|
+
const observationNames = observations.map((o) => o.name);
|
|
13
|
+
const areaItems = observations.map((o) => ({
|
|
14
|
+
name: o.name,
|
|
15
|
+
maxInt: o.maxInt,
|
|
16
|
+
maxLgInt: o.maxLgInt,
|
|
17
|
+
}));
|
|
18
|
+
const maxInt = info.maxInt ?? null;
|
|
19
|
+
const maxIntRank = maxInt != null ? (0, intensity_1.intensityToRank)(maxInt) : null;
|
|
20
|
+
return {
|
|
21
|
+
id: outcome.msg.id,
|
|
22
|
+
classification: outcome.msg.classification,
|
|
23
|
+
domain: outcome.domain,
|
|
24
|
+
type: outcome.headType,
|
|
25
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
26
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
27
|
+
headline: xmlReport?.head.headline ?? null,
|
|
28
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
29
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
30
|
+
isTest: outcome.msg.head.test,
|
|
31
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
32
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
33
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
34
|
+
isCancellation: info.infoType === "取消",
|
|
35
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
36
|
+
serial: xmlReport?.head.serial ?? null,
|
|
37
|
+
originTime: info.earthquake?.originTime ?? null,
|
|
38
|
+
hypocenterName: info.earthquake?.hypocenterName ?? null,
|
|
39
|
+
latitude: info.earthquake?.latitude ?? null,
|
|
40
|
+
longitude: info.earthquake?.longitude ?? null,
|
|
41
|
+
depth: info.earthquake?.depth ?? null,
|
|
42
|
+
magnitude: info.earthquake?.magnitude ?? null,
|
|
43
|
+
maxInt,
|
|
44
|
+
maxIntRank,
|
|
45
|
+
maxLgInt,
|
|
46
|
+
maxLgIntRank,
|
|
47
|
+
areaNames: [],
|
|
48
|
+
forecastAreaNames: [],
|
|
49
|
+
municipalityNames: [],
|
|
50
|
+
observationNames,
|
|
51
|
+
areaCount: 0,
|
|
52
|
+
forecastAreaCount: 0,
|
|
53
|
+
municipalityCount: 0,
|
|
54
|
+
observationCount: observationNames.length,
|
|
55
|
+
areaItems,
|
|
56
|
+
raw: outcome.parsed,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromNankaiTroughOutcome = fromNankaiTroughOutcome;
|
|
4
|
+
/** NankaiTroughOutcome → PresentationEvent */
|
|
5
|
+
function fromNankaiTroughOutcome(outcome) {
|
|
6
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
7
|
+
const info = outcome.parsed;
|
|
8
|
+
return {
|
|
9
|
+
id: outcome.msg.id,
|
|
10
|
+
classification: outcome.msg.classification,
|
|
11
|
+
domain: outcome.domain,
|
|
12
|
+
type: outcome.headType,
|
|
13
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
14
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
15
|
+
headline: xmlReport?.head.headline ?? null,
|
|
16
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
17
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
18
|
+
isTest: outcome.msg.head.test,
|
|
19
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
20
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
21
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
22
|
+
isCancellation: info.infoType === "取消",
|
|
23
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
24
|
+
serial: xmlReport?.head.serial ?? null,
|
|
25
|
+
infoSerialCode: info.infoSerial?.code ?? null,
|
|
26
|
+
bodyText: info.bodyText,
|
|
27
|
+
nextAdvisory: info.nextAdvisory ?? null,
|
|
28
|
+
areaNames: [],
|
|
29
|
+
forecastAreaNames: [],
|
|
30
|
+
municipalityNames: [],
|
|
31
|
+
observationNames: [],
|
|
32
|
+
areaCount: 0,
|
|
33
|
+
forecastAreaCount: 0,
|
|
34
|
+
municipalityCount: 0,
|
|
35
|
+
observationCount: 0,
|
|
36
|
+
areaItems: [],
|
|
37
|
+
raw: outcome.parsed,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromRawOutcome = fromRawOutcome;
|
|
4
|
+
/** RawOutcome → PresentationEvent (フォールバック用の最小変換) */
|
|
5
|
+
function fromRawOutcome(outcome) {
|
|
6
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
7
|
+
return {
|
|
8
|
+
id: outcome.msg.id,
|
|
9
|
+
classification: outcome.msg.classification,
|
|
10
|
+
domain: outcome.domain,
|
|
11
|
+
type: outcome.headType,
|
|
12
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
13
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
14
|
+
headline: xmlReport?.head.headline ?? null,
|
|
15
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
16
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
17
|
+
isTest: outcome.msg.head.test,
|
|
18
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
19
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
20
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
21
|
+
isCancellation: false,
|
|
22
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
23
|
+
serial: xmlReport?.head.serial ?? null,
|
|
24
|
+
areaNames: [],
|
|
25
|
+
forecastAreaNames: [],
|
|
26
|
+
municipalityNames: [],
|
|
27
|
+
observationNames: [],
|
|
28
|
+
areaCount: 0,
|
|
29
|
+
forecastAreaCount: 0,
|
|
30
|
+
municipalityCount: 0,
|
|
31
|
+
observationCount: 0,
|
|
32
|
+
areaItems: [],
|
|
33
|
+
raw: null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromSeismicTextOutcome = fromSeismicTextOutcome;
|
|
4
|
+
/** SeismicTextOutcome → PresentationEvent */
|
|
5
|
+
function fromSeismicTextOutcome(outcome) {
|
|
6
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
7
|
+
const info = outcome.parsed;
|
|
8
|
+
return {
|
|
9
|
+
id: outcome.msg.id,
|
|
10
|
+
classification: outcome.msg.classification,
|
|
11
|
+
domain: outcome.domain,
|
|
12
|
+
type: outcome.headType,
|
|
13
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
14
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
15
|
+
headline: xmlReport?.head.headline ?? null,
|
|
16
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
17
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
18
|
+
isTest: outcome.msg.head.test,
|
|
19
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
20
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
21
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
22
|
+
isCancellation: info.infoType === "取消",
|
|
23
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
24
|
+
serial: xmlReport?.head.serial ?? null,
|
|
25
|
+
bodyText: info.bodyText,
|
|
26
|
+
areaNames: [],
|
|
27
|
+
forecastAreaNames: [],
|
|
28
|
+
municipalityNames: [],
|
|
29
|
+
observationNames: [],
|
|
30
|
+
areaCount: 0,
|
|
31
|
+
forecastAreaCount: 0,
|
|
32
|
+
municipalityCount: 0,
|
|
33
|
+
observationCount: 0,
|
|
34
|
+
areaItems: [],
|
|
35
|
+
raw: outcome.parsed,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromTsunamiOutcome = fromTsunamiOutcome;
|
|
4
|
+
/** TsunamiOutcome → PresentationEvent */
|
|
5
|
+
function fromTsunamiOutcome(outcome) {
|
|
6
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
7
|
+
const info = outcome.parsed;
|
|
8
|
+
const forecastItems = info.forecast ?? [];
|
|
9
|
+
const forecastAreaNames = forecastItems.map((f) => f.areaName);
|
|
10
|
+
const tsunamiKinds = forecastItems.map((f) => f.kind);
|
|
11
|
+
const areaItems = forecastItems.map((f) => ({
|
|
12
|
+
name: f.areaName,
|
|
13
|
+
kind: f.kind,
|
|
14
|
+
}));
|
|
15
|
+
return {
|
|
16
|
+
id: outcome.msg.id,
|
|
17
|
+
classification: outcome.msg.classification,
|
|
18
|
+
domain: outcome.domain,
|
|
19
|
+
type: outcome.headType,
|
|
20
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
21
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
22
|
+
headline: xmlReport?.head.headline ?? null,
|
|
23
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
24
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
25
|
+
isTest: outcome.msg.head.test,
|
|
26
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
27
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
28
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
29
|
+
isCancellation: info.infoType === "取消",
|
|
30
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
31
|
+
serial: xmlReport?.head.serial ?? null,
|
|
32
|
+
warningComment: info.warningComment || null,
|
|
33
|
+
tsunamiKinds,
|
|
34
|
+
areaNames: [],
|
|
35
|
+
forecastAreaNames,
|
|
36
|
+
municipalityNames: [],
|
|
37
|
+
observationNames: [],
|
|
38
|
+
areaCount: 0,
|
|
39
|
+
forecastAreaCount: forecastAreaNames.length,
|
|
40
|
+
municipalityCount: 0,
|
|
41
|
+
observationCount: 0,
|
|
42
|
+
areaItems,
|
|
43
|
+
stateSnapshot: {
|
|
44
|
+
kind: "tsunami",
|
|
45
|
+
levelBefore: outcome.state.levelBefore,
|
|
46
|
+
levelAfter: outcome.state.levelAfter,
|
|
47
|
+
changed: outcome.state.changed,
|
|
48
|
+
},
|
|
49
|
+
raw: outcome.parsed,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromVolcanoOutcome = fromVolcanoOutcome;
|
|
4
|
+
/** VolcanoOutcome | VolcanoBatchOutcome → PresentationEvent */
|
|
5
|
+
function fromVolcanoOutcome(outcome) {
|
|
6
|
+
if ("isBatch" in outcome && outcome.isBatch) {
|
|
7
|
+
return fromVolcanoBatchOutcome(outcome);
|
|
8
|
+
}
|
|
9
|
+
return fromSingleVolcanoOutcome(outcome);
|
|
10
|
+
}
|
|
11
|
+
function fromSingleVolcanoOutcome(outcome) {
|
|
12
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
13
|
+
const info = outcome.parsed;
|
|
14
|
+
const alertLevel = info.kind === "alert" ? info.alertLevel : null;
|
|
15
|
+
return {
|
|
16
|
+
id: outcome.msg.id,
|
|
17
|
+
classification: outcome.msg.classification,
|
|
18
|
+
domain: outcome.domain,
|
|
19
|
+
type: outcome.headType,
|
|
20
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
21
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
22
|
+
headline: xmlReport?.head.headline ?? null,
|
|
23
|
+
reportDateTime: xmlReport?.head.reportDateTime ?? outcome.msg.head.time,
|
|
24
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
25
|
+
isTest: outcome.msg.head.test,
|
|
26
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
27
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
28
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
29
|
+
isCancellation: info.infoType === "取消",
|
|
30
|
+
isRenotification: outcome.state.isRenotification,
|
|
31
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
32
|
+
serial: xmlReport?.head.serial ?? null,
|
|
33
|
+
volcanoCode: info.volcanoCode,
|
|
34
|
+
volcanoName: info.volcanoName,
|
|
35
|
+
alertLevel,
|
|
36
|
+
areaNames: [],
|
|
37
|
+
forecastAreaNames: [],
|
|
38
|
+
municipalityNames: [],
|
|
39
|
+
observationNames: [],
|
|
40
|
+
areaCount: 0,
|
|
41
|
+
forecastAreaCount: 0,
|
|
42
|
+
municipalityCount: 0,
|
|
43
|
+
observationCount: 0,
|
|
44
|
+
areaItems: [],
|
|
45
|
+
stateSnapshot: {
|
|
46
|
+
kind: "volcano",
|
|
47
|
+
isRenotification: outcome.state.isRenotification,
|
|
48
|
+
},
|
|
49
|
+
raw: outcome.parsed,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function fromVolcanoBatchOutcome(outcome) {
|
|
53
|
+
const xmlReport = outcome.msg.xmlReport;
|
|
54
|
+
const firstItem = outcome.parsed[0];
|
|
55
|
+
const volcanoName = firstItem?.volcanoName ?? null;
|
|
56
|
+
const volcanoCode = firstItem?.volcanoCode ?? null;
|
|
57
|
+
return {
|
|
58
|
+
id: outcome.msg.id,
|
|
59
|
+
classification: outcome.msg.classification,
|
|
60
|
+
domain: outcome.domain,
|
|
61
|
+
type: outcome.headType,
|
|
62
|
+
subType: "ashfallBatch",
|
|
63
|
+
infoType: xmlReport?.head.infoType ?? "不明",
|
|
64
|
+
title: xmlReport?.head.title ?? outcome.headType,
|
|
65
|
+
headline: xmlReport?.head.headline ?? null,
|
|
66
|
+
reportDateTime: outcome.batchReportDateTime,
|
|
67
|
+
publishingOffice: xmlReport?.control.publishingOffice ?? outcome.msg.head.author,
|
|
68
|
+
isTest: outcome.batchIsTest,
|
|
69
|
+
frameLevel: outcome.presentation.frameLevel,
|
|
70
|
+
soundLevel: outcome.presentation.soundLevel,
|
|
71
|
+
notifyCategory: outcome.presentation.notifyCategory,
|
|
72
|
+
isCancellation: false,
|
|
73
|
+
eventId: xmlReport?.head.eventId ?? null,
|
|
74
|
+
serial: xmlReport?.head.serial ?? null,
|
|
75
|
+
volcanoCode,
|
|
76
|
+
volcanoName,
|
|
77
|
+
areaNames: [],
|
|
78
|
+
forecastAreaNames: [],
|
|
79
|
+
municipalityNames: [],
|
|
80
|
+
observationNames: [],
|
|
81
|
+
areaCount: 0,
|
|
82
|
+
forecastAreaCount: 0,
|
|
83
|
+
municipalityCount: 0,
|
|
84
|
+
observationCount: 0,
|
|
85
|
+
areaItems: [],
|
|
86
|
+
raw: outcome.parsed,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toPresentationEvent = toPresentationEvent;
|
|
4
|
+
const from_eew_1 = require("./from-eew");
|
|
5
|
+
const from_earthquake_1 = require("./from-earthquake");
|
|
6
|
+
const from_seismic_text_1 = require("./from-seismic-text");
|
|
7
|
+
const from_lg_observation_1 = require("./from-lg-observation");
|
|
8
|
+
const from_tsunami_1 = require("./from-tsunami");
|
|
9
|
+
const from_volcano_1 = require("./from-volcano");
|
|
10
|
+
const from_nankai_trough_1 = require("./from-nankai-trough");
|
|
11
|
+
const from_raw_1 = require("./from-raw");
|
|
12
|
+
/** ProcessOutcome → PresentationEvent に変換する */
|
|
13
|
+
function toPresentationEvent(outcome) {
|
|
14
|
+
switch (outcome.domain) {
|
|
15
|
+
case "eew":
|
|
16
|
+
return (0, from_eew_1.fromEewOutcome)(outcome);
|
|
17
|
+
case "earthquake":
|
|
18
|
+
return (0, from_earthquake_1.fromEarthquakeOutcome)(outcome);
|
|
19
|
+
case "seismicText":
|
|
20
|
+
return (0, from_seismic_text_1.fromSeismicTextOutcome)(outcome);
|
|
21
|
+
case "lgObservation":
|
|
22
|
+
return (0, from_lg_observation_1.fromLgObservationOutcome)(outcome);
|
|
23
|
+
case "tsunami":
|
|
24
|
+
return (0, from_tsunami_1.fromTsunamiOutcome)(outcome);
|
|
25
|
+
case "volcano":
|
|
26
|
+
return (0, from_volcano_1.fromVolcanoOutcome)(outcome);
|
|
27
|
+
case "nankaiTrough":
|
|
28
|
+
return (0, from_nankai_trough_1.fromNankaiTroughOutcome)(outcome);
|
|
29
|
+
case "raw":
|
|
30
|
+
return (0, from_raw_1.fromRawOutcome)(outcome);
|
|
31
|
+
}
|
|
32
|
+
}
|