streamer-node 1.0.31 → 1.0.37
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/dist/package.json +6 -2
- package/dist/scripts/README.md +670 -0
- package/dist/scripts/install-streamer-node.sh +117 -0
- package/dist/scripts/reframe_ball.py +354 -0
- package/dist/src/application/interfaces/StartStreamUseCase.types.d.ts +3 -1
- package/dist/src/application/interfaces/StartStreamUseCase.types.d.ts.map +1 -1
- package/dist/src/application/interfaces/StartStreamUseCase.types.js.map +1 -1
- package/dist/src/application/services/HttpClient.d.ts +21 -0
- package/dist/src/application/services/HttpClient.d.ts.map +1 -1
- package/dist/src/application/services/HttpClient.js +37 -5
- package/dist/src/application/services/HttpClient.js.map +1 -1
- package/dist/src/application/services/StreamManagerService.d.ts.map +1 -1
- package/dist/src/application/services/StreamManagerService.js +2 -0
- package/dist/src/application/services/StreamManagerService.js.map +1 -1
- package/dist/src/application/use-cases/CaptureHighlightUseCase.d.ts +52 -0
- package/dist/src/application/use-cases/CaptureHighlightUseCase.d.ts.map +1 -0
- package/dist/src/application/use-cases/CaptureHighlightUseCase.js +169 -0
- package/dist/src/application/use-cases/CaptureHighlightUseCase.js.map +1 -0
- package/dist/src/application/use-cases/StartStreamUseCase.d.ts +9 -1
- package/dist/src/application/use-cases/StartStreamUseCase.d.ts.map +1 -1
- package/dist/src/application/use-cases/StartStreamUseCase.js +125 -2
- package/dist/src/application/use-cases/StartStreamUseCase.js.map +1 -1
- package/dist/src/application/use-cases/StopStreamUseCase.d.ts +5 -1
- package/dist/src/application/use-cases/StopStreamUseCase.d.ts.map +1 -1
- package/dist/src/application/use-cases/StopStreamUseCase.js +7 -1
- package/dist/src/application/use-cases/StopStreamUseCase.js.map +1 -1
- package/dist/src/domain/events/StreamEvent.d.ts +5 -0
- package/dist/src/domain/events/StreamEvent.d.ts.map +1 -1
- package/dist/src/domain/services/BallReframer.d.ts +35 -0
- package/dist/src/domain/services/BallReframer.d.ts.map +1 -0
- package/dist/src/domain/services/BallReframer.js +3 -0
- package/dist/src/domain/services/BallReframer.js.map +1 -0
- package/dist/src/domain/services/FFmpegService.d.ts +6 -2
- package/dist/src/domain/services/FFmpegService.d.ts.map +1 -1
- package/dist/src/domain/services/HighlightSignalSource.d.ts +113 -0
- package/dist/src/domain/services/HighlightSignalSource.d.ts.map +1 -0
- package/dist/src/domain/services/HighlightSignalSource.js +3 -0
- package/dist/src/domain/services/HighlightSignalSource.js.map +1 -0
- package/dist/src/domain/services/SSEService.d.ts +1 -0
- package/dist/src/domain/services/SSEService.d.ts.map +1 -1
- package/dist/src/infrastructure/config/Config.d.ts +32 -0
- package/dist/src/infrastructure/config/Config.d.ts.map +1 -1
- package/dist/src/infrastructure/config/Config.js +60 -0
- package/dist/src/infrastructure/config/Config.js.map +1 -1
- package/dist/src/infrastructure/listeners/SupabaseListener.d.ts +5 -0
- package/dist/src/infrastructure/listeners/SupabaseListener.d.ts.map +1 -1
- package/dist/src/infrastructure/listeners/SupabaseListener.js +43 -5
- package/dist/src/infrastructure/listeners/SupabaseListener.js.map +1 -1
- package/dist/src/infrastructure/logging/LogShippingService.d.ts +3 -1
- package/dist/src/infrastructure/logging/LogShippingService.d.ts.map +1 -1
- package/dist/src/infrastructure/logging/LogShippingService.js +13 -4
- package/dist/src/infrastructure/logging/LogShippingService.js.map +1 -1
- package/dist/src/infrastructure/logging/RemoteLogger.d.ts +1 -0
- package/dist/src/infrastructure/logging/RemoteLogger.d.ts.map +1 -1
- package/dist/src/infrastructure/logging/RemoteLogger.js +1 -1
- package/dist/src/infrastructure/logging/RemoteLogger.js.map +1 -1
- package/dist/src/infrastructure/services/AdDownloaderService.d.ts +85 -0
- package/dist/src/infrastructure/services/AdDownloaderService.d.ts.map +1 -0
- package/dist/src/infrastructure/services/AdDownloaderService.js +530 -0
- package/dist/src/infrastructure/services/AdDownloaderService.js.map +1 -0
- package/dist/src/infrastructure/services/AdRotator.d.ts +63 -0
- package/dist/src/infrastructure/services/AdRotator.d.ts.map +1 -0
- package/dist/src/infrastructure/services/AdRotator.js +223 -0
- package/dist/src/infrastructure/services/AdRotator.js.map +1 -0
- package/dist/src/infrastructure/services/HighlightBufferManager.d.ts +65 -0
- package/dist/src/infrastructure/services/HighlightBufferManager.d.ts.map +1 -0
- package/dist/src/infrastructure/services/HighlightBufferManager.js +203 -0
- package/dist/src/infrastructure/services/HighlightBufferManager.js.map +1 -0
- package/dist/src/infrastructure/services/HighlightBufferRegistry.d.ts +23 -0
- package/dist/src/infrastructure/services/HighlightBufferRegistry.d.ts.map +1 -0
- package/dist/src/infrastructure/services/HighlightBufferRegistry.js +44 -0
- package/dist/src/infrastructure/services/HighlightBufferRegistry.js.map +1 -0
- package/dist/src/infrastructure/services/HighlightExtractorService.d.ts +65 -0
- package/dist/src/infrastructure/services/HighlightExtractorService.d.ts.map +1 -0
- package/dist/src/infrastructure/services/HighlightExtractorService.js +264 -0
- package/dist/src/infrastructure/services/HighlightExtractorService.js.map +1 -0
- package/dist/src/infrastructure/services/HighlightRendererService.d.ts +38 -0
- package/dist/src/infrastructure/services/HighlightRendererService.d.ts.map +1 -0
- package/dist/src/infrastructure/services/HighlightRendererService.js +182 -0
- package/dist/src/infrastructure/services/HighlightRendererService.js.map +1 -0
- package/dist/src/infrastructure/services/NodeFFmpegService.d.ts +6 -4
- package/dist/src/infrastructure/services/NodeFFmpegService.d.ts.map +1 -1
- package/dist/src/infrastructure/services/NodeFFmpegService.js +154 -32
- package/dist/src/infrastructure/services/NodeFFmpegService.js.map +1 -1
- package/dist/src/infrastructure/services/NodeSSEService.d.ts +8 -0
- package/dist/src/infrastructure/services/NodeSSEService.d.ts.map +1 -1
- package/dist/src/infrastructure/services/NodeSSEService.js +71 -27
- package/dist/src/infrastructure/services/NodeSSEService.js.map +1 -1
- package/dist/src/infrastructure/services/NullBallReframer.d.ts +11 -0
- package/dist/src/infrastructure/services/NullBallReframer.d.ts.map +1 -0
- package/dist/src/infrastructure/services/NullBallReframer.js +16 -0
- package/dist/src/infrastructure/services/NullBallReframer.js.map +1 -0
- package/dist/src/infrastructure/services/PythonBallReframer.d.ts +35 -0
- package/dist/src/infrastructure/services/PythonBallReframer.d.ts.map +1 -0
- package/dist/src/infrastructure/services/PythonBallReframer.js +238 -0
- package/dist/src/infrastructure/services/PythonBallReframer.js.map +1 -0
- package/dist/src/infrastructure/services/SerialHighlightListener.d.ts +45 -0
- package/dist/src/infrastructure/services/SerialHighlightListener.d.ts.map +1 -0
- package/dist/src/infrastructure/services/SerialHighlightListener.js +440 -0
- package/dist/src/infrastructure/services/SerialHighlightListener.js.map +1 -0
- package/dist/src/infrastructure/services/YouTubeUploadService.d.ts +36 -0
- package/dist/src/infrastructure/services/YouTubeUploadService.d.ts.map +1 -0
- package/dist/src/infrastructure/services/YouTubeUploadService.js +402 -0
- package/dist/src/infrastructure/services/YouTubeUploadService.js.map +1 -0
- package/dist/src/infrastructure/utils/ResourceSampler.d.ts +47 -0
- package/dist/src/infrastructure/utils/ResourceSampler.d.ts.map +1 -0
- package/dist/src/infrastructure/utils/ResourceSampler.js +102 -0
- package/dist/src/infrastructure/utils/ResourceSampler.js.map +1 -0
- package/dist/src/infrastructure/utils/lowPriority.d.ts +29 -0
- package/dist/src/infrastructure/utils/lowPriority.d.ts.map +1 -0
- package/dist/src/infrastructure/utils/lowPriority.js +31 -0
- package/dist/src/infrastructure/utils/lowPriority.js.map +1 -0
- package/dist/src/infrastructure/utils/paths.d.ts +27 -0
- package/dist/src/infrastructure/utils/paths.d.ts.map +1 -0
- package/dist/src/infrastructure/utils/paths.js +69 -0
- package/dist/src/infrastructure/utils/paths.js.map +1 -0
- package/dist/src/infrastructure/utils/spawnToFile.d.ts +20 -0
- package/dist/src/infrastructure/utils/spawnToFile.d.ts.map +1 -0
- package/dist/src/infrastructure/utils/spawnToFile.js +98 -0
- package/dist/src/infrastructure/utils/spawnToFile.js.map +1 -0
- package/dist/src/main.js +228 -2
- package/dist/src/main.js.map +1 -1
- package/package.json +6 -2
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { StreamId } from "../value-objects/StreamId";
|
|
2
|
+
export interface AdSpec {
|
|
3
|
+
url: string;
|
|
4
|
+
durationSec?: number;
|
|
5
|
+
}
|
|
2
6
|
export interface DomainEvent {
|
|
3
7
|
readonly eventId: string;
|
|
4
8
|
readonly occurredOn: Date;
|
|
@@ -44,6 +48,7 @@ export interface SSEStreamEvent extends DomainEvent {
|
|
|
44
48
|
readonly streamKey: string;
|
|
45
49
|
readonly reconciliationMode?: boolean;
|
|
46
50
|
readonly isScorecardActivated?: boolean;
|
|
51
|
+
readonly ads?: AdSpec[];
|
|
47
52
|
}
|
|
48
53
|
export type StreamDomainEvent = StreamStartedEvent | StreamStoppedEvent | StreamFailedEvent | AudioDetectedEvent | SSEConnectionEvent | SSEStreamEvent;
|
|
49
54
|
//# sourceMappingURL=StreamEvent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StreamEvent.d.ts","sourceRoot":"","sources":["../../../../src/domain/events/StreamEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"StreamEvent.d.ts","sourceRoot":"","sources":["../../../../src/domain/events/StreamEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,kBAAkB,GAClB,iBAAiB,GACjB,kBAAkB,GAClB,kBAAkB,GAClB,cAAc,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reframes a raw highlight clip to follow the ball, producing a
|
|
3
|
+
* social-media-shaped (e.g. 9:16) video.
|
|
4
|
+
*
|
|
5
|
+
* ── IN SIMPLE WORDS ──
|
|
6
|
+
* Takes the wide, full-court highlight clip and produces a cropped version that
|
|
7
|
+
* pans/zooms to keep the action (the ball) in frame, in a vertical aspect good
|
|
8
|
+
* for social posts. If it can't (feature off, or detection fails), it returns
|
|
9
|
+
* null and the caller just uses the full-frame clip instead.
|
|
10
|
+
*
|
|
11
|
+
* ── BUSINESS RULES ──
|
|
12
|
+
* - Off by default: the classical-CV implementation is unvalidated without real
|
|
13
|
+
* padel footage, so a bad detection day must never block a highlight — it
|
|
14
|
+
* falls back to the full frame.
|
|
15
|
+
* - Reframing OWNS the crop/track (it writes the reframed video). Logo overlay
|
|
16
|
+
* is a separate, later step so it works identically on a reframed or a
|
|
17
|
+
* full-frame clip.
|
|
18
|
+
*
|
|
19
|
+
* ── WHY IT'S BUILT THIS WAY (change at your peril) ──
|
|
20
|
+
* Returning a produced VIDEO PATH (not a per-frame crop path) keeps the hard
|
|
21
|
+
* per-frame cropping in OpenCV, which does it well, instead of forcing ffmpeg
|
|
22
|
+
* to apply an arbitrary motion path via fragile filter expressions.
|
|
23
|
+
*
|
|
24
|
+
* ── DO NOT ──
|
|
25
|
+
* - Do NOT throw: any failure must resolve to null (full-frame fallback).
|
|
26
|
+
*/
|
|
27
|
+
export interface BallReframer {
|
|
28
|
+
/**
|
|
29
|
+
* Produce a ball-following, reel-aspect video from `clipPath`. Returns the
|
|
30
|
+
* output path, or null when reframing is disabled or fails (caller falls back
|
|
31
|
+
* to the original clip). Never throws.
|
|
32
|
+
*/
|
|
33
|
+
reframe(clipPath: string, courtId: string): Promise<string | null>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=BallReframer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BallReframer.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/BallReframer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BallReframer.js","sourceRoot":"","sources":["../../../../src/domain/services/BallReframer.ts"],"names":[],"mappings":""}
|
|
@@ -10,6 +10,10 @@ export interface FFmpegProcess {
|
|
|
10
10
|
readonly command: FFmpegCommand;
|
|
11
11
|
readonly startTime: Date;
|
|
12
12
|
}
|
|
13
|
+
export interface AdOverlayPaths {
|
|
14
|
+
left?: string | null;
|
|
15
|
+
right?: string | null;
|
|
16
|
+
}
|
|
13
17
|
export interface FFmpegService {
|
|
14
18
|
/**
|
|
15
19
|
* Start an FFmpeg stream process
|
|
@@ -17,7 +21,7 @@ export interface FFmpegService {
|
|
|
17
21
|
startStream(cameraUrl: StreamUrl, streamKey: string, hasAudio: boolean, courtId: string, retry: {
|
|
18
22
|
event: StartStreamRequest;
|
|
19
23
|
onRetryStream: (event: StartStreamRequest) => Promise<void>;
|
|
20
|
-
}, isScorecardActivated?: boolean): Promise<FFmpegProcess>;
|
|
24
|
+
}, isScorecardActivated?: boolean, adPaths?: AdOverlayPaths, highlightBufferDir?: string | null): Promise<FFmpegProcess>;
|
|
21
25
|
/**
|
|
22
26
|
* Stop an FFmpeg process by PID
|
|
23
27
|
*/
|
|
@@ -33,7 +37,7 @@ export interface FFmpegService {
|
|
|
33
37
|
/**
|
|
34
38
|
* Build FFmpeg command for streaming
|
|
35
39
|
*/
|
|
36
|
-
buildStreamCommand(cameraUrl: StreamUrl, streamKey: string, hasAudio: boolean, courtId: string, isScorecardActivated?: boolean): FFmpegCommand;
|
|
40
|
+
buildStreamCommand(cameraUrl: StreamUrl, streamKey: string, hasAudio: boolean, courtId: string, isScorecardActivated?: boolean, adPaths?: AdOverlayPaths, highlightBufferDir?: string | null): FFmpegCommand;
|
|
37
41
|
/**
|
|
38
42
|
* Get all running FFmpeg processes managed by this service
|
|
39
43
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FFmpegService.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/FFmpegService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uDAAuD,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,CACT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;QACL,KAAK,EAAE,kBAAkB,CAAC;QAC1B,aAAa,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,EACD,oBAAoB,CAAC,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"FFmpegService.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/FFmpegService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uDAAuD,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,CACT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;QACL,KAAK,EAAE,kBAAkB,CAAC;QAC1B,aAAa,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,EACD,oBAAoB,CAAC,EAAE,OAAO,EAC9B,OAAO,CAAC,EAAE,cAAc,EACxB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GACjC,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B;;OAEG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhD;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpD;;OAEG;IACH,kBAAkB,CAChB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,OAAO,EAC9B,OAAO,CAAC,EAAE,cAAc,EACxB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GACjC,aAAa,CAAC;IAEjB;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAEhD;;OAEG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source of highlight signals from the physical ESP32 device.
|
|
3
|
+
*
|
|
4
|
+
* ── IN SIMPLE WORDS ──
|
|
5
|
+
* The court hardware (an ESP32) plugs into the streamer box over USB and
|
|
6
|
+
* constantly chatters one JSON object per line — a heartbeat every 5 seconds,
|
|
7
|
+
* plus a `{"type":"button"}` line when someone presses the physical highlight
|
|
8
|
+
* button on a court. This interface is the streamer's window onto that device:
|
|
9
|
+
* it can tell us whether the hardware is currently attached and alive
|
|
10
|
+
* (`isDevicePresent`), which is what decides whether a box records the
|
|
11
|
+
* highlight buffer at all.
|
|
12
|
+
*
|
|
13
|
+
* Protocol contract: docs/esp32/STREAMER_INTEGRATION.md (authoritative).
|
|
14
|
+
*
|
|
15
|
+
* ── BUSINESS RULES ──
|
|
16
|
+
* - Highlight capture is enabled per-box by HARDWARE PRESENCE, not by config
|
|
17
|
+
* (decision 2026-07-18): a box with the ESP32 plugged in records the rolling
|
|
18
|
+
* buffer; a box without it never does. `isDevicePresent()` is that signal.
|
|
19
|
+
* - Presence is proven by the device's own traffic (the existing 5s heartbeat),
|
|
20
|
+
* so no ESP32 firmware change is needed to support it.
|
|
21
|
+
*
|
|
22
|
+
* ── WHY IT'S BUILT THIS WAY (change at your peril) ──
|
|
23
|
+
* The application layer (StartStreamUseCase) depends on this abstraction, not
|
|
24
|
+
* on the concrete serial implementation, so the buffer-enable decision stays
|
|
25
|
+
* testable and the transport (USB serial today) can change without touching
|
|
26
|
+
* stream orchestration. Without the abstraction, the use-case would hard-couple
|
|
27
|
+
* to node-serialport and become impossible to exercise without real hardware.
|
|
28
|
+
*
|
|
29
|
+
* ── DO NOT ──
|
|
30
|
+
* - Do NOT make `isDevicePresent()` throw or block — it is called on the
|
|
31
|
+
* stream-start hot path and must be a cheap, synchronous, non-failing read.
|
|
32
|
+
* - Do NOT treat "port open" alone as present without a freshness check; a
|
|
33
|
+
* stale/hung device should read as absent.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* A highlight moment was signalled. `receivedAtMs` is the streamer's local
|
|
37
|
+
* receipt time (Date.now); the true event time is estimated downstream by
|
|
38
|
+
* subtracting the configured lag margin (the mesh/transport delay).
|
|
39
|
+
*/
|
|
40
|
+
export interface HighlightSignal {
|
|
41
|
+
receivedAtMs: number;
|
|
42
|
+
/**
|
|
43
|
+
* The court the press came from, taken from the `button` packet's `courtId`.
|
|
44
|
+
*
|
|
45
|
+
* MUST be checked before acting. Every unit ships with the same mesh
|
|
46
|
+
* credentials, so at a venue with two courts in WiFi range this box's ESP32
|
|
47
|
+
* relays the neighbouring court's traffic verbatim — the firmware does no
|
|
48
|
+
* filtering and the spec puts that on the streamer. Acting on any press
|
|
49
|
+
* would cut a clip from the wrong court's stream, with nothing in the logs
|
|
50
|
+
* to explain it.
|
|
51
|
+
*
|
|
52
|
+
* Undefined for debug-triggered signals (force/trigger-file), which carry no
|
|
53
|
+
* court and are treated as "this box's running stream".
|
|
54
|
+
*/
|
|
55
|
+
courtId?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The court's scoreboard state, exactly as the physical board reports it.
|
|
59
|
+
*
|
|
60
|
+
* ── WHY THE SCORES ARE STRINGS ──
|
|
61
|
+
* Tennis values are "00"/"15"/"30"/"40"/"AD" — the Arduino's token is passed
|
|
62
|
+
* through untouched by every hop. An integer type works right up until deuce.
|
|
63
|
+
* Games ARE integers (and are 0/meaningless in Americano).
|
|
64
|
+
*
|
|
65
|
+
* ── WHY ABSOLUTE, NEVER A DELTA ──
|
|
66
|
+
* Mesh delivery is best-effort with no retry. Replaying absolute state is
|
|
67
|
+
* self-healing after a dropped packet; replaying increments desyncs forever.
|
|
68
|
+
*/
|
|
69
|
+
export interface CourtScoreSignal {
|
|
70
|
+
courtId: string;
|
|
71
|
+
/** Raw firmware mode: "TENNIS" | "AMER". Mapped to the backend's enum later. */
|
|
72
|
+
mode?: string;
|
|
73
|
+
scoreA: string;
|
|
74
|
+
scoreB: string;
|
|
75
|
+
gamesA?: number;
|
|
76
|
+
gamesB?: number;
|
|
77
|
+
}
|
|
78
|
+
export interface HighlightSignalSource {
|
|
79
|
+
/**
|
|
80
|
+
* Begin listening to the device (open the serial port, start parsing).
|
|
81
|
+
* Called once at app boot. Must be fail-soft: if the device/library is
|
|
82
|
+
* unavailable, it logs and leaves `isDevicePresent()` returning false rather
|
|
83
|
+
* than throwing.
|
|
84
|
+
*/
|
|
85
|
+
start(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Stop listening and release the port. Idempotent; safe from shutdown.
|
|
88
|
+
*/
|
|
89
|
+
stop(): void;
|
|
90
|
+
/**
|
|
91
|
+
* True when the ESP32 is attached and has produced recognized traffic
|
|
92
|
+
* recently (within the freshness window). Cheap O(1) read, never throws.
|
|
93
|
+
* Drives automatic enablement of the highlight buffer.
|
|
94
|
+
*/
|
|
95
|
+
isDevicePresent(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Subscribe to highlight signals (a button press → HIGHLIGHT packet, or a
|
|
98
|
+
* debug trigger). The listener receives the receipt time; window anchoring
|
|
99
|
+
* (subtracting the lag margin) happens in the capture use-case.
|
|
100
|
+
*/
|
|
101
|
+
onHighlight(listener: (signal: HighlightSignal) => void): void;
|
|
102
|
+
/**
|
|
103
|
+
* Subscribe to scoreboard updates from the court hardware.
|
|
104
|
+
*
|
|
105
|
+
* Lives on this interface because the ESP32 is ONE serial device and a serial
|
|
106
|
+
* port has exactly one reader — so the same listener necessarily surfaces both
|
|
107
|
+
* the button presses and the score packets. (The interface name predates the
|
|
108
|
+
* score path; renaming it to something like CourtDeviceSource is a worthwhile
|
|
109
|
+
* follow-up, deliberately kept out of this change to keep the diff reviewable.)
|
|
110
|
+
*/
|
|
111
|
+
onScore(listener: (signal: CourtScoreSignal) => void): void;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=HighlightSignalSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HighlightSignalSource.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/HighlightSignalSource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;;OAIG;IACH,eAAe,IAAI,OAAO,CAAC;IAE3B;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI,CAAC;IAE/D;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HighlightSignalSource.js","sourceRoot":"","sources":["../../../../src/domain/services/HighlightSignalSource.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SSEService.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/SSEService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"SSEService.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/SSEService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAG5B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI,CAAC;IAE/D;;OAEG;IACH,kBAAkB,CAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,cAAc,KAAK,IAAI,GACxE,IAAI,CAAC;IAER;;OAEG;IACH,mBAAmB,IAAI,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;IAErE;;OAEG;IACH,aAAa,IAAI,MAAM,CAAC;IAExB;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface AppConfig {
|
|
2
2
|
server: {
|
|
3
3
|
baseUrl: string;
|
|
4
|
+
streamingApiKey: string;
|
|
4
5
|
};
|
|
5
6
|
images: {
|
|
6
7
|
clientPath: string;
|
|
@@ -15,6 +16,13 @@ export interface AppConfig {
|
|
|
15
16
|
stream: {
|
|
16
17
|
persistentStateDir: string;
|
|
17
18
|
healthCheckInterval: number;
|
|
19
|
+
youtubeRtmpBase: string;
|
|
20
|
+
};
|
|
21
|
+
ads: {
|
|
22
|
+
defaultDurationSec: number;
|
|
23
|
+
minDurationSec: number;
|
|
24
|
+
maxDurationSec: number;
|
|
25
|
+
clipFps: number;
|
|
18
26
|
};
|
|
19
27
|
logging: {
|
|
20
28
|
level: string;
|
|
@@ -41,6 +49,29 @@ export interface AppConfig {
|
|
|
41
49
|
apiKey: string;
|
|
42
50
|
apiSecret: string;
|
|
43
51
|
};
|
|
52
|
+
highlight: {
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
bufferDir: string;
|
|
55
|
+
bufferSegmentSec: number;
|
|
56
|
+
preRollSec: number;
|
|
57
|
+
postRollSec: number;
|
|
58
|
+
lagMarginSec: number;
|
|
59
|
+
bufferRetentionSec: number;
|
|
60
|
+
outputDir: string;
|
|
61
|
+
serialPortPath: string;
|
|
62
|
+
serialBaudRate: number;
|
|
63
|
+
forcePresent: boolean;
|
|
64
|
+
triggerFile: string;
|
|
65
|
+
ballTracking: {
|
|
66
|
+
enabled: boolean;
|
|
67
|
+
};
|
|
68
|
+
reelAspect: string;
|
|
69
|
+
uploadEnabled: boolean;
|
|
70
|
+
deleteAfterUpload: boolean;
|
|
71
|
+
};
|
|
72
|
+
esp32: {
|
|
73
|
+
scoreForwardingEnabled: boolean;
|
|
74
|
+
};
|
|
44
75
|
environment: string;
|
|
45
76
|
}
|
|
46
77
|
export declare class Config {
|
|
@@ -50,6 +81,7 @@ export declare class Config {
|
|
|
50
81
|
static getInstance(): Config;
|
|
51
82
|
get(): AppConfig;
|
|
52
83
|
private loadConfig;
|
|
84
|
+
private parseIntEnv;
|
|
53
85
|
private getEnvVar;
|
|
54
86
|
validate(): void;
|
|
55
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/config/Config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/config/Config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAOhB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,GAAG,EAAE;QACH,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAC;QAC3B,mBAAmB,EAAE,MAAM,CAAC;QAG5B,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,GAAG,EAAE;QACH,kBAAkB,EAAE,MAAM,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,aAAa,EAAE;QACb,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE;QACR,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,UAAU,EAAE;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,SAAS,EAAE;QAQT,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QAKzB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QAIvB,YAAY,EAAE,OAAO,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QAOpB,YAAY,EAAE;YACZ,OAAO,EAAE,OAAO,CAAC;SAClB,CAAC;QACF,UAAU,EAAE,MAAM,CAAC;QAKnB,aAAa,EAAE,OAAO,CAAC;QAMvB,iBAAiB,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF,KAAK,EAAE;QAQL,sBAAsB,EAAE,OAAO,CAAC;KACjC,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,MAAM,CAAY;IAE1B,OAAO;WAaO,WAAW,IAAI,MAAM;IAO5B,GAAG,IAAI,SAAS;IAIvB,OAAO,CAAC,UAAU;IAsIlB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,SAAS;IA+BV,QAAQ,IAAI,IAAI;CAexB"}
|
|
@@ -56,9 +56,15 @@ class Config {
|
|
|
56
56
|
return this.config;
|
|
57
57
|
}
|
|
58
58
|
loadConfig() {
|
|
59
|
+
// Highlight window values parsed once and reused (fields + derived
|
|
60
|
+
// retention default) to avoid re-reading the same env vars.
|
|
61
|
+
const hlPreRollSec = this.parseIntEnv("HIGHLIGHT_PRE_ROLL_SEC", 25);
|
|
62
|
+
const hlPostRollSec = this.parseIntEnv("HIGHLIGHT_POST_ROLL_SEC", 5);
|
|
63
|
+
const hlLagMarginSec = this.parseIntEnv("HIGHLIGHT_LAG_MARGIN_SEC", 5);
|
|
59
64
|
return {
|
|
60
65
|
server: {
|
|
61
66
|
baseUrl: this.getEnvVar("BASE_URL", "https://api.drop-shot.live"),
|
|
67
|
+
streamingApiKey: this.getEnvVar("STREAMING_API_KEY", ""),
|
|
62
68
|
},
|
|
63
69
|
images: {
|
|
64
70
|
clientPath: this.getEnvVar("CLIENT_IMAGES_PATH", "./public/client.png"),
|
|
@@ -73,6 +79,15 @@ class Config {
|
|
|
73
79
|
stream: {
|
|
74
80
|
persistentStateDir: this.getEnvVar("PERSISTENT_STATE_DIR", "/var/tmp/stream_registry"),
|
|
75
81
|
healthCheckInterval: parseInt(this.getEnvVar("HEALTH_CHECK_INTERVAL", "30000")),
|
|
82
|
+
// Trailing slash trimmed so a base like ".../live2/" can't produce a
|
|
83
|
+
// double slash when the stream key is appended.
|
|
84
|
+
youtubeRtmpBase: this.getEnvVar("YOUTUBE_RTMP_BASE", "rtmp://a.rtmp.youtube.com/live2").replace(/\/+$/, ""),
|
|
85
|
+
},
|
|
86
|
+
ads: {
|
|
87
|
+
defaultDurationSec: this.parseIntEnv("AD_DEFAULT_DURATION_SEC", 12),
|
|
88
|
+
minDurationSec: this.parseIntEnv("AD_MIN_DURATION_SEC", 5),
|
|
89
|
+
maxDurationSec: this.parseIntEnv("AD_MAX_DURATION_SEC", 120),
|
|
90
|
+
clipFps: this.parseIntEnv("AD_CLIP_FPS", 15),
|
|
76
91
|
},
|
|
77
92
|
logging: {
|
|
78
93
|
level: this.getEnvVar("LOG_LEVEL", "info"),
|
|
@@ -99,9 +114,54 @@ class Config {
|
|
|
99
114
|
apiKey: this.getEnvVar("CLOUDINARY_API_KEY", ""),
|
|
100
115
|
apiSecret: this.getEnvVar("CLOUDINARY_API_SECRET", ""),
|
|
101
116
|
},
|
|
117
|
+
highlight: {
|
|
118
|
+
// Default false until Phase 2 retention bounds the buffer (see the
|
|
119
|
+
// interface comment). Strict: only the literal "true" enables it.
|
|
120
|
+
enabled: this.getEnvVar("HIGHLIGHT_ENABLED", "false") === "true",
|
|
121
|
+
bufferDir: this.getEnvVar("HIGHLIGHT_BUFFER_DIR", "./highlight-buffer"),
|
|
122
|
+
// Floor at 2s: segment filenames use whole-second (%s) timestamps, so a
|
|
123
|
+
// 1s segment length could emit two files in the same second and clobber
|
|
124
|
+
// one, punching a gap in the buffer.
|
|
125
|
+
bufferSegmentSec: Math.max(2, this.parseIntEnv("HIGHLIGHT_BUFFER_SEGMENT_SEC", 2)),
|
|
126
|
+
preRollSec: hlPreRollSec,
|
|
127
|
+
postRollSec: hlPostRollSec,
|
|
128
|
+
lagMarginSec: hlLagMarginSec,
|
|
129
|
+
// Default = full window (pre + post + lag) + 10s safety pad. Overridable,
|
|
130
|
+
// but must stay ≥ the window or extraction can lose the leading edge.
|
|
131
|
+
bufferRetentionSec: this.parseIntEnv("HIGHLIGHT_BUFFER_RETENTION_SEC", hlPreRollSec + hlPostRollSec + hlLagMarginSec + 10),
|
|
132
|
+
outputDir: this.getEnvVar("HIGHLIGHT_OUTPUT_DIR", "./highlights"),
|
|
133
|
+
// "auto" → discover the ESP32 among connected serial devices; or an
|
|
134
|
+
// explicit path like "/dev/ttyUSB0". Baud must match esp32-leader.ino.
|
|
135
|
+
serialPortPath: this.getEnvVar("HIGHLIGHT_SERIAL_PORT", "auto"),
|
|
136
|
+
serialBaudRate: this.parseIntEnv("HIGHLIGHT_SERIAL_BAUD", 115200),
|
|
137
|
+
forcePresent: this.getEnvVar("HIGHLIGHT_FORCE_PRESENT", "false") === "true",
|
|
138
|
+
triggerFile: this.getEnvVar("HIGHLIGHT_TRIGGER_FILE", ""),
|
|
139
|
+
ballTracking: {
|
|
140
|
+
enabled: this.getEnvVar("HIGHLIGHT_BALL_TRACKING_ENABLED", "false") === "true",
|
|
141
|
+
},
|
|
142
|
+
// 9:16 — full-screen vertical. This is the ratio YouTube requires to
|
|
143
|
+
// classify an upload as a SHORT (the backend accepts 9:16 or 1:1), and
|
|
144
|
+
// it is what Reels/TikTok expect too. Overridable per box: "4:5" crops
|
|
145
|
+
// less aggressively for feed posts, "16:9" keeps the full landscape
|
|
146
|
+
// frame (and then skips the reframe entirely — nothing to crop).
|
|
147
|
+
reelAspect: this.getEnvVar("HIGHLIGHT_REEL_ASPECT", "9:16"),
|
|
148
|
+
uploadEnabled: this.getEnvVar("HIGHLIGHT_UPLOAD_ENABLED", "false") === "true",
|
|
149
|
+
// Opt OUT (set "false") to keep local copies after upload.
|
|
150
|
+
deleteAfterUpload: this.getEnvVar("HIGHLIGHT_DELETE_AFTER_UPLOAD", "true") !== "false",
|
|
151
|
+
},
|
|
152
|
+
esp32: {
|
|
153
|
+
scoreForwardingEnabled: this.getEnvVar("ESP32_SCORE_FORWARDING_ENABLED", "false") === "true",
|
|
154
|
+
},
|
|
102
155
|
environment: this.getEnvVar("NODE_ENV", "development"),
|
|
103
156
|
};
|
|
104
157
|
}
|
|
158
|
+
// Parse a positive integer env var, falling back when missing/invalid. Guards
|
|
159
|
+
// against NaN and non-positive values (a negative would otherwise pass through
|
|
160
|
+
// and, e.g., let an ad duration clamp to a zero-length clip).
|
|
161
|
+
parseIntEnv(key, fallback) {
|
|
162
|
+
const value = parseInt(this.getEnvVar(key, String(fallback)), 10);
|
|
163
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
164
|
+
}
|
|
105
165
|
getEnvVar(key, defaultValue) {
|
|
106
166
|
const value = process.env[key];
|
|
107
167
|
// Special logging for DROPSHOT_GROUND_ID to confirm source
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Config.js","sourceRoot":"","sources":["../../../../src/infrastructure/config/Config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAEjC,6BAA6B;AAC7B,MAAM,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"Config.js","sourceRoot":"","sources":["../../../../src/infrastructure/config/Config.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,6 +25,11 @@ export declare class SupabaseListener {
|
|
|
25
25
|
private handleAllEvents;
|
|
26
26
|
private extractScore;
|
|
27
27
|
private writeScoreImage;
|
|
28
|
+
/**
|
|
29
|
+
* Trim `text` with a trailing ellipsis until it fits within `maxWidth` at the
|
|
30
|
+
* context's current font. Returns the text unchanged when it already fits.
|
|
31
|
+
*/
|
|
32
|
+
private truncateToWidth;
|
|
28
33
|
private getScoreImagePath;
|
|
29
34
|
/**
|
|
30
35
|
* Stop listening to table changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseListener.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/listeners/SupabaseListener.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,uBAAuB,CAAkC;gBAErD,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAQlD;;OAEG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"SupabaseListener.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/listeners/SupabaseListener.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,uBAAuB,CAAkC;gBAErD,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAQlD;;OAEG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAuB9C;;OAEG;IACU,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAajE;;OAEG;IACH,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,YAAY;YAiDN,eAAe;IA2I7B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CASnC"}
|
|
@@ -60,6 +60,10 @@ class SupabaseListener {
|
|
|
60
60
|
return;
|
|
61
61
|
const channelName = `${this.channelName}-${courtId}`;
|
|
62
62
|
const filter = `court_id=eq.${courtId}`;
|
|
63
|
+
// Drop any cached render text from a previous session on this court so the
|
|
64
|
+
// first update after (re)subscribing always redraws the (freshly reset)
|
|
65
|
+
// transparent overlay, even if the score happens to match the old one.
|
|
66
|
+
this.lastRenderedTextByCourt.delete(courtId);
|
|
63
67
|
console.log(`🎯 Subscribing to Supabase updates for court: ${courtId}`);
|
|
64
68
|
this.supabaseService.subscribeToTable(channelName, this.tableName, this.handleAllEvents.bind(this), "UPDATE", "public", filter);
|
|
65
69
|
}
|
|
@@ -85,7 +89,7 @@ class SupabaseListener {
|
|
|
85
89
|
if (!score) {
|
|
86
90
|
return;
|
|
87
91
|
}
|
|
88
|
-
void this.writeScoreImage(score.courtId, score.left, score.right, score.leftGames, score.rightGames);
|
|
92
|
+
void this.writeScoreImage(score.courtId, score.left, score.right, score.leftGames, score.rightGames, score.leftTeam, score.rightTeam);
|
|
89
93
|
}
|
|
90
94
|
extractScore(record) {
|
|
91
95
|
const courtId = record["court_id"];
|
|
@@ -93,6 +97,8 @@ class SupabaseListener {
|
|
|
93
97
|
const rightValue = record["blue_score"];
|
|
94
98
|
const leftGamesValue = record["red_games"];
|
|
95
99
|
const rightGamesValue = record["blue_games"];
|
|
100
|
+
const leftTeamValue = record["red_team"];
|
|
101
|
+
const rightTeamValue = record["blue_team"];
|
|
96
102
|
if (typeof courtId !== "string" ||
|
|
97
103
|
leftValue === undefined ||
|
|
98
104
|
rightValue === undefined ||
|
|
@@ -100,18 +106,28 @@ class SupabaseListener {
|
|
|
100
106
|
rightGamesValue === undefined) {
|
|
101
107
|
return null;
|
|
102
108
|
}
|
|
109
|
+
// Team names are optional: older rows / other tables may not carry them,
|
|
110
|
+
// so fall back to the previous generic labels when absent or blank.
|
|
111
|
+
const leftTeam = typeof leftTeamValue === "string" && leftTeamValue.trim()
|
|
112
|
+
? leftTeamValue.trim()
|
|
113
|
+
: "TEAM A";
|
|
114
|
+
const rightTeam = typeof rightTeamValue === "string" && rightTeamValue.trim()
|
|
115
|
+
? rightTeamValue.trim()
|
|
116
|
+
: "TEAM B";
|
|
103
117
|
return {
|
|
104
118
|
courtId,
|
|
105
119
|
left: String(leftValue),
|
|
106
120
|
right: String(rightValue),
|
|
107
121
|
leftGames: String(leftGamesValue),
|
|
108
122
|
rightGames: String(rightGamesValue),
|
|
123
|
+
leftTeam,
|
|
124
|
+
rightTeam,
|
|
109
125
|
};
|
|
110
126
|
}
|
|
111
|
-
async writeScoreImage(courtId, leftScore, rightScore, leftGames, rightGames) {
|
|
127
|
+
async writeScoreImage(courtId, leftScore, rightScore, leftGames, rightGames, leftTeam, rightTeam) {
|
|
112
128
|
const width = 420;
|
|
113
129
|
const height = 120;
|
|
114
|
-
const text = `${leftScore}-${rightScore} ${leftGames}-${rightGames}`;
|
|
130
|
+
const text = `${leftTeam}|${rightTeam} ${leftScore}-${rightScore} ${leftGames}-${rightGames}`;
|
|
115
131
|
if (text === this.lastRenderedTextByCourt.get(courtId)) {
|
|
116
132
|
return;
|
|
117
133
|
}
|
|
@@ -187,8 +203,14 @@ class SupabaseListener {
|
|
|
187
203
|
// Team Names
|
|
188
204
|
ctx.font = "300 28px sans-serif";
|
|
189
205
|
const namePad = 40;
|
|
190
|
-
|
|
191
|
-
|
|
206
|
+
// Clamp names to the width of the names column (up to the first slanted
|
|
207
|
+
// separator) so a long name is ellipsized instead of bleeding over the
|
|
208
|
+
// points/games columns. 8px right gap keeps it clear of the divider.
|
|
209
|
+
const maxNameWidth = namesWidth - namePad - 8;
|
|
210
|
+
const leftName = this.truncateToWidth(ctx, leftTeam.toUpperCase(), maxNameWidth);
|
|
211
|
+
const rightName = this.truncateToWidth(ctx, rightTeam.toUpperCase(), maxNameWidth);
|
|
212
|
+
ctx.fillText(leftName, namePad, height / 4 + 2);
|
|
213
|
+
ctx.fillText(rightName, namePad - (slantX / 2), 3 * height / 4 + 2);
|
|
192
214
|
// Points
|
|
193
215
|
ctx.textAlign = "center";
|
|
194
216
|
ctx.font = "500 42px sans-serif";
|
|
@@ -212,6 +234,22 @@ class SupabaseListener {
|
|
|
212
234
|
await fs.rename(tempPath, scoreImagePath);
|
|
213
235
|
this.lastRenderedTextByCourt.set(courtId, text);
|
|
214
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* Trim `text` with a trailing ellipsis until it fits within `maxWidth` at the
|
|
239
|
+
* context's current font. Returns the text unchanged when it already fits.
|
|
240
|
+
*/
|
|
241
|
+
truncateToWidth(ctx, text, maxWidth) {
|
|
242
|
+
if (ctx.measureText(text).width <= maxWidth) {
|
|
243
|
+
return text;
|
|
244
|
+
}
|
|
245
|
+
const ellipsis = "…";
|
|
246
|
+
let truncated = text;
|
|
247
|
+
while (truncated.length > 0 &&
|
|
248
|
+
ctx.measureText(truncated + ellipsis).width > maxWidth) {
|
|
249
|
+
truncated = truncated.slice(0, -1);
|
|
250
|
+
}
|
|
251
|
+
return truncated.length > 0 ? truncated + ellipsis : ellipsis;
|
|
252
|
+
}
|
|
215
253
|
getScoreImagePath(courtId) {
|
|
216
254
|
return path.join(this.scoreImageDir, `${courtId}.png`);
|
|
217
255
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupabaseListener.js","sourceRoot":"","sources":["../../../../src/infrastructure/listeners/SupabaseListener.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iEAA8D;AAC9D,gDAAkC;AAClC,2CAA6B;AAE7B,4CAA+C;AAE/C;;;;GAIG;AACH,MAAa,gBAAgB;IAQ3B,YAAY,WAAmB,EAAE,SAAiB;QAF1C,4BAAuB,GAAwB,IAAI,GAAG,EAAE,CAAC;QAG/D,IAAI,CAAC,eAAe,GAAG,iCAAe,CAAC,WAAW,EAAE,CAAC;QACrD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;QAChD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,OAAe;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAE1B,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,eAAe,OAAO,EAAE,CAAC;QAExC,OAAO,CAAC,GAAG,CAAC,iDAAiD,OAAO,EAAE,CAAC,CAAC;QAExE,IAAI,CAAC,eAAe,CAAC,gBAAgB,CACnC,WAAW,EACX,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAC/B,QAAQ,EACR,QAAQ,EACR,MAAM,CACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,oBAAoB,CAAC,OAAe;QAC/C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAE1B,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,EAAE,CAAC;QAErD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,qDAAqD,OAAO,EAAE,CAAC,CAAC;QAC5E,MAAM,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,OAAY;QAClC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,KAAK,IAAI,CAAC,eAAe,CACvB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"SupabaseListener.js","sourceRoot":"","sources":["../../../../src/infrastructure/listeners/SupabaseListener.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,11 @@ export declare class LogShippingService {
|
|
|
4
4
|
private readonly sourceId;
|
|
5
5
|
private readonly retryAttempts;
|
|
6
6
|
private readonly retryDelay;
|
|
7
|
+
private readonly streamingApiKey;
|
|
7
8
|
private readonly errorRetryQueue;
|
|
8
9
|
private isProcessingErrorQueue;
|
|
9
|
-
constructor(url: string, sourceId: string, retryAttempts: number, retryDelay: number);
|
|
10
|
+
constructor(url: string, sourceId: string, retryAttempts: number, retryDelay: number, streamingApiKey?: string);
|
|
11
|
+
private headers;
|
|
10
12
|
shipLogs(logs: LogEntry[]): Promise<LogShippingResult>;
|
|
11
13
|
shipImmediateLog(log: LogEntry): Promise<void>;
|
|
12
14
|
shipBatch(logs: LogEntry[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogShippingService.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/logging/LogShippingService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAY,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEzE,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,sBAAsB,CAAS;gBAGrC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"LogShippingService.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/logging/LogShippingService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAY,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEzE,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,sBAAsB,CAAS;gBAGrC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,eAAe,SAAK;IAWtB,OAAO,CAAC,OAAO;IAQF,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA6BtD,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAyBzC,qBAAqB;YA8BrB,UAAU;YA2BV,iBAAiB;IAe/B,OAAO,CAAC,KAAK;IAIN,aAAa,IAAI;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,OAAO,CAAC;KAC7B;IAOY,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;CAK9C"}
|